DynamicDocumentAPI

Errors

The problem details format, which failures are worth retrying, and every error code grouped by HTTP status with a suggested fix.

View as Markdown

Errors are returned as problem details (RFC 9457) with the content type application/problem+json. Every error carries a stable machine-readable code; branch on that, never on the human-readable title or detail.

{
  "type": "https://docs.dynamicdocumentapi.com/errors/template_runtime_error",
  "title": "Template runtime error",
  "status": 422,
  "code": "template_runtime_error",
  "detail": "'dict object' has no attribute 'total' (line 12, column 7)",
  "errors": [
    { "path": "/data/items/0/qty", "code": "type_error", "message": "expected number" }
  ],
  "render_id": "rnd_01J9ZM1X3F7R8K2C4V6B8N0P2Q",
  "request_id": "req_01J9ZM4T6W8Y0A2C4E6G8J0K2M",
  "doc_url": "https://docs.dynamicdocumentapi.com/errors/template_runtime_error"
}
FieldDescription
typeURI identifying the error type, such as https://docs.dynamicdocumentapi.com/errors/template_runtime_error
titleShort human-readable summary
statusThe HTTP status code, repeated in the body
codeStable identifier to branch on. Every code is listed below.
detailWhat went wrong in this particular case, including template line and column where applicable
errorsFor validation failures: one entry per problem, with a JSON Pointer path, a code and a message
render_idPresent when a render was created before the failure
request_idThe request's ID, also in the X-Request-Id header. Include it in support requests.
doc_urlLink to the documentation for this code

Failed renders carry the same information. A sync render that fails returns 422 with the render error, and an async render ends with status: "failed" and an error object holding code, message and, for template problems, line, column and excerpt.

Handling errors

Retry these:

  • 429 after the number of seconds in Retry-After
  • 500 and 503, with exponential backoff; 503 also sends Retry-After
  • 409 idempotency_in_progress, after a short pause, with the same idempotency key

Don't retry the others without changing the request: 400, 401, 402, 403, 404, 410, 413, 415, 422 and 423 describe something that will fail the same way again.

Always send an Idempotency-Key header so that a retry can never produce a second document, and log request_id next to your own identifiers.

const MAX_ATTEMPTS = 5;

async function createRender(body: unknown, idempotencyKey: string) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch("https://api-eu.dynamicdocumentapi.com/v1/renders", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
        "Content-Type": "application/json",
        "Idempotency-Key": idempotencyKey,
      },
      body: JSON.stringify(body),
    });
    if (response.ok) return response.json();

    const problem = await response.json().catch(() => ({}));
    const retryable =
      response.status === 429 || response.status >= 500 || problem.code === "idempotency_in_progress";
    if (!retryable || attempt === MAX_ATTEMPTS) {
      throw new Error(`${problem.code ?? response.status}: ${problem.detail ?? ""} (request ${problem.request_id ?? "?"})`);
    }

    const retryAfter = Number(response.headers.get("Retry-After"));
    const delaySeconds = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : 2 ** attempt;
    await new Promise((resolve) => setTimeout(resolve, delaySeconds * 1000));
  }
}

400 Bad Request

CodeMeaningFix
invalid_jsonThe request body isn't valid JSONCheck quoting and encoding. In shells, watch for unescaped quotes inside -d '…'.
validation_errorThe JSON is valid but a field is missing, has the wrong type or is out of rangeRead errors[]: each entry points at the offending field with a JSON Pointer

401 Unauthorized

CodeMeaningFix
authentication_requiredNo API key was sentSend Authorization: Bearer <key> or the X-API-Key header
invalid_api_keyThe key is malformed or unknownCheck for truncation, stray whitespace or a key from another workspace
api_key_expiredThe key passed its expiry dateCreate a new key or extend the expiry
api_key_revokedThe key was revoked, or a rolled key's grace period endedDeploy the current key

402 Payment Required

