API referenceLetters

List physical-mail letters

List physical-mail letters (paginated)

Endpoint
GET https://api.dairo.app/v1/letters

Returns the project's letters newest first, limit per page (default 20, max 100), with an opaque pagination.nextCursor to pass back as cursor for the next page. Filter with status (one lifecycle value such as in_transit), country (ISO 3166-1 alpha-2, case-insensitive), and batchId; filters combine. List items carry only the recipient's city and country — fetch a single letter for the full address and its event timeline.

Scope: letters:read. Send the API key as a bearer token; Scopes lists what each one reaches.

Request

cURL
curl "https://api.dairo.app/v1/letters" \
  -H "Authorization: Bearer $DAIRO_API_KEY"

Query parameters

NameTypeRequiredDescription
limitintegernoMaximum number of items in the page. (minimum 1, maximum 100, default 25)
cursorstringnoThe nextCursor of the previous page; omit it for the first page (Pagination).
statusLetterStatusno
countrystringno
batchIdstringnoFilter to the member letters of one batch (the id returned by POST /v1/letters/batches).

Response

200 Success. Body: application/json, LetterList.

FieldTypeRequiredDescription
object"list"yes
dataarray of Letteryes
paginationPaginationyes
200
{
  "object": "list",
  "data": [
    {
      "object": "letter",
      "id": "string",
      "status": "draft",
      "fileName": "letter.pdf",
      "pageCount": null,
      "to": {
        "name": "Ada Lovelace",
        "company": "Acme GmbH",
        "street": "Hauptstraße",
        "houseNumber": "1",
        "poBox": null,
        "addressLine2": null,
        "postalCode": "10115",
        "city": "Berlin",
        "country": "DE"
      },
      "from": {
        "name": "Ada Lovelace",
        "company": "Acme GmbH",
        "street": "Hauptstraße",
        "houseNumber": "1",
        "poBox": null,
        "addressLine2": null,
        "postalCode": "10115",
        "city": "Berlin",
        "country": "DE"
      },
      "print": {
        "mode": "color",
        "sides": "simplex",
        "addressPlacement": "left"
      },
      "delivery": "economy",
      "paperTypes": [
        "standard"
      ],
      "autoSend": true,
      "price": {
        "currency": "EUR",
        "amount": 0,
        "walletAmount": 0,
        "walletCurrency": "string",
        "walletRate": 0
      },
      "metadata": {},
      "lastEventType": null,
      "lastEventAt": "2026-10-19T09:30:00Z",
      "submittedAt": "2026-10-19T09:30:00Z",
      "canceledAt": "2026-10-19T09:30:00Z",
      "error": null,
      "createdAt": "2026-10-19T09:30:00Z",
      "updatedAt": "2026-10-19T09:30:00Z",
      "events": [
        {
          "object": "letter_event",
          "eventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "letterId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "type": "string",
          "code": null,
          "description": null,
          "producer": null,
          "location": null,
          "reason": null,
          "hasImage": true,
          "occurredAt": "2026-10-19T09:30:00Z",
          "recordedAt": "2026-10-19T09:30:00Z"
        }
      ],
      "paymentSlip": "qr",
      "dryRun": true,
      "providerMode": "test",
      "notifications": true,
      "payment": {
        "type": "qr",
        "creditor": {
          "name": "Ada Lovelace",
          "iban": "string",
          "bic": null,
          "street": "Hauptstraße",
          "houseNumber": "1",
          "postalCode": "10115",
          "city": "Berlin",
          "country": "DE"
        },
        "amount": 0,
        "currency": "CHF",
        "reference": null,
        "message": null,
        "debtor": {
          "name": "Ada Lovelace",
          "street": "Hauptstraße",
          "houseNumber": "1",
          "postalCode": "10115",
          "city": "Berlin",
          "country": "DE"
        }
      },
      "batchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }
  ],
  "pagination": {
    "nextCursor": "string",
    "hasMore": true
  }
}

Errors

Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.

StatusMeaning
400The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch).
401The API key is missing or invalid.
403The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted).
404No such resource in this account (resource_not_found).
422The request is well-formed but a field failed validation (validation_failed).
429Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached).
500An unexpected error; retry with backoff, then contact support (internal_error).

On this page