KovaPDF API error codes
Every error is JSON with a sentence for a person in error and a stable code in code. Switch on the code: the wording of the sentence may change. This page lists all 119 codes, grouped by what they are about. Each code has its own link, such as #monthly_limit.
HTTP/1.1 429 Too Many Requests
Retry-After: 172800
{
"error": "Monthly limit reached: your account has used all 5000 tasks this month. Live calls start again on 1 December 2026. Write to support@kovapdf.com to raise the limit.",
"code": "monthly_limit",
"limit": 5000,
"used": 5000,
"retryAfter": 172800
}Keys and access
The key in the Authorization header, what it may do, and where it may be used from.
| Code | Status | What it means | What to do |
|---|---|---|---|
missing_api_key | 401 | There is no Authorization header, or it does not hold a Bearer key. | Send Authorization: Bearer followed by your key. |
invalid_api_key | 401 | We do not know this key. | Check that you copied the whole key. If it is lost, revoke it in your account and make a new one. |
revoked_api_key | 401 | The key was revoked, or the person who held it left the workspace. | Make a new key in your account, or ask the workspace's Owner for one. |
expired_api_key | 401 | The key passed the end date chosen when it was made. The answer carries expiredAt. | Make a new key and switch your server to it. |
api_access_required | 402 | A live call from an account without API access. Older keys that start with kova_ only, made before test and live keys existed, get it too once their 30 day changeover ends. The answer carries requestAccessUrl. | Use a test key, or ask for API access on the request form. |
key_paused | 403 | The key paused itself after a burst of tasks or too many bounced signing emails, or we paused it. | Write to support@kovapdf.com. We look at it with you and turn it back on. |
ip_not_allowed | 403 | The call came from an address that is not on the key's IP allow list, or not on the list agreed for your account. | Call from an allowed address, or change the key's list in your account. |
insufficient_scope | 403 | The key does not have the scope this endpoint needs. required names it, granted lists the key's scopes, and WWW-Authenticate says the same. | Make a key with that scope. |
two_factor_required | 403 | The workspace asks everyone to use two step sign in, and the account that holds the key has it off. | Turn on two step sign in for that account, then call again. |
workspace_inactive | 403 | The workspace the key belongs to is closed, or has no Owner right now. | Make a personal key, or ask the workspace's Owner. |
account_inactive | 403 | The account the key belongs to, or works for, is not active. | Write to support@kovapdf.com. |
api_blocked | 403 | This account may not use the API. | Write to support@kovapdf.com. |
tool_blocked | 403 | Signing or verifying is switched off for this account. | Write to support@kovapdf.com if you think this is a mistake. |
TOOL_BLOCKED | 403 | Request Signatures is switched off for this account. | Write to support@kovapdf.com if you think this is a mistake. |
EMAIL_NOT_VERIFIED | 403 | Signature requests go out in your name, so your account needs a confirmed email address. | Confirm your email address from the link we sent, then send again. |
Test keys
A test key runs 10 tasks within 14 days. These codes say that the test has run its course.
| Code | Status | What it means | What to do |
|---|---|---|---|
test_key_used_up | 401 | The test key has run all of its test tasks, so it no longer works. The answer carries requestAccessUrl. | Ask for API access on the request form. |
test_key_expired | 401 | The free test ended: it runs 14 days from your first test key. The answer carries requestAccessUrl. | Ask for API access on the request form. |
test_monthly_limit | 429 | An account with API access has used this month's test tasks. Retry-After counts down to the 1st of next month. Live keys are not affected. | Use your live key, or wait for the new month. |
Limits
Every limited call gets 429, a plain sentence in error and, where waiting helps, a Retry-After header in seconds. Refused calls are not counted.
| Code | Status | What it means | What to do |
|---|---|---|---|
rate_limited | 429 | More than 60 calls a minute with this key, or more than 30 signature requests sent in an hour with it. Reminders count as sends. | Wait the seconds in Retry-After, then send again. |
daily_limit | 429 | The key's calls for today (UTC) are used: the lower of the cap you set on the key and your plan's cap. | Wait until midnight UTC, or raise the key's cap in your account. |
monthly_limit | 429 | Your account has used every task of its monthly limit. The answer carries limit, used and retryAfter. Nothing is charged on top. | Wait for the 1st of next month, or write to support@kovapdf.com to raise the limit. |
credits_used | 429 | Every task in your account's pack is used. | Write to support@kovapdf.com for more tasks. |
limit_reached | 429 | Your account's own allowance for signing or verifying is used, the same allowance as on the website. | Wait the seconds in Retry-After, or look at your plan. |
DAILY_LIMIT | 429 | Sending documents for signature is paused on your account. | Write to support@kovapdf.com. |
FREE_MONTHLY_LIMIT | 429 | The Free plan's signature requests for this calendar month are used. | They come back on the 1st, or upgrade your plan. |
FREE_RECIPIENT_DAILY | 429 | On the Free plan, one of the people on the request has already had a lot of signature emails today. | Try again tomorrow, or upgrade your plan. |
Safe retries
Every POST takes an Idempotency-Key header. A repeat with the same key and the same body within 24 hours gets the first answer back.
| Code | Status | What it means | What to do |
|---|---|---|---|
invalid_idempotency_key | 400 | Idempotency-Key is empty, longer than 255 characters, or has characters that are not visible ASCII. | Send a UUID, or another string of 1 to 255 visible characters. |
idempotency_key_reused | 422 | This Idempotency-Key was already used with a different request. | Make a new key for every new request. Reuse a key only to send the very same request again. |
idempotency_in_progress | 409 | The first request with this key is still running. Retry-After is 2 seconds. | Wait a moment and send it again. You then get the first request's answer. |
Requests and files
Something in the call itself: a missing part, a file we cannot read, or a request that does not exist.
| Code | Status | What it means | What to do |
|---|---|---|---|
invalid_request | 400 | Details are missing or not valid. issues lists up to five problems, each with a path and a message. | Fix the fields named in issues. |
missing_file | 400 | There is no multipart part called file. | Attach the PDF as the field file. |
empty_file | 400 | The file you sent is empty (0 bytes). | Check the file on your side and send it again. |
missing_certificate | 400 | There is no multipart part called certificate. | Attach your .pfx or .p12 file as the field certificate. |
unsupported_file_type | 400 | The signature image is not a PNG, JPEG or WebP. | Send the image in one of those formats. |
invalid_pdf | 400 or 422 | The file is not a PDF we can read. | Open it on your side to check it, or save it again as a PDF. |
encrypted_pdf | 422 | The PDF is protected with a password. | Remove the password first. |
file_too_large | 413 | The file is larger than the limit for signing and verifying. | Send a smaller file. |
certificate_too_large | 422 | The certificate file is far larger than a real .pfx. | Check that you attached the certificate, not another file. |
invalid_certificate | 422 | The certificate file is not a PKCS#12 (.pfx or .p12) file. | Export the certificate with its private key as .pfx or .p12. |
NO_FILE | 400 | A signature request without a PDF. | Attach the PDF as the field file. |
BAD_PDF | 400 | The file for a signature request cannot be read as a PDF, or a test key cannot stamp TEST on it (for example a PDF with a password). | Send a readable PDF without a password. |
INVALID | 400 | The spec part is missing or is not a JSON object. | Send the request details as the multipart field spec, as JSON. |
INVALID_VERSION | 400 | version is not original, current or final. | Use one of those three. |
NOT_FOUND | 404 | No such signature request, or not one this key can reach. | Check the id. A workspace key reaches only its workspace's requests. |
not_found | 404 | No such endpoint. | Check the method and the path against the reference. |
NO_FINAL | 404 | The signed document is ready once everyone has signed. | Wait for request.completed, then download version=final. |
CLOSED | 409 | The request is no longer open, so it cannot be reminded or cancelled. | Read the request to see its status. |
NOBODY | 400 | Nobody is waiting to sign right now, so there is nobody to remind. | Nothing to do. |
Signature request checks
A signature request sent by API is checked exactly like one sent from the website. These codes name the part of spec to fix.
| Code | Status | What it means | What to do |
|---|---|---|---|
TITLE_REQUIRED | 400 | The request has no title. | Give it a title of up to 150 characters. |
NOT_PDF | 400 | The file is not a PDF. | Convert it to PDF first. |
TOO_MANY_PAGES | 400 | The PDF has more pages than a document sent for signing may have. | Split it, or send the pages that need signing. |
TOO_MANY_DOCUMENTS | 400 | More documents than one envelope can hold. | Send fewer documents in one request. |
FILE_TOO_LARGE | 413 | The document is larger than a signature request allows (15 MB). | Send a smaller file. |
ENVELOPE_TOO_LARGE | 413 | The documents in one envelope are over 30 MB together. | Send fewer or smaller documents. |
SIGNER_COUNT | 400 | No recipients, or more than one request can have. | Add at least one recipient, or remove some. |
FREE_SIGNER_LIMIT | 403 | More people on one request than the Free plan allows. | Remove people, or upgrade your plan. |
NO_SIGNER | 400 | Nobody on the request signs. | Add at least one person with the role SIGNER. |
ROLE | 400 | A recipient has a role that does not exist. | Use SIGNER, APPROVER, WITNESS or CC. |
SIGNER_NAME | 400 | A recipient has no name. | Give every recipient a name. |
SIGNER_EMAIL | 400 | A recipient's email address is not valid. | Fix the address. |
SIGNER_DUPLICATE | 400 | The same email address is on the request twice. | Keep each person once. |
ACCESS_CODE | 400 | An access code is not 4 to 12 letters or digits. | Change the code. |
EXPIRY | 400 | expiresInDays is not between 1 and 60. | Pick a number of days from 1 to 60. |
REMINDER | 400 | reminderEveryDays is not between 1 and 14. | Pick 1 to 14 days, or leave it out. |
WITNESS_FOR | 400 | A witness does not say whose signature they witness. | Set witnessFor to that signer's index. |
WITNESS_ORDER | 400 | A witness comes before the person they witness. | Give the witness a later order. |
NO_FIELDS | 400 | The request has no fields to fill in. | Place at least one field. |
TOO_MANY_FIELDS | 400 | A document has more fields than one may have. | Place fewer fields. |
FIELD_SIGNER | 400 | A field belongs to a signer who is not on the list. | Check the signer index of each field. |
FIELD_ROLE | 400 | A field does not suit its recipient's role, for example an APPROVAL box for a signer. | Match each field to the role, as the reference describes. |
FIELD_DOCUMENT | 400 | A field is on a document that is not in the envelope. | Check the document of each field. |
FIELD_PAGE | 400 | A field is on a page the document does not have. | Check the page numbers, counted from 1. |
FIELD_BOUNDS | 400 | A field is outside the page. | Check x, y, width and height, in PDF points from the lower left corner. |
PREFILL_KIND | 400 | prefill is set on a field that cannot be filled in advance. | Prefill only text, number, date, company and job title fields. |
PREFILL_VALUE | 400 | A prefilled value is empty or too long. | Shorten it, or leave prefill out. |
SIGNER_WITHOUT_SIGNATURE | 400 | A signer or witness has no signature field. | Place a SIGNATURE field for every signer and witness. |
FREE_BRANDING_LIMIT | 403 | Your own branding has been used on as many Free requests as the Free plan allows. | Send without branding, or upgrade your plan. |
ACCENT | 400 | The accent colour is not a hex value. | Use a value like #2846d6. |
LOGO_TYPE | 400 | The logo is not a PNG or JPG image. | Send a PNG or JPG. |
LOGO_TOO_LARGE | 413 | The logo is over 200 KB. | Send a smaller image. |
UNAVAILABLE | 503 | Creating requests through the API is unavailable for a moment. | Try again shortly, with the same Idempotency-Key. |
Digital signature
POST /digital-sign answers a signing problem with a code and the stage it happened in. Nothing in these messages repeats your password.
| Code | Status | What it means | What to do |
|---|---|---|---|
WRONG_PASSWORD | 400 | The certificate's password is wrong. | Send the password the .pfx was exported with. |
INVALID_PKCS12 | 400 | The certificate file could not be opened. | Export it again as .pfx or .p12. |
NO_PRIVATE_KEY | 400 | The file holds a certificate but no private key. | Export it with its private key. |
NO_CERTIFICATE | 400 | The file holds no certificate. | Export the certificate itself. |
UNSUPPORTED_KEY_TYPE | 400 | The certificate's key type cannot sign PDFs here. | Use an RSA certificate, or ECDSA on P-256, P-384 or P-521. |
INVALID_CERTIFICATE | 400 | The certificate cannot be used to sign. | Check it with whoever issued it. |
MALFORMED_CERTIFICATE | 400 | The certificate is damaged. | Export it again. |
CERTIFICATE_EXPIRED | 400 | The certificate has expired. | Sign with a current certificate. |
CERTIFICATE_NOT_YET_VALID | 400 | The certificate's start date is in the future. | Wait for that date, or use another certificate. |
CERTIFICATE_NOT_FOR_SIGNING | 400 | The certificate is not allowed to make signatures. | Use a certificate issued for signing documents. |
MISSING_CERTIFICATE_CHAIN | 400 | The certificate's chain is missing from the file. | Export the .pfx with the full chain. |
CERTIFICATE_CHAIN_INVALID | 400 | The certificate's chain does not check out. | Export the .pfx with the right chain. |
ENCRYPTED_PDF | 400 | The PDF is protected with a password. | Remove the password first. |
INVALID_SIGNATURE_IMAGE | 400 | The signature image could not be read. | Send a PNG, JPEG or WebP. |
MISSING_PLACEMENT | 400 | A visible signature without a place to put it. | Send placement, or page and rect. |
INVALID_RECT | 400 | rect is not four numbers on the page. | Send [x1,y1,x2,y2] in points. |
PAGE_OUT_OF_RANGE | 400 | page is past the end of the document. | Use a page the PDF has. |
SIGNATURE_FIELD_NOT_FOUND | 400 | No empty signature field has that fieldName. | Check the field's name, or leave fieldName out. |
LTV_REQUIRES_TIMESTAMP | 400 | ltv needs timestamp. | Turn timestamp on, or ltv off. |
ARCHIVE_TIMESTAMP_REQUIRES_LTV | 400 | archiveTimestamp needs ltv. | Turn ltv on, or archiveTimestamp off. |
INVALID_CERTIFY_LEVEL | 400 | certify is not one of the allowed values. | Use none, no-changes, form-filling or form-filling-and-comments. |
SIGNATURE_FIELD_ALREADY_SIGNED | 409 | That signature field is already signed. | Sign a new field, or leave fieldName out. |
CERTIFICATION_NOT_FIRST | 409 | A certification signature has to be the first signature in the PDF. | Sign without certify. |
DOCUMENT_CERTIFIED_NO_CHANGES | 409 | The PDF is certified so that no changes are allowed, not even a new signature. | Sign the version before it was certified. |
TIMESTAMP_FAILED | 422 | The trusted timestamp could not be added just now. | Try again, or sign with timestamp=false. |
Our side
Nothing is wrong with your call. These are safe to retry with backoff, with the same Idempotency-Key.
| Code | Status | What it means | What to do |
|---|---|---|---|
service_unavailable | 503 | The API is briefly unavailable. | Retry with backoff. |
api_disabled | 503 | The API is switched off for now. | Try again later. The status page says when it is back. |
server_error | 500 | Something failed on our side. | Retry with backoff. If it keeps happening, write to support@kovapdf.com. |
When you make keys and webhooks in your account
Not API calls: these come from the Developer API screen of your account, and from scripts that drive it.
| Code | Status | What it means | What to do |
|---|---|---|---|
email_not_verified | 403 | A test key needs a confirmed email address, because every email it sends goes there. | Confirm your email address first. |
test_key_exists | 409 | You already have a test key. You can hold one at a time. | Revoke the old one if you lost it, then make a new one. |
test_used | 403 | Your free test has ended, so no new test key can be made. | Ask for API access on the request form. |
too_many_keys | 409 | You have as many active keys as you may have. | Revoke a key first. |
invalid_ip | 400 | An entry in the IP allow list is not an address or a range. | Use addresses like 203.0.113.7 or ranges like 203.0.113.0/24. |
invalid_scope | 400 | No scope picked, or a scope your API access does not include. | Pick at least one scope from the list. |
not_allowed | 403 | Only the workspace's Owner or an Admin can make a key that belongs to the workspace. | Ask one of them, or make a personal key. |
too_many_endpoints | 409 | You have as many webhook endpoints as you may have (5). | Remove one first. |
json_required | 415 | A POST that is not JSON. | Send Content-Type: application/json. |
unsupported_encoding | 415 | The JSON body was sent compressed (for example with gzip). | Send the JSON body without compression. |
More help
- How keys, tasks, limits and retries work: the API reference.
- What you agree to when you use a key: the API terms.
- The same codes, endpoint by endpoint: the OpenAPI file.
- A code that is not on this page, or one that does not match what you see: write to support@kovapdf.com with the time of the call and the code.