CodeMeaningFix
render_limit_reachedThe Free plan's included renders are used up, or a paid workspace ran out of renders and no auto top-up can be added (monthly top-up limit reached, auto top-ups off, or a top-up payment outstanding)Free: upgrade, buy a render pack, or wait for the next cycle. Paid: raise the monthly top-up limit or settle the open payment. Test keys keep working. See Plans and limits.
plan_feature_unavailableThe request uses a feature that isn't part of your plan, such as PDF/UA, PDF/A or e-invoicing below GrowthRemove the option or upgrade
free_workspace_limitYou already own two workspaces on the Free plan, the most one person can have. Free workspaces you deleted in the last 30 days still count, and so does taking over a free workspace from someone elseUpgrade one of your workspaces to a paid plan, then create the new one

403 Forbidden

CodeMeaningFix
insufficient_scopeThe key lacks a scope for this operationUse a key with the right scope, for example render:write
ip_not_allowedThe request came from an address outside the key's IP allowlistAdd the address range, or call from an allowed network
test_key_requiredThe request needs a test key, for example rendering a template draft or sending test: true with a live keyUse a test key, or render a published version
workspace_suspendedThe workspace is suspendedCheck billing and email, or contact support@dynamicdocumentapi.com
workspace_deletion_scheduledThe workspace is scheduled for deletion, so its API keys are refusedThe owner can cancel the deletion in the dashboard until it completes
template_not_allowed_for_keyThe key's template allowlist doesn't include this templateAdd the template to the allowlist or use another key
email_not_verifiedLive rendering requires a verified email addressVerify the address; test keys work meanwhile
region_not_enabledYour workspace isn't enabled for the region of this API host, so renders, previews, PDF tools and e-invoices are refused hereCall the API host of your workspace's region, see Data residency, or contact support@dynamicdocumentapi.com
feature_not_enabledEmail delivery isn't enabled for your workspace yet, so its connections and rules can't be created, changed or testedWrite to support@dynamicdocumentapi.com to have it enabled; reading, deleting and switching rules off work meanwhile
invalid_signatureA signed link URL has no sig, or it doesn't match the URLSign the exact path and query with the link secret; any change to a parameter, the name or exp needs a new signature
referrer_not_allowedThe page embedding a signed link isn't in the link's allowed_referrersAdd the site to allowed_referrers, or remove the list

404 Not Found

CodeMeaningFix
not_foundThe resource doesn't exist, or belongs to another workspaceCheck the ID and the key's workspace
template_not_foundNo template with this IDCheck the template_id; GET /v1/templates lists them
render_not_foundNo render with this IDCheck the ID and the key's workspace; test keys only see test renders
version_not_foundThe template has no such versionList versions with GET /v1/templates/{id}/versions
upload_not_foundThe upload doesn't exist or has expiredUploads expire 24 hours after creation; upload the file again

408 Request Timeout

CodeMeaningFix
render_timeoutA sync render reached the plan's sync timeout and was canceled because timeout_behavior is cancelUse mode: "async", simplify the document, or upgrade for a longer timeout

409 Conflict

CodeMeaningFix
idempotency_in_progressAn earlier request with the same idempotency key is still runningWait briefly and retry with the same key
draft_revision_conflictThe template draft changed since you read itFetch the current draft and apply your change again
conflictThe request doesn't fit the resource's current state, for example canceling a render that already finished, retrying a batch that is still running, or replaying a delivery to a deleted endpointRead the detail, which says what conflicts
zero_retentionretry-failed on a zero-retention batch, which keeps no item dataSubmit the failed items in a new batch
item_files_expiredretry-failed on a batch with combine whose succeeded items' files are gone, so new combined files couldn't hold them. items lists those items' indexes.Submit the failed items in a new batch. See combined files.
email_connection_in_useEmail rules still use the connection you're deletingChange or delete those rules first
email_file_expiredA file of the email send is no longer hosted, so the send can't be repeatedRender the document again
email_not_resendableThe send can't be repeated: its content wasn't kept, or it failed before sendingFix the rule or the data and render again

410 Gone

CodeMeaningFix
template_deletedThe template was deletedRestore it from the trash in the dashboard, or use another template
file_expiredThe file was deleted at the end of its retention period or purgedRender again, or raise the retention period
link_expiredA signed link or the URL's exp has expiredSign a new URL, or extend the link's expires_at

413 Payload Too Large

