API referenceLetters

Send one template to many recipients

Fans one stored template out to up to 1,000 recipients, creating one letter per recipient rendered with that recipient's templateData.

Endpoint
POST https://api.dairo.app/v1/letters/batches

Fans one stored template out to up to 1,000 recipients, creating one letter per recipient rendered with that recipient's templateData. The whole request is validated up front — one malformed address, an unsupported to.country, or an unknown templateId (404) rejects the batch with nothing created. from, print, delivery, paymentSlip, autoSend, notifications, and metadata are shared by every member letter; only the address and templateData vary per recipient. Returns { id, total, status: "queued" } immediately, then rendering, printing, and posting proceed asynchronously — each member follows the normal lifecycle and emits letter.status_changed webhook events carrying its batchId. Each letter is priced and billed individually; list the members with GET /v1/letters?batchId=... and watch the rollup on GET /v1/letters/batches/{id}. Requires the letters:send scope.

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

Request

cURL
curl -X POST "https://api.dairo.app/v1/letters/batches" \
  -H "Authorization: Bearer $DAIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "recipients": [
      {
        "to": {
          "name": "Ada Lovelace",
          "company": "Acme GmbH",
          "street": "Hauptstraße",
          "houseNumber": "1",
          "poBox": null,
          "addressLine2": null,
          "postalCode": "10115",
          "city": "Berlin",
          "country": "DE"
        },
        "templateData": {}
      }
    ]
  }'

Body

Required, application/json: CreateLetterBatchRequest.

FieldTypeRequiredDescription
templateIdstringyesThe stored letter template rendered once per recipient.
recipientsarray of BatchRecipientyes(min items 1, max items 1000)
fromPostalAddress or nullno
printLetterPrintOptionsno
deliveryLetterDeliveryno
paymentSlip"qr", "sepaDe", "sepaAt" or nullnoOptional payment-slip overlay applied to every letter.
autoSendbooleanno(default true)
notificationsbooleanno(default true)
metadataobjectno

Response

200 Success. Body: application/json, LetterBatchCreateResponse.

FieldTypeRequiredDescription
object"letter_batch"yes
idstringyes
totalintegeryesNumber of letters created (one per recipient).
statusstringyesThe batch status; queued on create.
200
{
  "object": "letter_batch",
  "id": "string",
  "total": 0,
  "status": "string"
}

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