Outcomes and error codes
Every failure answers with the same body shape, so one parser handles all of them:
{
"code": "TEMPLATE_VERSION_NOT_ACTIVE",
"number": 1204,
"message": "version 2 of template 'x' is not active; active versions are [1, 3]",
"details": { "requestedVersion": 2, "activeVersions": [1, 3] },
"retryable": false
}
Every outcome also has a number. 1204 and TEMPLATE_VERSION_NOT_ACTIVE are the same thing said twice: branch on the code in software, quote the number when you write to us from the contact page (/contatti) or wherever a long string is awkward to keep. Both are permanent — a number is never reused, renumbered, or moved to a different outcome.
They start at 1000 so that one can never be mistaken for an HTTP status, and the first two digits name the family: access, the request, template and version, the template file, data against the template, documents, signatures, flows, limits, ours rather than yours. Warnings start with 2, so the leading digit alone says whether the call succeeded.
Branch on code, never on message. The code is a stable contract; the message is a human hint and may be reworded at any time. details is present when there is something to act on, and retryable: true appears only when retrying the identical request could actually succeed.
In the console, API errors (under Build) counts what your keys were refused over the last day, week or month, by code, key and operation; each code links to its row below.
The full table
| Code | HTTP | When | Retry? |
|---|---|---|---|
| Success | |||
| (no code) | 200 | PDF generated; body is the file. Version used is in X-Template-Version. | — |
| Authentication | |||
MISSING_CREDENTIALS1001 | 401 | No Authorization: Bearer header. | no |
INVALID_API_KEY1002 | 401 | Key unknown, revoked or expired. Same answer for all three, so the API cannot confirm a key once existed. | no |
TENANT_INACTIVE1004 | 403 | The key is valid but its organisation cannot act: it is suspended, its registration is not approved yet (details.registration), it was archived after a long period without use (details.lifecycle is archived; ask to have it reactivated, nothing was deleted) or it was anonymised (details.lifecycle is anonymised). | no |
SUITE_NOT_ENABLED1005 | 403 | The key is valid and the organisation is active; the product you called is not switched on for it. The three are sold separately: composition (/api/v1/compose/documents/*, /api/v1/compose/templates/*), signature (/api/v1/sign/*) and the one-call flow (/api/v1/flow/*). details.suite names the one you called and details.enabled lists the ones you may. Nothing is charged. Your organisation’s administrator can see the same list under Settings, and only we can change it. | no |
FEATURE_NOT_ENABLED1007 | 403 | You asked for something your organisation has not bought: a trust service (settings.qeSeal or settings.qualifiedTimestamp set to true), an SMS one-time code (validationMode: "sms"), a bulk operation (/bulk/compose, /bulk/sign, /bulk/flow) or a signature level. Refused on every API (composition, signature and the flow alike) and never produced without it: unlike your organisation’s own settings, which hand back the ordinary document and say so in a warning, this one is invisible from your side, so a silent downgrade would be undetectable. details.feature names which one (qeSeal, qualifiedTimestamp, smsValidation, bulkCompose, bulkSign, bulkFlow, signatureSes, signatureAes, signatureQes) and details.enabled lists what you do hold; GET /api/v1/usage shows the same list. Nothing is charged. Ask your DoConure contact to activate it; only we can. | no |
IP_NOT_ALLOWED1003 | 403 | The key is valid; the address it arrived from is not on your organisation's allowlist. Distinct from INVALID_API_KEY on purpose — moving to a new server needs to be told apart from a bad key, and details.address echoes the address back, because it is not a secret from its own owner. | no |
ADMIN_LOGIN_REQUIRED1006 | 401 | A console page reached without a session. Not returned to API callers. | no |
TOKEN_SCOPE_NOT_ALLOWED1008 | 403 | Your organisation may call this; the token you sent was not granted the scope it needs. Distinct from SUITE_NOT_ENABLED, which is your organisation's own purchase — this is the token's own restriction, from the scopes you chose when you created it. details.missingScopes names what is missing. Create a token with the scope you need; an existing token's scopes only ever shrink, never grow, so re-issuing rather than editing is the fix. | no |
FEATURE_NOT_AVAILABLE_IN_TEST_MODE1009 | 422 | You sent isTest: true together with a feature that is paid for at an external provider: qeSeal, qualifiedTimestamp, an SMS one-time code (validationMode: "sms") or an AES/QES level. Refused before anything is reserved, sent or charged — a test call never spends money and is never silently downgraded. details.features names each. Send the call without isTest, or without the feature. | no |
FEATURE_NOT_AVAILABLE_IN_BULK1010 | 422 | The batch asked for something a bulk job cannot do yet: a seal or a qualified timestamp (charged after the fact, so a batch of them could overdraw what was reserved), a document password, a responseFormat (an item has no response of its own) or a filename (one name for many files). details.fields names each. Nothing was reserved; send the same batch without them, or send those documents one at a time. | no |
REQUIRED_FEATURE_NOT_AVAILABLE_IN_TEST_MODE1011 | 422 | You sent isTest: true to an organisation whose own settings require a seal or a qualified timestamp on every document (seal_mode / timestamp_mode = always). A test call never buys one, and a document the policy says must be sealed is never returned unsealed, so the call is refused before anything is reserved, sent or charged. details.features names each. Send the call without isTest, or change the setting. Where the setting is only optional, isTest skips the seal with PAID_EXTRA_SKIPPED_ON_TEST instead. | no |
TIMESTAMP_REQUIRES_SEAL1012 | 422 | You asked for a qualifiedTimestamp without a qeSeal (or your organisation's timestamp_mode is always and the document is not sealed). The qualified timestamp is an option of the qualified seal and is never applied on its own, so the call is refused before anything is rendered, reserved, sent or charged. Send qeSeal: true as well, or drop qualifiedTimestamp; a sealed document without a timestamp is fine. details.source says whether the request or the organisation's setting asked for it. | no |
| Template and version | |||
TEMPLATE_NOT_FOUND1201 | 404 | No such id, or it belongs to another tenant — deliberately indistinguishable. | no |
TEMPLATE_DEACTIVATED1202 | 409 | The template is switched off entirely. Activate a version in the admin. | no |
TEMPLATE_VERSION_NOT_FOUND1203 | 404 | You pinned a number that was never created. details.activeVersions lists what exists. | no |
TEMPLATE_VERSION_NOT_ACTIVE1204 | 409 | You pinned a version that exists but is off. details.activeVersions tells you what to use instead. | no |
NO_ACTIVE_VERSION1205 | 409 | The template exists and is on, but no version is active. | no |
| Signatures — Signer Fly | |||
SIGNATURE_LEVEL_UNAVAILABLE1601 | 501 | You asked for AES or QES. They are coming soon, in the next wave; only SES is produced today, and the request is refused, never downgraded — under eIDAS those are different legal objects, so being handed a weaker one silently would be worse than being told no. details.available lists what can be issued. See Signature levels: SES, AES, QES. | no |
SMS_VALIDATION_UNAVAILABLE1624 | 422 | A signer was set to validate by sms and the code cannot be delivered: the platform has no SMS provider configured (details.reason: provider_not_configured) or the number is outside the countries the sender is registered for (country_not_registered); details.signer names the signer. Refused when the envelope is created, before anything is sent, rather than an envelope nobody can sign or a code that quietly goes by email. Use validationMode: "email" for that signer. | no |
ENVELOPE_NOT_FOUND1602 | 404 | No such envelope, or it belongs to another tenant — deliberately indistinguishable, as with templates. | no |
ENVELOPE_NOT_EDITABLE1603 | 409 | It has already been sent. An envelope is composed once and sent once. | no |
ENVELOPE_CLOSED1604 | 409 | Completed, cancelled, declined or expired. details.status says which. | no |
ENVELOPE_NOT_CLOSED1605 | 409 | The evidence bundle was requested before the envelope reached a terminal status. details.status says what it is now. | no |
DOCUMENT_NOT_SIGNABLE1606 | 422 | The document exists but is not a PDF. | no |
DOCUMENT_SOURCE_UNAVAILABLE1607 | 501 | Retired 2026-10-04 and kept so the number is never reused. An uploaded PDF (fileId, or the inline fileBase64) is now a supported envelope source, so nothing raises this any more. If you meet it in old logs, it meant an upload was refused before uploads existed. | no |
STORED_FILE_IN_USE1620 | 409 | You tried to delete a stored file (a PDF you uploaded to be signed, or any file by fileId) while an open envelope — a draft, a sent or an in-progress one — still uses it. details.envelopeIds names them. Cancel or finish those first; a file that only finished envelopes use can be deleted, and its bytes are kept for their evidence until their retention ends. | no |
SOURCE_FILE_CHANGED1621 | 409 | You pinned a sha256 beside a fileId and it is not that file's. A stored file never changes — a new version is a new upload with a new fileId — so this means the id names a different file from the one you meant. | no |
SIGNER_FIELD_INVALID1622 | 422 | Signer-facing. A field the sender required (a text, a ticked checkbox, a dropdown choice) was left empty, or answered with something that is not allowed. The signature was not taken: the signer corrects the answer and signs again. details.fields names each. | no |
CALLBACK_DELIVERY_NOT_FOUND1623 | 404 | The webhook delivery you asked the console to send again does not exist, or belongs to another organisation — deliberately indistinguishable. | no |
CALLBACK_ENVIRONMENT_UNKNOWN1625 | 422 | callbackUrl.env names no callback environment of your organisation, or you sent a path without env and no environment is the default. Refused at the call, before anything is created or charged. details.known lists your environments. | no |
CALLBACK_PATH_INVALID1626 | 422 | A callback path that could change the host (a scheme, //, @, .., a backslash or a fragment), a full URL sent together with env, or a path mixed with a full URL. Send only the end of the URL; the environment holds the host. details.reason says which. | no |
CALLBACK_ENVIRONMENT_IN_USE1627 | 409 | The console was asked to delete a callback environment that open envelopes, running batches or queued callbacks still name. Wait for them to close; details counts them. | no |
CALLBACK_ENVIRONMENT_INVALID1628 | 422 | Console only, never an API answer. A callback environment could not be saved: the sigla, the base URL, the type of authentication or its credentials. details.field names which. | no |
SIGNATURE_TAG_UNKNOWN_SIGNER1629 | 422 | A signature tag in the document, such as {{ signature.C }}, names a signer your request does not have. Add the signer, or remove the tag from the template. A flow is refused before anything is composed or charged when the tag is in the template; a tag typed in an uploaded annex is read after composing. details.tags and details.signers say which. | no |
SIGNER_NOT_PLACED1630 | 422 | The document places its signers with signature tags, and a signer has neither a tag nor fields, or its tag was not in the finished document (for example inside a condition that was false). Add a tag or fields for them. details.signers names them. | no |
SIGNATURE_TYPE_NOT_ALLOWED1611 | 422 | The signer chose a way of making a mark that the organisation does not permit. Never substituted for an allowed one — somebody who drew their name and found a typed one on the document would have signed something they did not do. The signing page offers only the ways the organisation accepts, so a signer meets this only by sending another way anyway, and is then shown the form again with the reason. | no |
DELEGATION_NOT_ALLOWED1613 | 403 | Signer-facing. They tried to pass the request to somebody else and may not: the organisation forbids it for this envelope, or it has already changed hands as often as it may. | no |
SIGNING_LINK_INVALID1608 | 404 | Signer-facing. The link is unknown, already used, or was killed by a cancellation. | no |
SIGNING_LINK_EXPIRED1609 | 410 | Signer-facing. Past the envelope's deadline. Issue a new envelope. | no |
SIGNING_OUT_OF_TURN1610 | 409 | Signer-facing. A sequential envelope, and it is somebody else's turn. | no |
RECIPIENT_ALREADY_SIGNED1612 | 409 | Signer-facing. That person has already signed; links are single-use. | no |
OTP_REQUIRED1614 | 403 | Signer-facing. No live code — ask for one first. | no |
OTP_INVALID1615 | 403 | Signer-facing. Wrong code. The attempt is counted. | no |
OTP_TOO_MANY_ATTEMPTS1616 | 429 | Signer-facing. Too many wrong guesses on one code, or too many codes requested. A fresh code resets the guesses. | no |
RECIPIENT_NOT_FOUND1617 | 404 | No such recipient on that envelope — including one that belongs to another tenant, which answers the same as absent. | no |
VALIDATION_MODE_UNAVAILABLE1618 | 501 | Reserved for a validationMode this service does not yet support. Not raised for "sms" any more — that mode works, with a real SMS gateway (refused with SMS_VALIDATION_UNAVAILABLE where a code cannot be delivered) — but kept for whatever validation mode comes after it. | no |
RECIPIENT_NOT_REQUIRED1619 | 409 | Signer-facing. This recipient's group signs "OR" and somebody else in it already signed — their own signature was never required, and there is nothing left to act on for that link. | no |
| Flows — Document Fly | |||
FLOW_NOT_FOUND1701 | 404 | No such flow, or it belongs to another tenant — deliberately indistinguishable. | no |
FLOW_CLOSED1702 | 409 | The flow has already finished, been cancelled, or expired. | no |
| Request payload | |||
INVALID_REQUEST_BODY1101 | 422 | Body does not match the expected shape. details.fields names each offending field. | no |
IDEMPOTENCY_KEY_REUSED1104 | 422 | The same Idempotency-Key arrived with a different request. Answering it with the first call’s result would look to you exactly like success, so it is refused instead. Use a new key, or send the same request. | no |
IDEMPOTENCY_IN_PROGRESS1105 | 409 | A request with this key is still running. Retryable, with a Retry-After: you are doing the right thing, just early. | yes |
IDEMPOTENT_RESULT_GONE1106 | 410 | The key is known and its result cannot be served again — the generation was dataless and kept nothing, or the document reached its retention date. details.jobId names the work: you were charged once, not twice, which is what you were retrying to find out. | no |
BULK_INPUT_INVALID1107 | 422 | The batch (or the uploaded file) is malformed as a whole: a line that is not JSON, an item without data, a duplicate externalId, an empty batch, both or neither of items and fileId. details.problems lists up to twenty, each with its line (a file) or index (inline). Nothing was reserved or created; fix the input and send it again. | no |
IDEMPOTENCY_KEY_REQUIRED1109 | 422 | You asked for a qeSeal on a compose or flow call that carries no Idempotency-Key. A retry after a timeout could not be told from a new request and would buy a second seal at the provider, which cannot be reversed. Send the header (any unique string, reused only when you retry the same call). Nothing was reserved, sent or charged. | no |
FILE_REJECTED1121 | 422 | An uploaded file was refused: empty, not a PNG, JPEG, WebP or PDF by its bytes (SVG is refused), unreadable, encrypted, a PDF with scripts, launch actions, embedded files or forms that submit, or a PDF with more than 500 pages (200 for a PDF uploaded to be signed). details.reason says which; nothing was stored. | no |
INVALID_JSON1102 | 400 | The body is not parseable JSON. | no |
JSON_STRUCTURE_LIMIT_EXCEEDED1108 | 422 | The JSON body is nested deeper, or holds more values, than the platform reads, and was refused before it was parsed. details.limit is depth or nodes, with the figure in force. A long list belongs in a bulk job or a stored file. | no |
MISSING_TEMPLATE_FIELD1401 | 422 | An absent field renders empty by default — see Missing and extra fields — so this is raised only when the template is set to reject incomplete data, or when a field is absent from an object the template does reach. details.fields / details.field names them. | no |
TEMPLATE_DATA_MISMATCH1402 | 422 | The template and the payload do not fit together: a field that is present and of the wrong kind. {{ importo + 1 }} against "quarantadue" cannot render, and leniency does not cover it — leniency is about fields that are absent. details.problem names the kind of failure. Never retryable: the identical request fails identically. (Before 2026-09-19 these answered INTERNAL_ERROR, which is marked retryable — so a caller obeying that flag retried forever.) | no |
PAYLOAD_SCHEMA_VIOLATION1403 | 422 | The payload does not satisfy the template's JSON Schema and the template is set to payloadValidation: "reject". Refused before any credit is reserved or any slot taken, so it costs nothing. details.violations lists the first ones as {path, keyword, message} (JSON pointer into your data), details.count how many there were. The offending value is never in it. Never retryable: fix the data, or set the template to warn. | no |
DATALESS_NOT_AVAILABLE1103 | 422 | You sent settings.dataless: true to /api/v1/flow. A document that is being signed has to be kept — a signature with nothing to show is not a signature, and its evidence is kept for ten years — so the request is refused rather than half-honoured. Compose it at /api/v1/compose/documents/generate if nothing may be stored. Refused before anything is generated or charged. | no |
PAYLOAD_TOO_LARGE1803 | 413 | The request body is over 25 MB, the largest this service accepts, so nothing was received or processed. On /api/* and /verify.json the answer is the usual JSON error body (output.error included), like every other refusal; smaller limits of your own (a template, an uploaded file) are refused with this code too and say the limit in the message. | no |
| Template file | |||
TEMPLATE_FILE_INVALID1301 | 422 | The stored template file could not be read or merged. | no |
TEMPLATE_FILE_REJECTED1302 | 422 | Refused at upload: macros present, or a suspicious archive. | no |
JSON_SCHEMA_INVALID1303 | 422 | The jsonSchema sent with a template or a version cannot be enforced: not valid JSON Schema, a keyword outside the supported subset, a $ref that is not local to the schema, or past the size, depth or pattern caps. Refused at upload so that no compose call ever meets it. details.problems names each, with its path inside the schema. | no |
| Documents | |||
DOCUMENT_NOT_FOUND1501 | 404 | No such document id, or it belongs to another tenant. | no |
BULK_JOB_NOT_FOUND1502 | 404 | No bulk job with that id, or it belongs to another organisation — the two are indistinguishable on purpose. | no |
BULK_FILE_NOT_FOUND1503 | 404 | No uploaded bulk file with that id for your organisation, or a job already used it, or it expired (an upload not used within its lifetime is deleted). Upload it again. | no |
BULK_RESULTS_UNAVAILABLE1504 | 409 | The result bundle of a bulk job cannot be built: the job has not finished, or its per-item results were deleted by retention. details.reason says which (job_not_finished, results_expired). The documents themselves follow their own retention. | no |
BULK_RETRY_NOT_POSSIBLE1505 | 409 | The failed items of a bulk job cannot be put back: it has not finished, nothing in it is retryable, the payloads were not kept (an organisation that composes without keeping data), or its results expired. details.reason says which; details.skipped lists items refused one by one. An item whose outcome is unknown is never repeated. | no |
STORED_FILE_NOT_FOUND1520 | 404 | No stored file with that id for your organisation: it never existed, was deleted, expired, or belongs to another organisation — the same answer for all. Upload it again. | no |
DOWNLOAD_LINK_NOT_FOUND1521 | 404 | The document or download link you named to mint, list or revoke is not yours, or does not exist. | no |
DOWNLOAD_LINK_INVALID1522 | 404 | The public download address is unknown, altered, revoked, already used (single use) or no longer matches its document — one answer for all, so it cannot be probed. Ask for a new link. | no |
DOWNLOAD_LINK_EXPIRED1523 | 410 | The download address was genuine and has expired. Mint a new one. | no |
| Service side | |||
RENDERING_FAILED1901 | 500 | The merge step failed for a reason that is not the payload's fault. | no |
CONVERSION_FAILED1902 | 500 | PDF conversion failed, or a settings-driven post-processing step did (PDF/A export, colour conversion). | no |
CONVERSION_TIMEOUT1903 | 504 | Conversion or post-processing exceeded its time limit. | yes |
STORAGE_UNAVAILABLE1904 | 503 | Template or document storage could not be reached. | yes |
INTERNAL_ERROR1905 | 500 | Anything unclassified. | yes |
TRUST_PROVIDER_NOT_CONFIGURED1906 | 503 | This deployment cannot perform what you asked for — the platform does not offer the qualified seal and timestamp (details.comingSoon: true, whatever your organisation holds; they are on sale now, so this is a switch we turned off), or no sealing certificate or timestamp authority is configured, or a provider does not offer the one you asked for. Ours to fix, not yours, and distinct from FEATURE_NOT_ENABLED for that reason. The document is refused, before anything is reserved or charged, rather than returned without what it was asked to carry. | no |
TRUST_PROVIDER_UNAVAILABLE1907 | 503 | The seal or timestamp provider was asked and could not be reached, or refused us — a connection that never got through, a rate limit, an upstream failure. details.category carries the normalised reason. Retryable: the identical request works once they answer, and nothing about it has to change. | yes |
SEAL_FAILED1908 | 502 | A qualified seal was asked for, everything allowed it, and it could not be applied — so no document is returned. Deliberate: a composition can be run again, and handing back an unsealed PDF where a seal was asked for would be claiming a property the file does not have. Nothing was charged for the seal. Not marked retryable, because the provider may have performed the operation before the failure and a blind retry could buy a second one. details.category: "OUTCOME_UNKNOWN" is that case exactly: the provider received the request and its answer was lost. An envelope behaves differently on purpose — see SEAL_NOT_APPLIED. | no |
TIMESTAMP_FAILED1909 | 502 | The same, for the qualified timestamp. | no |
BULK_JOB_TIMED_OUT1910 | 504 | Seen only as the error of a bulk item: the item was still waiting when its job passed its deadline, so it was not run. Its credit was released. Put it in a new batch. | yes |
PROVIDER_BILLING_PROFILE_INCOMPLETE1911 | 503 | The seal provider refused because our own account with it is not complete. This is ours to fix and nothing in your request can change it: you are told the service is temporarily unavailable, nothing is charged for the seal (anything already paid for it at the send is returned), and the identical request works once we have fixed it. | yes |
| Limits | |||
QUOTA_EXCEEDED1801 | 429 | The prepaid balance does not cover the operation: no credit left. details carries requestedCredits, currentBalance, reservedCredits, availableCredits and missingCredits, and a flow names its breakdown. The whole request is refused before any work, and nothing was reserved. | no |
RATE_LIMIT_EXCEEDED1802 | 429 | More than max_requests_per_minute calls in the last 60 seconds. Carries Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. | yes |
SERVER_BUSY1804 | 503 | Every conversion slot on this instance is in use (measured ceiling, not a per-tenant limit). Carries Retry-After; a well-behaved caller waits that long before retrying rather than immediately. | yes |
SERVICE_PAUSED1805 | 503 | An operator has paused generation across the whole platform — the emergency switch that exists so an incident can be stopped without a deploy. Nothing is wrong with your request and nothing about it needs to change; the identical call succeeds once the pause is lifted. Carries Retry-After. | yes |
RECIPIENT_VOLUME_EXCEEDED1806 | 429 | Sending this envelope would take your organisation past the number of distinct addresses it may write to in a rolling 24 hours — signers, cc and bcc together, across every envelope. Outbound mail leaves under a shared sender, so this protects the deliverability of everybody’s signature requests rather than any one account. Nothing was charged and the envelope is untouched: it is still a draft and the same call works tomorrow. The ceiling is higher once your organisation has completed a purchase, and an operator can raise it further for a customer that genuinely sends at volume. | yes |
TEST_QUOTA_EXCEEDED1807 | 429 | Your organisation has spent its shared daily pool of isTest items (20 a day unless an operator set another number); a whole call is refused, never trimmed to what is left. details carries requestedItems, remainingTestItems and dailyLimit. Nothing was charged — a test call never touches credit. The pool resets at UTC midnight. A test item is spent on the attempt, so a retried failing call still uses one. | no |
TEST_CAPACITY_TEMPORARILY_LIMITED1808 | 503 | A test (isTest) call was turned away to protect production: a production request was waiting, the test share of the render slots was in use, or the test queue was full. Nothing was reserved, charged or taken from the test pool. Carries Retry-After; sandbox traffic is throttled first by design, so back off and try again. | yes |
QUEUE_CAPACITY_EXCEEDED1809 | 503 | The line for a render slot in this request's class is full, so waiting would only have ended in SERVER_BUSY. Refused before any work; nothing was charged. Carries Retry-After. | yes |
TENANT_CONCURRENCY_LIMIT_REACHED1810 | 429 | Your organisation already has as many documents rendering (or waiting to) as one organisation may hold at once. Other organisations are not affected. Nothing was charged. Carries Retry-After; sending fewer calls at the same moment avoids it. | yes |
BULK_ITEM_LIMIT_EXCEEDED1811 | 422 | The batch has more items than allowed — the lowest of your own options.maxItems, your organisation’s limit and the platform’s, or, for an isTest batch, the test cap. Refused whole and never trimmed. details.requestedItems and details.allowedItems say by how much. Nothing was reserved. | no |
JOB_TOO_LARGE1812 | 413 | The bulk body or the uploaded file is over its byte limit (details.limit). For a large batch upload a file instead of sending the items inline. | no |
BULK_CONCURRENCY_LIMIT_REACHED1813 | 429 | Your organisation already has as many bulk jobs running, items queued, unused uploads or submissions in the last minute as the platform allows; details.what says which. Nothing was reserved. Retry when a job finishes. | yes |
MAINTENANCE_MODE1814 | 503 | The platform is in planned maintenance: every call is answered with this until it ends, and nothing is done or charged. details.state is on. While maintenance is about to start it is pending: the bulk jobs already running are finished, and a new bulk job (or a retry of one) is refused with this code; single calls still work, and every answer carries X-Maintenance-Pending with the seconds left. Carries Retry-After; the identical call works afterwards. | yes |
PURCHASE_AMOUNT_TOO_LARGE1815 | 422 | One credit purchase is more than EUR 1,000.00, VAT excluded — the most a single purchase may be (EUR 1,220.00 with Italian VAT). Refused before any order is opened or any payment provider is called: nothing is reserved or charged. Make several purchases, or contact us (the contact form, or Report a problem in the console) for a larger amount. details.netCents and details.maximumNetCents say by how much. | no |
SUBSCRIPTION_ALLOWANCE_EXHAUSTED1816 | 429 | A counter of your plan (signatures, documents or calls) has nothing left for this request, and paying with credit after it is off (the default). Refused whole before anything is reserved or charged: a batch is never half-admitted, and a flow is not half-paid. Turn on Pay with credit when a counter of the plan is used up on the Billing page, renew, or wait for the next period. details.remaining and details.requested (by counter), details.missing (what is short) and details.endsAt say where you stand. An SMS code to a signer is never refused this way. | no |
FILE_LIMIT_REACHED1830 | 429 | Your organisation already keeps as many stored files as the platform allows. Delete some, or wait for them to expire. | no |
Warnings: a call that succeeded, having done less
Some settings are not yours alone to decide. An organisation can require
its signed documents to be sealed, or forbid it, from its own Settings page —
and that setting is a ceiling, not a default: your request
may go under it, never over. When it overrules something you asked for
explicitly, the call still succeeds and the answer carries a
warnings array.
{
"id": "…",
"seal": false,
"timestamp": false,
"padesProfile": null,
"warnings": [
{
"code": "SEAL_NOT_ENABLED",
"number": 2001,
"message": "this organisation does not seal signed documents, so 'settings.seal' was ignored; the document was produced unsealed",
"details": { "setting": "seal_mode" }
}
]
}
A warning is not a softer error. It arrives on a 2xx and
the operation went ahead. The rule for which you get: a request that would
hand you something different from what you asked for is
refused (that is why level: "AES" is a 501);
a request that hands you less — the ordinary document, without an
attestation — succeeds and warns.
Read seal, timestamp and, once the envelope
completes, padesProfile from the response rather than assuming
what you sent was used. They are echoed on every read of the envelope, and
the warnings are stored with it, so a later
GET /api/v1/sign/envelopes/{id} still tells you.
| Code | When |
|---|---|
SEAL_NOT_ENABLED2001 | You asked for a seal; the organisation has sealing switched off. The document is produced unsealed. |
TIMESTAMP_NOT_ENABLED2002 | The same for a timestamp. |
SEAL_REQUIRED_BY_ORGANISATION2003 | You asked not to seal; the organisation seals everything. It is sealed, and charged for. |
TIMESTAMP_REQUIRED_BY_ORGANISATION2004 | The same for a timestamp. |
SEAL_NOT_CONFIGURED2005 | Wanted by everybody, and this platform has no sealing certificate installed. Ours, not yours — nothing in your request can fix it. |
TIMESTAMP_NOT_CONFIGURED2006 | The same, for the timestamp authority. |
SEAL_NOT_APPLIED2007 | Configured, wanted, attempted at completion, and it did not work. The envelope still completed: a third party being unreachable never costs a signature that has been given. |
TIMESTAMP_NOT_APPLIED2008 | The same. Appears on the envelope after it completes, not on the create call. |
SEAL_NOT_ENTITLED2009 | Your organisation’s own setting seals every document, and the qualified seal is not active on the account. The document is produced without it and nothing is charged. You see this only when you asked for nothing: a request that asks explicitly is refused with FEATURE_NOT_ENABLED instead, because then somebody would be believing something untrue. |
TIMESTAMP_NOT_ENTITLED2010 | The same, for the qualified timestamp. |
DELEGATION_NOT_ENABLED2102 | You asked to let signers pass the request on; the organisation does not allow it. The envelope is created and the option is off. |
DELEGATION_REQUIRED_BY_ORGANISATION2103 | You asked not to allow it; the organisation always does. |
TEMPLATE_FIELDS_MISSING2104 | The template reads fields your payload did not carry. They rendered empty and the document was produced, because this template is not set to refuse incomplete data (errorOnMissingFields). details.fields names every one of them — this is the warning to read when a PDF comes back with blanks in it. |
RENDER_NOTES2105 | The renderer had something to say while producing this document: a value it shortened, a section that did not appear, a comparison it could not make. details.notes carries the texts and details.count how many — except on a dataless generation, which gets the count alone, because a note quotes your own values. |
PAYLOAD_SCHEMA_VIOLATIONS2106 | The payload does not satisfy the template's JSON Schema and the template is set to warn (the default), so the document was produced anyway. details.violations lists the first ones as {path, keyword, message} and details.count how many there were. A value from your payload is never in it, so it is the same on a dataless generation. |
TRUST_NOT_QUALIFIED2107 | The seal or timestamp on this document was applied by a provider that is simulated or not declared qualified (details.feature, details.simulated). The structure is genuine and verifies, but it carries no eIDAS presumption of origin or time. The call did what it said; treat the document accordingly. The same facts are in output.compose.trust as qualified and simulated. |
COMPRESSION_SKIPPED2120 | compressionLevel was asked for and not applied: the document is converted to PDF/A, is black-and-white, or compressing would not have made it smaller (details.reason: pdfa, blackwhite, not_smaller). The document is exactly what the request without the setting would produce. |
PDFA_NOT_VERIFIED2121 | A PDF/A conversion was made and the result was not validated against a PDF/A checker, so no conformance is claimed. output.compose.pdfa.verified is false. Validate the file yourself if you rely on it. |
ATTESTATION_REFUNDED_ENVELOPE_CLOSED2130 | An envelope was cancelled, expired or declined after it was sent, so the seal and the timestamp it had paid for were returned to the credit they came from. The signature is not returned: the work of sending was done. details.units and details.credits say what came back. |
ATTESTATION_REFUNDED_NOT_APPLIED2131 | The seal or timestamp paid at the send could not be applied when the last signer finished (the provider or the authority was down or refused), so it was returned at once. The envelope completed without it, as SEAL_NOT_APPLIED says. |
ATTESTATION_REFUNDED_OUTCOME_UNKNOWN2132 | The seal's request reached the provider and the answer was lost. We cannot say whether it was performed, so it was returned at once and the request is not repeated: the risk is ours, not yours. The envelope completed without the seal. |
DOCUMENT_NOT_STORED2201 | This generation was dataless: the PDF in your hands is the only copy there will ever be, and nothing about the request was written down. Arrives as a header (X-Warning-Code) rather than in a body, because the body of that call is the PDF. X-Document-Id is empty for the same reason. See Generating a document. |
DOCUMENT_STORED_FOR_SIGNATURE2202 | Your organisation composes dataless and this call was a flow, so the document was kept — it is being signed. What you sent was still not recorded. The half that could be honoured, was, and this says which half. |
DOCUMENT_STORED_FOR_BULK2203 | Your organisation composes dataless and this was a bulk batch, so its documents were kept — a batch answers with no bytes, and they are fetched afterwards. What you sent was not recorded, and each item’s payload is wiped when the item finishes. |
PAID_EXTRA_SKIPPED_ON_TEST2101 | This is a test organisation, or an isTest call whose organisation setting switches on something that costs real money at a third party (a seal or a timestamp). A call that itself asks for the feature together with isTest is refused with FEATURE_NOT_AVAILABLE_IN_TEST_MODE (1009) instead. Refused before it is bought, whatever the organisation's own settings say — test documents are not worth paying for. At every door — composition, envelope and flow. details.feature names which: qeSeal or qualifiedTimestamp. Use the live organisation to see a sealed document. |
Rate limiting is per organisation, and a key can have its own
limit too. Several active keys on one account share the
organisation's per-minute budget; a key given a lower limit of its own is
refused on that one first (details.limitedBy: "token", see
A limit for one key). Besides
the per-minute limits there are size limits (a request body of at most
25 MB, and the sizes under Reference → Limits in your console),
the daily pool of test calls and a 24-hour ceiling on signing invitations.
SERVER_BUSY is different: it is a
shared ceiling across every tenant on the instance, not a per-tenant
number — it exists to protect the machine, not to meter your account.