> For the complete documentation index, see [llms.txt](https://docs.material.security/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.material.security/reference/api-v1/hello-world.md).

# Hello World

## Issues

This example walks you through making your first Issues API calls: listing open issues then retrieving the details of a specific one.

The workflow illustrates how the three Issues API endpoints interact to investigate a security issue. Depending on your needs and the level of detail required, you might use one or more endpoints.

<figure><img src="https://3441929823-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDXSwW7QZtKgywlqSARjL%2Fuploads%2FmNYilhjBhcQtEOmsIiHy%2Fimage.png?alt=media&#x26;token=5dc6cd60-abca-47bb-a7c1-5285c353460b" alt=""><figcaption></figcaption></figure>

<details>

<summary><strong>Step 1: Authenticate</strong></summary>

All Issues API requests must be authenticated using an API key (token), passed in the `x-material-client-secret` request header.

Follow the steps in Authentication to create a token in Material.

**Store your API token securely**

Avoid hardcoding your API token in scripts or source code. Instead, store it as an environment variable and reference it in your requests:

```bash
export MATERIAL_API_KEY="your_api_key_here"

curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/issues" \
  --header "x-material-client-secret: $MATERIAL_API_KEY"
```

#### Authentication errors

If your API token is missing or invalid, the API will return a `401 Unauthorized` response. Verify that the `x-material-client-secret` header is present and that the token is correct.

</details>

<details>

<summary><strong>Step 2: Find open issues</strong></summary>

Call the List Issues endpoint to retrieve a page of open issues from your instance.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/issues?status=open" \
  --header "x-material-client-secret: YOUR_API_KEY"
```

A successful response returns a paginated collection of issues. The response returns a paginated collection of issues. Each item includes the issue's name, severity, classification, and the detection rule that triggered it. Because `include=comments,accounts` was specified, analyst comments and associated accounts are also returned.

Note the `id` field on any issue you want to investigate — you'll use it in the next step.

```json
{
  "meta": {
    "totalCount": 3,
    "limit": 25,
    "hasMore": false,
    "nextCursor": null
  },
  "items": [
    {
      "id": "ABC",
      "name": "Credential phishing attempt",
      "status": "open",
      "severity": "04-high",
      "classification": "malicious",
      ...
    }
  ]
}
```

</details>

<details>

<summary><strong>Step 3: Retrieve a specific issue</strong></summary>

Using the `id` from the previous response, call the Get Issue endpoint to retrieve the full details of that issue.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/issues/{issue_id}" \
  --header "x-material-client-secret: YOUR_API_KEY"
```

The response returns the full issue object, including its severity, classification, primary entity, detection rule, and key lifecycle timestamps.

</details>

<details>

<summary><strong>Step 4: Retrieve the associated messages</strong></summary>

Examine the messages at the center of the issue by calling the List Issue Messages endpoint with the same issue ID.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/issues/{issue_id}/messages" \
  --header "x-material-client-secret: YOUR_API_KEY"
```

The response returns a paginated list of messages, each with sender, recipients, subject, and attachment metadata. The `meta` object includes `numLinks` and `numAttachments` counts across all messages in the issue.

Use `cursor` and `limit` to page through large result sets.

</details>

<details>

<summary><strong>Next Steps</strong></summary>

Add `?include=comments,accounts` to any request to pull in analyst comments and associated accounts.

</details>

{% hint style="success" %}
Review the Issues API in more detail in the API reference
{% endhint %}

***

## Messages

This example walks you through making your first Messages API calls: searching for messages matching a query, polling for results, and retrieving a specific message.

<figure><img src="https://3441929823-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDXSwW7QZtKgywlqSARjL%2Fuploads%2FLWNQ3Tfeo1TxxO9MTGkI%2Fimage.png?alt=media&#x26;token=d07d2530-347b-4248-963e-4363d71f1361" alt="" width="563"><figcaption></figcaption></figure>

<details>

<summary><strong>Step 1: Authenticate</strong></summary>

All Messages API requests require an API key (token) passed in the `x-material-client-secret` request header. Store your token as an environment variable to avoid hardcoding it in your scripts:

```bash
export MATERIAL_API_KEY="your_api_key_here"
```

Then reference it in every request:

```bash
--header "x-material-client-secret: $MATERIAL_API_KEY"
```

If your API token is missing or invalid, the API returns a `401 Unauthorized` response.

</details>

<details>

<summary><strong>Step 2: Start a search job</strong></summary>

Call the Search Messages endpoint with a MQL query and a time window to find matching messages.

```bash
curl --request POST \
  --url "https://{your-instance.on.material.security}/api/v1/messages/search" \
  --header "x-material-client-secret: $MATERIAL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "mqlSearchString": "from:attacker@example.com subject:\"urgent payment\"",
    "startDate": "2024-01-01T00:00:00.000Z",
    "endDate": "2024-02-01T00:00:00.000Z"
  }'
```

The response returns a job ID and an initial status of `"CREATED"` or `"STARTED"`. Note the `id` — you'll use it to poll for results.

```json
{
  "id": "job.1.<base64>",
  "status": "CREATED"
}
```

</details>

<details>

<summary><strong>Step 3: Poll for results</strong></summary>

Call the Get Message Search Results endpoint using the job ID. Repeat until `status` is `"DONE"`.

```bash
curl --request GET \
  --url "https://{your-instance.on.material.security}/api/v1/messages/search/{job_id}" \
  --header "x-material-client-secret: $MATERIAL_API_KEY"
