# Logs

The requests you made in the last 30 days, with bodies and the webhooks they caused. Integrators only.

## Endpoints

-   [GET `/v2/api-requests`](https://public-api.dapi.digital/docs/reference/logs.md#list_api_requests)
-   [GET `/v2/api-requests/{id}`](https://public-api.dapi.digital/docs/reference/logs.md#get_api_request)

## The api request detail object

One logged request with its bodies and what it caused.

### Attributes

-   `id` (string): Unique identifier of the request, prefixed with `req_`. Every response carries it in the `Request-Id` header, and error bodies in `details.request_id`.
-   `object` (string): Names the type of this object. Always `api_request`.
-   `method` (string): HTTP method, uppercase.
-   `route` (string or null): The operation's path template, for grouping (`/v2/quotes/:id`). Null when no operation matched, for example an unknown path.
-   `path` (string): The path as called, without the query string.
-   `status_code` (integer): HTTP status code the API answered with.
-   `duration_ms` (integer): Time the API took to answer, in milliseconds.
    
    Range at least 0.
    
-   `credential` (string or null): How the call was authenticated: an API key, a signed-in dashboard session, or an app the user connected (OAuth, such as Claude or ChatGPT). Null when it was refused before authentication.
    
    Possible values: `api_key`, `session`, `oauth`.
    
-   `api_key` (object or null): The key used, when one was.
    -   `id` (string): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.
    -   `object` (string): Names the type of this object. Always `api_key`.
    -   `name` (string): The key's label, or "Deleted key" when it no longer exists.
-   `ip` (string or null): IP address the request came from: the first address in `X-Forwarded-For`, or the connecting address when that header is absent. Null when neither could be read.
-   `user_agent` (string or null): The `User-Agent` header sent. Null when there was none.
-   `idempotency_key` (string or null): The `Idempotency-Key` header sent, if any.
-   `error_code` (string or null): The `code` of an error answer; null on success.
-   `request_bytes` (integer): Size of the request body in bytes, as received (chunked bodies included). 0 when there was none.
    
    Range at least 0.
    
-   `response_bytes` (integer): Size of the response body in bytes. 0 when there was none.
    
    Range at least 0.
    
-   `created_at` (timestamp): When the request arrived.
-   `request_body` (value, optional): The body you sent, with credentials, secrets and buyer personal data removed. JSON when it parsed, text otherwise. Null when there was none, or it is no longer available.
-   `response_body` (value, optional): The body the API answered, redacted the same way. Null when there was none, or it is no longer available.
-   `bodies_truncated` (boolean): True when a body was larger than 256 KB and only its start was kept (then as text).
-   `events` (array of object): Webhook events this request caused, with their deliveries to your endpoints.
    -   `id` (string): Unique identifier of the event, prefixed with `evt_`. Treat it as an opaque string: store it and compare it, never parse it.
    -   `object` (string): Names the type of this object. Always `event`.
    -   `type` (string): The event type.
    -   `created_at` (timestamp): Point in time, ISO 8601 in UTC.
    -   `deliveries` (array of object): Where the event was sent, with every try.
        -   `id` (string): Unique identifier of the webhook delivery, prefixed with `whd_`. Treat it as an opaque string: store it and compare it, never parse it.
        -   `object` (string): Names the type of this object. Always `webhook_delivery`.
        -   `endpoint` (object): The webhook endpoint this delivery went to.
            -   `id` (string): Unique identifier of the webhook endpoint, prefixed with `whe_`. Treat it as an opaque string: store it and compare it, never parse it.
            -   `object` (string): Names the type of this object. Always `webhook_endpoint`.
            -   `url` (string): The URL the event was sent to.
        -   `status` (WebhookDeliveryStatus):
            
            -   `pending`: being sent, or waiting for a retry (retries run for 24 hours).
            -   `succeeded`: your endpoint answered with a 2xx.
            -   `failed`: every try in the 24 hours failed.
            -   `skipped`: not sent because the endpoint was disabled when its turn came. Nothing was posted, so there are no attempts.
            
        -   `attempts` (array of WebhookDeliveryAttempt): Every try so far, first try first. Empty until the first try is made.
            -   `attempt` (integer): 1 for the first try.
                
                Range at least 1.
                
            -   `started_at` (timestamp): Point in time, ISO 8601 in UTC.
            -   `duration_ms` (integer): How long your endpoint took to answer or fail, in milliseconds. 0 when the request was not sent because the URL was refused.
                
                Range at least 0.
                
            -   `status_code` (integer or null): What your endpoint answered; null when it did not answer (timeout, connection refused).
            -   `succeeded` (boolean): True when your endpoint answered with a 2xx status.
            -   `error` (string or null): Why the attempt failed: `HTTP <status>` for a non-2xx answer, or `Timed out after <n>s`, `Could not connect` or `Target not allowed` when there was no answer. Null when it succeeded.
            -   `response_body` (string or null): The first 4 KB of your endpoint's answer, with secrets and personal data removed.

**The api request detail object**

```json
{
  "id": "req_7Kq2Xb9LmN4pR8sT1vW3yZ5a",
  "object": "api_request",
  "method": "POST",
  "route": "/v2/quotes",
  "path": "/v2/quotes",
  "status_code": 201,
  "duration_ms": 184,
  "credential": "api_key",
  "api_key": {
    "id": "key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
    "object": "api_key",
    "name": "Production server"
  },
  "ip": "203.0.113.7",
  "user_agent": "node-fetch/1.0",
  "idempotency_key": "0f8c2d1e-5a6b-4c3d-9e8f-1a2b3c4d5e6f",
  "error_code": null,
  "request_bytes": 96,
  "response_bytes": 512,
  "created_at": "2026-10-21T14:02:11Z",
  "request_body": {
    "name": "Phone stand",
    "file": {
      "upload": "upl_3fZq9a[redacted]"
    }
  },
  "response_body": {
    "id": "qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
    "object": "quote",
    "status": "processing"
  },
  "bodies_truncated": false,
  "events": []
}
```

## List your API requests

GET `/v2/api-requests`

- **Credentials**: A signed-in dashboard session only; API keys are refused.

- **For**: Integrators

- **Operation id**: `list_api_requests`

Lists the requests you made to the API in the last 30 days, newest first: method, path, status, time taken and the key used. Filter by time, status class, method, operation, key or request id.

Integrators only, and only with a signed-in dashboard session (`credential_not_allowed` with an API key).

### Query parameters

-   `created_after` (timestamp): Only requests made at or after this time.
-   `created_before` (timestamp): Only requests made before this time.
-   `status_class` (array of string): Only these status classes (`2xx`, `4xx`, ...). Repeat for several.
    
    Possible values: `2xx`, `3xx`, `4xx`, `5xx`.
    
-   `method` (array of string): Only these HTTP methods. Repeat for several.
    
    Possible values: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`.
    
-   `route` (string): Only this operation, by its path template (`/v2/quotes/:id`).
-   `api_key` (string): Only requests made with this API key.
-   `request_id` (string): Find one request by its `Request-Id`.
-   `limit` (integer): How many results per page, from 1 to 100.
    
    Range 1 to 100. Defaults to 20.
    
-   `cursor` (string): Where to continue from: the `next_cursor` of the previous page. Omit for the first page.

### Returns 200 OK

A page of requests.

Response attributes (ApiRequestList):

-   `object` (string): Names the type of this object. Always `list`.
-   `data` (array of ApiRequest): The page of results.
    -   `id` (string): Unique identifier of the request, prefixed with `req_`. Every response carries it in the `Request-Id` header, and error bodies in `details.request_id`.
    -   `object` (string): Names the type of this object. Always `api_request`.
    -   `method` (string): HTTP method, uppercase.
    -   `route` (string or null): The operation's path template, for grouping (`/v2/quotes/:id`). Null when no operation matched, for example an unknown path.
    -   `path` (string): The path as called, without the query string.
    -   `status_code` (integer): HTTP status code the API answered with.
    -   `duration_ms` (integer): Time the API took to answer, in milliseconds.
        
        Range at least 0.
        
    -   `credential` (string or null): How the call was authenticated: an API key, a signed-in dashboard session, or an app the user connected (OAuth, such as Claude or ChatGPT). Null when it was refused before authentication.
        
        Possible values: `api_key`, `session`, `oauth`.
        
    -   `api_key` (object or null): The key used, when one was.
        -   `id` (string): Unique identifier of the api key, prefixed with `key_`. Treat it as an opaque string: store it and compare it, never parse it.
        -   `object` (string): Names the type of this object. Always `api_key`.
        -   `name` (string): The key's label, or "Deleted key" when it no longer exists.
    -   `ip` (string or null): IP address the request came from: the first address in `X-Forwarded-For`, or the connecting address when that header is absent. Null when neither could be read.
    -   `user_agent` (string or null): The `User-Agent` header sent. Null when there was none.
    -   `idempotency_key` (string or null): The `Idempotency-Key` header sent, if any.
    -   `error_code` (string or null): The `code` of an error answer; null on success.
    -   `request_bytes` (integer): Size of the request body in bytes, as received (chunked bodies included). 0 when there was none.
        
        Range at least 0.
        
    -   `response_bytes` (integer): Size of the response body in bytes. 0 when there was none.
        
        Range at least 0.
        
    -   `created_at` (timestamp): When the request arrived.
-   `has_more` (boolean): True when more results exist after this page. Fetch them by passing `next_cursor` as `cursor`.
-   `next_cursor` (string or null): Opaque cursor for the next page, or null on the last page. Pass it back unchanged as `cursor`.

### Responses

-   `200`: A page of requests.
-   `400`: The request is invalid. `details.errors` lists each problem (`validation_failed`), or an `expand[]` path is unknown (`invalid_expand`).
-   `401`: Credentials are missing (`missing_credentials`), the API key is unknown or inactive (`invalid_api_key`), the session expired (`invalid_session`), or both a key and a session were sent (`ambiguous_credentials`).
-   `403`: The credentials are valid but not allowed to do this: a scope is missing (`missing_scope`), the endpoint is for another kind of account (`actor_not_allowed`) or another kind of credential (`credential_not_allowed`), the account may no longer use the API (`account_blacklisted`), or the account must change something first, in which case `details.fix_url` links to the dashboard page that fixes it.
-   `429`: Too many requests (`rate_limited`): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl "https://public-api.dapi.digital/v2/api-requests" \
  -H "x-api-key: $DAPI_API_KEY"
```

**Response 200**

```json
{
  "object": "list",
  "data": [
    {
      "id": "req_7Kq2Xb9LmN4pR8sT1vW3yZ5a",
      "object": "api_request",
      "method": "POST",
      "route": "/v2/quotes",
      "path": "/v2/quotes",
      "status_code": 201,
      "duration_ms": 184,
      "credential": "api_key",
      "api_key": {
        "id": "key_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
        "object": "api_key",
        "name": "Production server"
      },
      "ip": "203.0.113.7",
      "user_agent": "node-fetch/1.0",
      "idempotency_key": "0f8c2d1e-5a6b-4c3d-9e8f-1a2b3c4d5e6f",
      "error_code": null,
      "request_bytes": 96,
      "response_bytes": 512,
      "created_at": "2026-10-21T14:02:11Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Get an API request

GET `/v2/api-requests/{id}`

- **Credentials**: A signed-in dashboard session only; API keys are refused.

- **For**: Integrators

- **Operation id**: `get_api_request`

Returns one logged request with the bodies sent and answered (credentials, secrets and buyer personal data removed), the webhook events it caused and every delivery attempt to your endpoints.

Integrators only, and only with a signed-in dashboard session (`credential_not_allowed` with an API key).

### Path parameters

-   `id` (string, required): Unique identifier of the request, prefixed with `req_`. Every response carries it in the `Request-Id` header, and error bodies in `details.request_id`.

### Returns 200 OK

The request. Returns [the api request detail object](https://public-api.dapi.digital/docs/reference/logs.md#api_request_detail_object).

### Responses

-   `200`: The request.
-   `400`: The request is invalid. `details.errors` lists each problem (`validation_failed`), or an `expand[]` path is unknown (`invalid_expand`).
-   `401`: Credentials are missing (`missing_credentials`), the API key is unknown or inactive (`invalid_api_key`), the session expired (`invalid_session`), or both a key and a session were sent (`ambiguous_credentials`).
-   `403`: The credentials are valid but not allowed to do this: a scope is missing (`missing_scope`), the endpoint is for another kind of account (`actor_not_allowed`) or another kind of credential (`credential_not_allowed`), the account may no longer use the API (`account_blacklisted`), or the account must change something first, in which case `details.fix_url` links to the dashboard page that fixes it.
-   `404`: You have no logged request with this id (`api_request_not_found`). Requests are kept for 30 days.
-   `429`: Too many requests (`rate_limited`): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl "https://public-api.dapi.digital/v2/api-requests/req_7Kq2Xb9LmN4pR8sT1vW3yZ5a" \
  -H "x-api-key: $DAPI_API_KEY"
```

---

3DAPI API Docs. This page on the web: https://public-api.dapi.digital/docs/reference/logs. Index of every page: https://public-api.dapi.digital/docs/llms.txt.
