Verify a letter PDF's layout before sending
Layout-verifies a letter BEFORE it is sent and returns a structured verdict — no side effects, nothing stored, nothing mailed, nothing charged.
Layout-verifies a letter BEFORE it is sent and returns a structured verdict — no side effects, nothing stored, nothing mailed, nothing charged. Checks: every page is A4 portrait; the recipient address sits inside the address window (left x=22mm y=60mm 85.5×25.5mm; right x=118mm — mm from the top-left corner; REGISTERED letters use the registered window y=67–90mm below the carrier's label band); the franking keep-out, 5mm edge band, 15mm bottom-left corner, and left-margin routing-code zone are clear; fonts are embedded; no interactive form fields; and, when to is provided, the address PRINTED in the PDF matches the intended recipient (the carrier mails to what is printed). Accepts the same document sources as the create — pass the SAME delivery and payment you will send with, so the templateId source verifies the exact PDF a create with the same inputs would mail. Every agent should call this before a real send and fix every fail (and review every warn). Requires only letters:read. For a templateId source the checks include clipped_content, which fails when the render cut text off; it is skipped for a caller-supplied PDF.
Scope: letters:read. Send the API key as a bearer token; Scopes lists what each one reaches.
Request
Body
Required, application/json: LetterVerifyRequest.
Exactly one document source must be provided: pdfBase64, file, or templateId (with templateData + to — the render composites the recipient). Passing to is strongly recommended: it enables the printed-address match check.
| Field | Type | Required | Description |
|---|---|---|---|
pdfBase64 | string or null | no | Base64-encoded PDF to verify (max 4 MB for verification). |
file | LetterFileRef or null | no | |
templateId | string or null | no | Verify a stored template's render. Requires to. |
templateData | object or null | no | |
to | PostalAddress or null | no | The intended recipient — enables the printed-address match check. Required with templateId. |
from | PostalAddress or null | no | Optional return address (template path only). |
print | LetterPrintOptions | no | |
maxPages | integer or null | no | Optional page-count ceiling enforced as a fail check. (minimum 1) |
delivery | LetterDelivery or null | no | Pass the SAME delivery class you will send with. registered letters use a DIFFERENT address geometry — the carrier prints its registered-mail label into y=50–67mm, so the recipient block must sit in y=67–90mm — and are verified against it. Registered delivery is domestic only (the recipient must be in the print centre country, DE); with to in another country verify adds a failing registered_domestic check, and price/create reject it with 422, param delivery. |
payment | LetterPayment or null | no | The structured payment object the create will carry. Template letters are rendered WITH the generated slip so the verified PDF is the exact PDF the create would mail. Template-path only (mirrors the create's rule). |
Response
200 Success. Body: application/json, LetterVerification.
| Field | Type | Required | Description |
|---|---|---|---|
object | "letter_verification" | yes | |
valid | boolean | yes | True when NO check failed. Warnings may still be present. |
pageCount | integer | no | |
pageSize | object or null | no | Page size in mm. A page within 1 mm of A4 is reported as exactly 210 x 297 with format A4. |
measuredPageSize | object or null | no | The raw measured page size, present when pageSize was reported as nominal A4 (a page within 1 mm of 210 x 297 mm, e.g. Chromium's 596 pt width). |
addressPlacement | "left", "right", null | no | The window where the recipient address was detected, or null when none was found. |
addressLines | array of string | no | The text lines detected inside the address window, top to bottom. |
checks | array of LetterVerificationCheck | yes | |
summary | string | no | |
agentHint | string | no | The recommended next step. |
Errors
Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.
| Status | Meaning |
|---|---|
400 | The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch). |
401 | The API key is missing or invalid. |
403 | The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted). |
404 | No such resource in this account (resource_not_found). |
413 | The request body or an attachment is too large (payload_too_large, plan_limit_reached). |
422 | The request is well-formed but a field failed validation (validation_failed). |
429 | Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached). |
500 | An unexpected error; retry with backoff, then contact support (internal_error). |
List a letter's delivery events
Returns the letter's delivery timeline as letter_event objects, newest first, capped at the 100 most recent.
Get the letter layout spec and starter templates
Returns the machine-readable compliance spec for physical letters: the exact A4 geometry (address windows, franking/edge/corner keep-outs, all in mm from the top-left corner), the PDF rules (embed fonts, no encryption, A4 portrait), the recommended verify→price→dryRun→send workflow, and ready-made COMPLIANT starter templates whose html can be stored via POST /v1/letters/templates verbatim.