```

When the job is complete, the response includes a `data` object containing `meta` and `items` with the matching messages. If `meta.hasMore` is true, pass the `nextCursor` value to the `cursor` query parameter to retrieve the next page.

```json
{
  "id": "job.1.<base64>",
  "status": "DONE",
  "data": {
    "meta": {
      "totalCount": 2,
      "limit": 25,
      "hasMore": false,
      "nextCursor": null
    },
    "items": [
      {
        "id": "msg.1.<base64>",
        "date": "2024-01-15T12:00:00.000Z",
        "subject": "urgent payment",
        "from": "attacker@example.com",
        ...
      }
    ]
  }
}
```

</details>

<details>

<summary><strong>Step 4: Retrieve a specific message</strong></summary>

Using a message ID from the search results, retrieve the full details of that message.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/messages/{message_id}" \
  --header "x-material-client-secret: $MATERIAL_API_KEY"
```

The response returns the full message object, including sender, recipients, subject, date, snippet, and attachment metadata.

</details>

<details>

<summary><strong>Next Steps</strong></summary>

Filter search results to specific tenants by passing `uDomainIds` in the search request body.

</details>

{% hint style="success" %}
Review the Issues API in more detail in the API reference.
{% endhint %}

***

## Trusted Entities

This example walks you through making your first Trusted Entities API calls: reviewing what your instance already trusts, adding a new trusted entity, retrieving it to confirm its settings, and updating those settings.

Trusted entities are the domains, email addresses, and IP addresses (or CIDR ranges) that Material treats as known and trusted. Adding or changing one affects what Material trusts, so every write is security-sensitive and audited.

<figure><img src="/files/lQ1MVukv69kK8UO9VjEn" alt=""><figcaption></figcaption></figure>

<details>

<summary><strong>Step 1: Authenticate</strong></summary>

All Trusted Entities API requests require an API key (token) passed in the `x-material-client-secret` request header. Store your token as an environment variable to avoid hardcoding it in your scripts:

```bash
export MATERIAL_API_KEY="your_api_key_here"
```

Then reference it in every request:

```bash
--header "x-material-client-secret: $MATERIAL_API_KEY"
```

If your API token is missing or invalid, the API returns a `401 Unauthorized` response.

</details>

<details>

<summary><strong>Step 2: Review what's already trusted</strong></summary>

Call the List Trusted Entities endpoint to see the entities your instance already trusts. Material returns its built-in system entities first, followed by any you've added.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/trusted-entities" \
  --header "x-material-client-secret: $MATERIAL_API_KEY"
```

Each item includes the entity value, its `type`, and its detection settings. To narrow the list, add query parameters such as `type=external_domain` or `enabled=true`.

```json
{
  "meta": {
    "limit": 25,
    "hasMore": false,
    "nextCursor": null
  },
  "items": [
    {
      "id": "te.1.<base64>",
      "entity": "example.com",
      "type": "external_domain",
      "tenant": null,
      "enabled": true,
      "subdomains": "included",
      "emailThreatDetection": "detect",
      "emailAuthentication": "enforced",
      "fileDetection": "treat_as_external"
    }
  ]
}
```

This list doesn't return a total count. Use `hasMore` and `nextCursor` to page through large result sets.

</details>

<details>

<summary><strong>Step 3: Add a trusted entity</strong></summary>

Call the Create Trusted Entity endpoint to add a new entity. Only `entity` and `type` are required. Any settings you leave out default to their least-permissive value.

```bash
curl --request POST \
  --url "https://your-instance.on.material.security/api/v1/trusted-entities" \
  --header "x-material-client-secret: $MATERIAL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "entity": "partner.example.com",
    "type": "external_domain",
    "subdomains": "included"
  }'
```

The response returns the created entity, including its generated `id`. Note the `id` — you'll use it to retrieve or update the entity.

```json
{
  "id": "te.1.<base64>",
  "entity": "partner.example.com",
  "type": "external_domain",
  "tenant": null,
  "enabled": true,
  "subdomains": "included",
  "emailThreatDetection": "detect",
  "emailAuthentication": "enforced",
  "fileDetection": "treat_as_external"
}
```

</details>

<details>

<summary><strong>Step 4: Retrieve the trusted entity</strong></summary>

Using the `id` from the previous response, call the Get Trusted Entity endpoint to confirm its settings.

```bash
curl --request GET \
  --url "https://your-instance.on.material.security/api/v1/trusted-entities/{entity_id}" \
  --header "x-material-client-secret: $MATERIAL_API_KEY"
```

The response returns the full trusted entity object. Add `?include=timeline` to see the change history for the entity, including when it was created and last modified.

</details>

<details>

<summary><strong>Step 5: Update its settings</strong></summary>

Call the Update Trusted Entity endpoint to change a setting. Only the fields you include change, and the `entity`, `type`, and `tenant` values can't be changed after creation.

For example, temporarily disable the entity without removing it:

```bash
curl --request PATCH \
  --url "https://your-instance.on.material.security/api/v1/trusted-entities/{entity_id}" \
  --header "x-material-client-secret: $MATERIAL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "enabled": false
  }'
```

The response returns the updated entity with your changes applied.

</details>

<details>

<summary><strong>Next Steps</strong></summary>

Apply up to 200 create, update, and delete operations in a single request with the Bulk Trusted Entities endpoint. To remove an entity you've added, call the Delete Trusted Entity endpoint with its `id`. System-managed entities can't be deleted.

</details>

{% hint style="success" %}
Review the Trusted Entities API in more detail in the [API reference](/reference/api-v1/trusted-entities.md).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.material.security/reference/api-v1/hello-world.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
