Skip to main content

Error Handling

Every error the API returns, and what to do about it.

Error Response Format​

All errors share the same shape:

{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits to generate PDF. Please purchase credits to continue.",
"details": {
"current_balance": 0.005,
"required_amount": 0.01,
"subscription_credits_remaining": 0,
"action_required": "purchase_credits"
}
}
}

Match on error.code, not on message. details varies by code and often carries the values you need to fix the request.

HTTP Status Codes​

StatusMeaning
400The request is malformed or a value is invalid
401Missing or invalid credentials
402The account has no paid plan
403Authenticated, but not allowed: allowance or credits, plan features, ownership, rate limits
404The job, upload or output does not exist
408A quick job exceeded the 30-second limit
409The request conflicts with the current state
410The output existed but has been deleted
413The inline payload is too large
422The request was valid but a remote URL could not be used
429Platform throttling — retry with backoff
500Something failed on our side

Request Errors (400)​

CodeMeaningFix
MISSING_INPUT_TYPENo input_typeSend html, markdown, image or url
INVALID_INPUT_TYPEUnknown input_typeUse a supported value
MISSING_CONTENT_FIELDThe field matching input_type is absentSend html, markdown or url
EMPTY_CONTENT_FIELDThe content field is emptySend real content
CONFLICTING_FIELDSBoth html and markdown sentSend only the one matching input_type
WRONG_FIELD_PROVIDEDA field does not match input_typeRemove it
CONTENT_TYPE_MISMATCHContent looks like a different typeCorrect input_type
INPUT_SIZE_EXCEEDEDContent over 5 MBSplit the document
PAGE_LIMIT_EXCEEDEDThe PDF exceeds the page limitUse /longjob, or split the document
INVALID_PARAMETERA parameter is invalidSee details.parameter
INVALID_OPTIONS_JSONoptions is not valid JSONFix the JSON
INVALID_MULTIPARTMalformed multipart requestCheck the form encoding
MISSING_IMAGESNo image files in the requestAttach at least one image
INVALID_IMAGE_FORMATNot a PNG or JPEGConvert the image
INVALID_IMAGE_DATAThe image is corruptRe-export it
IMAGE_TOO_LARGEOver 5 MB or 10,000 × 10,000 pixelsResize
MISSING_URLinput_type: url without urlSend the URL
INVALID_URLNot HTTPS, malformed, or a private addressUse a public https:// URL
INVALID_WEBHOOK_URLWebhook URL is not HTTPSUse HTTPS

Bulk-specific request errors are listed in POST /bulkjob.

Authentication and Account (401, 402, 403)​

StatusCodeMeaningFix
401UNAUTHORIZEDMissing or invalid API key or tokenCheck the X-API-Key header, or refresh your token
402UPGRADE_REQUIREDThe account has no paid planBuy a credit pack or start a subscription to activate the account
403ACCOUNT_NOT_FOUNDNo account record for this userCreate an account first
403INSUFFICIENT_CREDITSSubscription allowance, free credits and one-off credits together cannot cover the workBuy credits or upgrade your plan; details shows current_balance (one-off credits), subscription_credits_remaining and required_amount
403CONVERSION_TYPE_NOT_ENABLEDYour plan does not allow that input typedetails.enabled_types lists what is allowed
403RATE_LIMIT_EXCEEDEDYour plan's per-minute limitWait details.retry_after seconds
403ACCESS_DENIEDThe resource belongs to someone elseCheck the ID

Rate limiting only applies to plans that define a per-minute limit. Platform-level throttling is separate and returns 429.

Jobs and Output (404, 409, 410)​

StatusCodeMeaningFix
404JOB_NOT_FOUNDUnknown job, or it belongs to another accountCheck the ID
404OUTPUT_NOT_AVAILABLEThe job has no stored outputQuick jobs need store: true
409JOB_NOT_READYThe job has not finishedPoll until completed or partial_failed
410OUTPUT_EXPIREDDeleted after 30 daysConvert again

Timeouts and Remote URLs (408, 422)​

StatusCodeMeaningFix
408QUICKJOB_TIMEOUTRendering passed 30 secondsUse /longjob
422URL_FETCH_TIMEOUTThe remote server took over 10 secondsCheck the URL
422URL_FETCH_HTTP_ERRORThe remote server returned an errordetails.status_code shows what it returned
422URL_CONTENT_TYPE_NOT_SUPPORTEDThe URL returned something other than HTML, Markdown, PNG or JPEGUse a supported page
422URL_FETCH_FAILEDThe URL could not be fetchedCheck that it is publicly reachable

Server Errors (500)​

CodeMeaningFix
PDF_GENERATION_FAILEDRendering failedRetry; if it persists, check the document for very large assets
INTERNAL_SERVER_ERRORUnexpected failureRetry with backoff

Handling Errors in Code​

const response = await fetch('https://api.podpdf.com/quickjob', {
method: 'POST',
headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
body: JSON.stringify({ input_type: 'html', html }),
});

if (!response.ok) {
const { error } = await response.json();

switch (error.code) {
case 'INSUFFICIENT_CREDITS':
case 'UPGRADE_REQUIRED':
throw new Error('Buy credits or upgrade your plan before converting');
case 'PAGE_LIMIT_EXCEEDED':
return convertWithLongJob(html); // 25-page limit on /quickjob
case 'QUICKJOB_TIMEOUT':
return convertWithLongJob(html);
case 'RATE_LIMIT_EXCEEDED':
await sleep((error.details.retry_after ?? 60) * 1000);
return retry();
default:
throw new Error(`${error.code}: ${error.message}`);
}
}

Retry advice​

  • Retry with backoff: 429 and 500.
  • Do not retry unchanged: every 4xx except 429 — fix the request, the plan or the balance first.
  • Switch endpoint: PAGE_LIMIT_EXCEEDED or QUICKJOB_TIMEOUT on /quickjob usually means the document belongs on /longjob.

Bulk Jobs​

A bulk job can finish with status: "partial_failed" — some files converted, others did not. That is not an HTTP error: check GET /jobs/{job_id}/files for per-file codes, and remember only successful PDFs are billed. See the bulk conversion guide.

Merge and Split​

Errors from /pdf/merge, /pdf/split and /pdf/jobs name the file that caused them in details.filename and details.input_index.

  • Never retry unchanged: PDF_ENCRYPTED, INVALID_PDF, PDF_NO_PAGES — the file itself has to change.
  • Retry later: PDF_JOB_ALREADY_ACTIVE (409), once one of your running jobs finishes.
  • Switch path: PDF_INPUT_TOO_LARGE, PDFOP_TIMEOUT or a 413 on /pdf/merge or /pdf/split means the files belong in an upload and a job.
  • Warnings are not errors: FORM_FIELDS_NOT_PRESERVED, BOOKMARKS_NOT_PRESERVED and SIGNATURE_INVALIDATED come back with a successful result.

Next Steps​

  • Limits — the numbers behind most 400s
  • Jobs API — statuses and downloads