CodeMeaningFix
payload_too_largeThe request body is larger than your plan allowsTrim the payload, use data_url for large data sets, or upgrade
output_too_largeThe generated file exceeds the limit for the delivery type (20 MB for binary, 10 MB for base64) or the maximum output sizeUse url delivery, compress images, or split the document

415 Unsupported Media Type

CodeMeaningFix
unsupported_media_typeThe Content-Type isn't supported by this endpointSend application/json, or multipart/form-data when uploading files

422 Unprocessable Entity

Most render failures land here. When a render was created before it failed, the body includes render_id.

CodeMeaningFix
template_syntax_errorThe template can't be parsedFix the syntax at the reported line and column; the editor flags these live
template_runtime_errorThe template failed while rendering, for example an unknown filter, an unsupported operation, or an undefined value in strict modeCheck the line, column and excerpt against your data
template_fuel_exhaustedThe template exceeded its execution budgetSimplify nested loops, precompute values in your application, or upgrade
data_schema_mismatchThe data doesn't match the template's JSON SchemaRead errors[] for the failing paths, or relax the schema
idempotency_key_reusedThe same idempotency key was used with a different bodyUse a new key for a different request
url_not_allowedThe target URL is blocked: a private or internal address, an unsupported scheme or a non-standard portUse a publicly reachable HTTP or HTTPS URL on a standard port
navigation_failedThe page couldn't be loadedCheck that the URL is reachable from the public internet and that any credentials in input.http are correct
wait_timeoutThe page never reached the wait condition within wait.timeout_msCheck that the selector appears or the ready flag is set, raise the timeout, or use another wait strategy
asset_fetch_failedA required remote file couldn't be fetched, such as the source URL of a PDF toolCheck that the host is reachable and fast enough, or upload the file instead
data_url_fetch_failedThe data_url couldn't be fetchedCheck that the URL is public, returns JSON and responds quickly
page_limit_exceededThe PDF has more pages than your plan allowsCheck for unexpectedly long data, split the document, or upgrade. Nothing is billed.
attachment_failedA file in pdf.attachments couldn't be loaded, for example because its URL fails or it is too large; the message names itCheck the attachment's source and size. See Attachments.
invalid_pdf_sourceA PDF passed to a PDF tool isn't a valid PDFCheck the source file
pdf_password_requiredThe source PDF is encryptedSupply the password, or unlock the file first
scene_invalidA canvas template's design can't be rendered, for example because the output would be larger than 16,384 pixels on a sideRead the message; for size problems, lower the artboard size or scale
data_invalidA canvas template's data isn't an object, or a required dynamic property is missingSend an object with every required property
email_template_errorA field of an email rule, such as its subject or recipients, can't be parsedFix the field at the reported line and column. See Email delivery.
email_needs_hosted_fileEmail rules were requested for a zero-retention render, which keeps no file to sendLeave out delivery.email, or render without zero retention
render_failedThe render failed without a more specific codeSend us the render_id and request_id
pdfua_validation_failedThe PDF doesn't pass veraPDF's PDF/UA-1 checks, often because of a missing title, language, alt text or table headersRead the failed rules in result.conformance.pdfua. See PDF/UA.
pdfa_conversion_failedThe PDF couldn't be made PDF/A conformant, for example because a font isn't embedded or the source is encrypted, or veraPDF found it non-compliantRead the message, which names missing fonts, and the failed rules in result.conformance.pdfa. See PDF/A.
einvoice_invalidThe invoice model breaks a rule of the e-invoice profile before any XML is written, such as a missing field the profile requires, a VAT category without a rate or a net_amount that doesn't add upresult.conformance.einvoice.errors lists every problem with a JSON path into the invoice. See E-invoicing.
einvoice_validation_failedThe e-invoice validator rejected the generated XMLRead the rules in result.conformance.einvoice.errors; they usually concern content such as a missing Leitweg-ID or an invalid code

invalid_pdf_source and pdf_password_required come from the PDF tools, and scene_invalid and data_invalid from canvas templates. The last four codes come from PDF/UA, PDF/A and e-invoice output: such renders fail without being billed and carry the validation report in result.

423 Locked

CodeMeaningFix
template_lockedThe template is locked, so through the API its draft can't be replaced (PUT /v1/templates/{id}/draft) and it can't be deleted (DELETE /v1/templates/{id})Ask an Owner or Admin to unlock it in the dashboard

