> This page is for API, version 2026-01-01 (Stable) (default).
> For other versions, use one of these documentation indexes:
> - 2026-01-01 (Stable) (default): https://developer.deel.com/api/stable/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.deel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.deel.com/_mcp/server.

# Request logs

> Inspect every API request made with your organization's tokens: status, latency, request id and the reason a request was rejected

Deel records every request made to the public API with one of your organization's tokens and keeps the records for **15 days**. Use them to find out why a request failed, to see which tokens are in use, and to give Deel Support the exact request to look at.

## What is recorded

One record is kept per REST API request, SCIM API request, or MCP tool call, including rejected responses, such as `401`, `403`, `404`, and `429`.

Each record details the request id, the timestamp in UTC, the HTTP method, route, and path, the status, the total and upstream durations, the source, the token, the client IP address, the user agent, the [API version](/api/api-versioning), the response size, and the error. The API reference documents every field.

Notes on additional fields:

| Field                  | What to know                                                                                                                                                                     |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request_id`           | Identical to the `X-Request-ID` response header. Quote it when contacting support.                                                                                               |
| `route`                | The route template the request matched, for example `/rest/v2/contracts/{contract_id}`. `null` when no endpoint matched (`404`).                                                 |
| `path`                 | Stops at the `?`: the query string is never stored. Path parameters are kept.                                                                                                    |
| `upstream_duration_ms` | `null` when the request was answered without reaching the service behind the API.                                                                                                |
| `token`                | `label` is the name the token was given when it was created in the Developer Center, or the OAuth2 app name for OAuth2 tokens. `oauth2_client_id` is set only for OAuth2 tokens. |
| `user_agent`           | Truncated to 512 characters.                                                                                                                                                     |
| `error`                | Set only when Deel's API layer rejected the request. `null` for successful requests and for errors returned by the underlying service.                                           |

When you retrieve a single request, the record also includes a `gateway_message` (what the outcome means in plain language) and a `hint` (what to do about it). See [Common gateway messages](#common-gateway-messages).

> **Note**
>
> Requests that cannot be attributed to an organization, for example a request sent with a malformed token, are not recorded.

### What is never recorded

* Request and response **bodies**
* Request and response **headers**, including `Authorization`
* **Query strings**: `path` stops at the `?`

The logs describe *that* a request happened and how it ended, not what it carried. Deel does not process request logs with AI.

## Retention and access

Deel keeps records for 15 days and then deletes them. There is no archive, and a query window cannot span more than 15 days.

| Access via       | Who can access                              | Requirement                                                                                                      |
| ---------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Developer Center | Organization Admins and IT Developer Admins | Role assignment                                                                                                  |
| API, CLI and MCP | Anyone holding a token with the scope       | The `api-logs:read` scope on an organization or personal access token, as an API token or an OAuth2 access token |

To read the logs through the API, CLI, or MCP, a token needs the `api-logs:read` scope, which is never granted by default. Select it when you [create the token](/api/authentication#generating-an-api-token) or request it during the [OAuth2 authorization](/api/oauth).

> **Warning**
>
> The logs are organization-wide. Any token that carries `api-logs:read` returns all requests of the organization, including requests made with other users' personal access tokens. Grant the scope only to tokens whose owners may see that.

The logs endpoints are limited to 60 requests in any rolling 60-second window per organization, in addition to the general [rate limits](/api/rate-limits), so short bursts are allowed. Excess requests receive a `429` response. Each list request returns up to 100 records, so you can read up to 6,000 records per minute.

## Developer Center

Open the Logs tab in the [Developer Center](https://app.deel.com/settings/developer/logs).

* **API requests** lists the organization's requests, newest first, covering a range of 15 minutes to 15 days. You can:
  * Filter by `X-Request-ID`, token ID, route, or status (`2xx`, `4xx`, `5xx`).
  * Select a request to open its details: the gateway message and hint, request ID (with a copy action), token, source, calling client, source IP, API version, and response size.
  * Turn on **Live** to refresh the list every 10 seconds.
* **Token activity** lists the tokens seen in the time range with their calls, errors, last use, and last IP, and shows a per-day breakdown for each token.

## API

| Endpoint                                  | Returns                                                                                                                               |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /rest/v2/logs/requests`              | A page of requests, newest first, filtered by the parameters below.                                                                   |
| `GET /rest/v2/logs/requests/{request_id}` | One request with its `gateway_message` and `hint`. Unknown ids, and requests of other organizations, return `404`.                    |
| `GET /rest/v2/logs/requests/summary`      | Request counts per status class, rate-limited requests, `p50_ms` and `p95_ms` latency and the number of active tokens for the window. |
| `GET /rest/v2/logs/tokens`                | Per-token activity for the window: calls, errors, last use, last IP and a per-day series.                                             |

The full parameter and response schemas are in the API reference, section **Logs**.

### Filters and pagination

