Errors

Errors return the matching HTTP status and a JSON body of the shape { "error": { "code", "message" } }. Branch on the stable code rather than the human-readable message.

StatusCodeMeaning
401missing_api_keyNo API key was provided.
401invalid_api_keyThe key is invalid or revoked.
402quota_exceededMonthly PDF quota reached; upgrade your plan.
402ai_quota_exceededMonthly AI-authoring allowance reached; upgrade your plan.
403upgrade_requiredquality "pro" AI authoring requires a paid plan.
403watermark_not_allowedCustom watermarks require a paid plan.
404template_not_foundNo template with that id exists for your account.
404generation_not_foundNo generation with that id exists for your account.
409duplicate_requestThis Idempotency-Key was already used within the last 24 hours.
429rate_limitedToo many requests; retry after the Retry-After delay.
429test_quota_exceededThe account's 100-request daily test allowance was reached.
422invalid_jsonThe request body was not valid JSON.
422invalid_requestThe request body failed validation (e.g. prompt missing or too long).
422invalid_optionsoptions failed validation (unknown key, bad units/bounds, invalid filename, etc.).
422missing_template_idThe 'template_id' field is required.
422data_too_largeThe 'data' payload exceeds 256 KB.
422template_too_largeStored template HTML exceeds 512 KB.
422template_compile_errorThe template has a syntax error.
422template_render_errorThe template failed to render with this data.
422missing_data_fieldsoptions.strict was set and the template references fields absent from data.
422invalid_webhook_urloptions.webhook_url must be a public https URL.
501async_unavailableAsync webhook delivery is not enabled on this deployment.
502enqueue_failedThe async generation job could not be queued; retry.
502ai_failedAI template generation failed; retry.
502render_failedThe render service returned an error.
504render_timeoutRendering took longer than 20 seconds.

402, 429, 502 and 504 are safe to retry with backoff; for 429, wait for the Retry-After header. 4xx validation errors are not retryable: fix the request first.

Every /v1/generate response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset so you can pace requests before hitting a 429.

Every response also carries an X-Request-Id header — a stable id for that request, surfaced in your dashboard Generation logs. Binary renders that completed despite unresolved template variables include X-Doclinth-Warnings: missing=<paths>; URL responses carry the same as a warnings JSON array. Set "options": { "strict": true } to get 422 missing_data_fields instead of a partial render.