429 Too Many Requests

CodeMeaningFix
rate_limitedToo many requests per second for your planWait for Retry-After, smooth out bursts, or upgrade. See rate limits.
concurrency_limitedToo many synchronous renders are running at onceWait for Retry-After, use mode: "async", or lower your parallelism
quota_exceededA signed link has used its quota_total rendersRaise the link's quota; cached URLs keep being served

500 and 503

StatusCodeMeaningFix
500internal_errorSomething failed on our sideRetry with the same idempotency key. If it persists, send us the request_id.
503region_degradedThe region is running with reduced capacityRetry after Retry-After; see https://status.dynamicdocumentapi.com
503maintenancePlanned maintenance is in progressRetry after Retry-After; see https://status.dynamicdocumentapi.com

A render that the platform loses fails with the code render_lost: its job expired in the queue, or it stopped without a result well past its time limit. Nothing is billed; render it again.

Render warnings

Warnings don't fail a render. They appear in the render object's warnings array and in webhook payloads, and they are worth logging: they usually explain why output doesn't look the way you expect.

CodeMeaningWhat to check
slow_assetA remote asset took a long time to loadHost large images closer to the renderer, or embed them; slow assets also slow down renders
asset_failedAn asset couldn't be loaded and is missing from the outputCheck the URL and that the host is publicly reachable
font_fallback_usedA canvas template uses a font that isn't available, so Noto Sans was used insteadPick one of the bundled fonts, or add the font file to the template. HTML renders don't report fallback fonts; see common problems.
header_footer_overlapA header or footer is taller than its page margin, so it may overlap the bodyRaise margin.top or margin.bottom, or lower the height. See height and margins.
locale_unsupportedThe engine doesn't support the locale you setUse another BCP 47 tag, such as de-DE
feature_unavailableSomething in the request or the template can't take effect and was ignored, such as a @page :first rule meant to hide the header on the first pageRead the message, which names what was ignored
data_coercedA canvas template couldn't use a data value as given, such as an unknown key or a value that had to be shortened; an invalid value keeps the designed oneCheck the keys and values against the template's dynamic properties
text_overflowText in a canvas template was cut off or overflows its boxShorten the text or make the box larger
storage_upload_failedAn upload to one of your storage destinations failed for good. The message says whether a copy remains: the hosted file, a copy kept for a day with hosted: false, or none under zero retention.Check the destination's credentials and permissions
einvoice_validation_warningThe e-invoice validator accepted the XML but reported warnings; the message names the rulesRead result.conformance.einvoice.warnings and fix the content if your recipient requires it
einvoice_validation_unavailableThe e-invoice validator didn't answer in time, so the XML was delivered unvalidatedValidate the file yourself or render it again later
pdfa_validation_unavailableveraPDF didn't answer in time, so the PDF/A file was delivered unvalidatedRender it again later if you need the report
pdfua_validation_unavailableveraPDF didn't answer in time, so the PDF/UA file was delivered unvalidatedRender it again later if you need the report
accessibility_validation_unavailableA tagged PDF without pdfua comes without its PDF/UA report, because veraPDF didn't answer in timeRender it again later if you need the report
einvoice_skipped_planThe template embeds a ZUGFeRD e-invoice by default, but the plan doesn't include e-invoicing, so the PDF has noneUpgrade to Growth or higher, or send "output": {"einvoice": null} to render plain PDFs without the warning
storage_skipped_planThe workspace has a default storage destination, but the plan doesn't include storage destinations, so the files stayed hosted; under zero retention nothing was uploadedUpgrade to Starter or higher, or set is_default to false on the destination
email_skipped_planThe template has email rules, but they need the Growth plan or higher, so no email was sentUpgrade, or switch the rules off
email_skipped_zero_retentionZero-retention renders keep no file to email, so the template's email rules were skippedRender without zero retention when the document should be emailed
invoice_totals_unavailableThe template has a default e-invoice that this render doesn't embed, and the invoice at its data path couldn't be computed, so render.invoice is missingSend the invoice at the template's data path (invoice by default); the message names the first problem

Email sends report their own error codes in the email send object; see Email delivery.

On this page