The requests endpoints filter by request id, token, route, path, method, status, status class, and source; the tokens endpoint filters by label or id with `search`. The requests endpoints accept a time range as `from` and `to`, in ISO 8601 format. Without `from`, the range covers the 24 hours before `to`. Without `to`, the range ends at the current timestamp. A range longer than 15 days is cut to 15 days.

List responses have the shape `{"data": [...], "page": {"cursor": "...", "has_next_page": true}}`. Pass `page.cursor` back as `cursor` until `has_next_page` is `false`. Set the page size with `limit`, from 1 to 100; the default is 50.

### Examples

The examples read the token from the `DEEL_API_TOKEN` environment variable.

#### List requests

`4xx` responses in the last 24 hours (the default range), 100 per page:

**`Request`**

```bash Request showLineNumbers={false}
curl --get 'https://api.letsdeel.com/rest/v2/logs/requests' \
  --header "Authorization: Bearer $DEEL_API_TOKEN" \
  --data-urlencode 'status_class=4xx' \
  --data-urlencode 'limit=100'
```

**`Response`**

```json Response highlight={4,10,23-26,29-32}
{
  "data": [
    {
      "request_id": "5f1c2a8e9b3d4c7a1e2f3a4b",
      "timestamp": "2026-09-21T16:04:39.001Z",
      "source": "rest",
      "method": "GET",
      "route": "/rest/v2/contracts/{contract_id}",
      "path": "/rest/v2/contracts/3k9d2m",
      "status": 403,
      "duration_ms": 12,
      "upstream_duration_ms": null,
      "token": {
        "id": "2f4d6c8a-1b3e-4f5a-9c7d-8e6f0a1b2c3d",
        "type": "pat",
        "label": "HRIS sync",
        "oauth2_client_id": null
      },
      "ip": "203.0.113.42",
      "user_agent": "hris-sync/2.4.0",
      "api_version": "2026-01-01",
      "response_bytes": 212,
      "error": {
        "code": "INSUFFICIENT_SCOPES",
        "message": "Missing required scope: contracts:read"
      }
    }
  ],
  "page": {
    "cursor": "eyJ0cyI6IjIwMjYtMDktMjFUMTY6MDQ6MzkuMDAxWiIsImlkIjoiNWYxYzJhOGU5YjNkNGM3YTFlMmYzYTRiIn0",
    "has_next_page": true
  }
}
```

To run other queries, change the `--data-urlencode` lines:

| To get                                        | Parameters                                                                                              | In the response                              |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| The next page                                 | The same parameters, plus `cursor` set to `page.cursor` from the previous response                      | Repeat until `page.has_next_page` is `false` |
| Requests from one token in a fixed time range | `token_id=2f4d6c8a-1b3e-4f5a-9c7d-8e6f0a1b2c3d`, `from=2026-09-20T16:00:00Z`, `to=2026-09-21T16:00:00Z` |                                              |

#### Retrieve one request

The request a client reported, by its `X-Request-ID`. The response adds the explanation:

**`Request`**

```bash Request showLineNumbers={false}
curl 'https://api.letsdeel.com/rest/v2/logs/requests/5f1c2a8e9b3d4c7a1e2f3a4b' \
  --header "Authorization: Bearer $DEEL_API_TOKEN"
```

**`Response`**

```json Response highlight={9-10}
{
  "data": {
    "request_id": "5f1c2a8e9b3d4c7a1e2f3a4b",
    "status": 403,
    "error": {
      "code": "INSUFFICIENT_SCOPES",
      "message": "Missing required scope: contracts:read"
    },
    "gateway_message": "The token does not carry a scope this endpoint requires.",
    "hint": "Grant the required scope named in the error message to the token in the Developer Center, or call with a token that has it."
  }
}
```

#### Get a summary

Counts and latency for the last 24 hours:

**`Request`**

```bash Request showLineNumbers={false}
curl 'https://api.letsdeel.com/rest/v2/logs/requests/summary' \
  --header "Authorization: Bearer $DEEL_API_TOKEN"
```

**`Response`**

```json Response
{
  "data": {
    "from": "2026-09-20T16:00:00.000Z",
    "to": "2026-09-21T16:00:00.000Z",
    "total": 12840,
    "by_status_class": { "2xx": 12610, "3xx": 0, "4xx": 226, "5xx": 4 },
    "rate_limited": 180,
    "p50_ms": 200,
    "p95_ms": 750,
    "active_tokens": 7
  }
}
```

> **Note**
>
> `p50_ms` and `p95_ms` are computed over 1-hour intervals and reported as the upper bound of a latency bucket, so they are approximations.

## CLI

Read the logs with `deel logs`. The commands print JSON, so you can filter the output or pipe it to another tool.

| To get                                                                                                              | Command                                              |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| Requests that failed with a `4xx`                                                                                   | `deel logs requests list --status_class 4xx`         |
| Requests made with one token                                                                                        | `deel logs requests list --token_id <token_id>`      |
| The next page of a list                                                                                             | Repeat the command with `--cursor <page.cursor>`     |
| One request, with its gateway message and hint                                                                      | `deel logs requests get --request_id <request_id>`   |
| Requests per status class, rate-limited requests, `p50_ms` and `p95_ms` latency, and active tokens for a time range | `deel logs requests summary --from <from> --to <to>` |
| Tokens whose label or ID contains `HRIS`                                                                            | `deel logs tokens list --search HRIS`                |

The flags take the same filters as the [API parameters](#filters-and-pagination). The CLI's own calls are logged like any other request, with the CLI recorded as the calling client.

## MCP

The four endpoints are also available as tools on the [Deel MCP server](/mcp), so an AI assistant connected to Deel can answer questions such as "why did the payroll sync fail this morning?" from the logs.

| Tool                         | Returns                                                                                  |
| ---------------------------- | ---------------------------------------------------------------------------------------- |
| `listRequestLogs`            | A page of requests, newest first, with the same filters as `GET /rest/v2/logs/requests`. |
| `retrieveRequestLog`         | One request by its `X-Request-ID`, with `gateway_message` and `hint`.                    |
| `retrieveRequestLogsSummary` | Counts per status class, rate-limited requests, latency and active tokens for a window.  |
| `listTokenActivity`          | Per-token activity for a window.                                                         |

Tool calls are recorded in the logs with `source` set to `mcp`. To grant scopes to an MCP client, see [Authorization](/mcp/authorization). For the full list of tools, see the [Tools reference](/mcp/reference/tools-reference).

> **Warning**
>
> To use these tools, the token must have the `api-logs:read` scope.

## Using the request id with support

Every API response includes its request ID in the `X-Request-ID` header. Error responses also include it in the body, as `request.api_req_id`. In log records it appears as `request_id`, and the Developer Center shows it for each logged request.

When you contact [Deel Support](https://app.deel.com/contact-support) about a failed request, include:

1. The request id.
2. The timestamp in UTC, as shown in the log.
3. What you expected to happen.

With the request id, Support can locate the exact request without you sharing the payload.

## Handling log data

> **Warning**
>
> Log output is **organization data**. It reveals which systems call the Deel API, from which IP addresses, with which tokens, and how often. Share it only through channels your organization has approved. Do not paste it into third-party AI assistants, public forums, or support tickets with other vendors.

When an AI agent reads the logs for you through the CLI or MCP, it does so with your organization's token, under your organization's data policies.

## Common gateway messages

The `gateway_message` and `hint` of a request depend on its status and, where present, its `error.code`. The most common outcomes:

| Status              | Error code            | Meaning                                                                     | What to do                                                                                                                                           |
| ------------------- | --------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`               | `INVALID_TOKEN`       | The access token could not be verified.                                     | Send a valid bearer token in the `Authorization` header. Personal access tokens are shown once at creation; create a new one if it was lost.         |
| `401`               | `TOKEN_EXPIRED`       | The access token has expired.                                               | Create a new personal access token, or refresh the OAuth2 access token with the refresh token.                                                       |
| `401`               | `TOKEN_REVOKED`       | The access token was revoked.                                               | The token was disabled in the Developer Center; create a new token and update the integration.                                                       |
| `403`               | `INSUFFICIENT_SCOPES` | The token does not carry a scope this endpoint requires.                    | Grant the scope named in the error message to the token, or call with a token that has it.                                                           |
| `403`               | `PERMISSION_DENIED`   | The token owner is not allowed to perform this action.                      | Ask an organization admin to grant the permission, or use an organization token.                                                                     |
| `404`               |                       | No endpoint or resource matched the request.                                | Check the path and the identifiers in it; the resource may belong to another organization, no longer exist, or not exist in this API version.        |
| `429`               | `RATE_LIMITED`        | The organization exceeded the rate limit of this endpoint.                  | Back off and retry after the seconds given in the `Retry-After` header; spread bursts over time or cache responses.                                  |
| `499`               |                       | The client closed the connection before the response was sent.              | Raise the client timeout. For `POST` and `PATCH`, retry only with an [Idempotency-Key](/api/idempotency): the request may have been processed.       |
| `500`               |                       | Something went wrong on Deel's side.                                        | Retry later. If it persists, contact support and quote the request id.                                                                               |
| `502`, `503`, `504` |                       | The service behind the endpoint was unavailable or did not respond in time. | Retry with backoff; narrow the request (smaller page, tighter filters) if a `504` repeats. If it persists, contact support and quote the request id. |

You can retry `5xx` responses to `GET` and `DELETE` requests unconditionally. For `POST` and `PATCH`, follow the [error handling guidance](/api/best-practices#error-handling--retries).

## Next steps

#### [Authentication](/api/authentication)

Create tokens and choose their scopes

#### [Rate limits](/api/rate-limits)

Stay within the organization-wide limits

#### [Best practices](/api/best-practices#error-handling--retries)

Handle errors and retries safely

#### [MCP tools reference](/mcp/reference/tools-reference)

Browse every tool the Deel MCP server exposes