When a request fails, the Nutrient DWS Data Extraction API returns an error response with an HTTP status code and a human-readable message. The response includes structured details when available.
Error response format
The API uses this response shape for most errors:
interface ParseErrorResponse { /** HTTP status code (4xx or 5xx) */ status: number; /** Unique request identifier for debugging / support */ requestId: string; /** Human-readable error summary */ errorMessage: string; /** Structured error details (present on validation and processing errors) */ errorDetails?: { /** Error origin: "request", "processing", etc. */ source: string; /** Stable machine-readable error code for client branching. */ code?: string; /** List of invalid fields */ failingPaths?: { path: string; details: string }[]; };}The response can include these fields:
requestId— Always present. Include this value when you contact Support. For support details, refer to the support guide.errorMessage— Short summary of the error.errorDetails.source— Error origin, such asrequestfor validation errors,processing, ormaestrofor backend failures.errorDetails.code— Machine-readable error code for client branching, such asinvalid_requestormaestro_error.errorDetails.failingPaths— Invalid fields with JSON paths and descriptions.
HTTP status codes
Use the HTTP status code to decide how your client should handle an error.
| Status | Meaning | Description |
|---|---|---|
| 400 | Bad request | Malformed or empty input, unsupported file format, password-protected PDF, invalid parameters, missing file or URL, or schema error. |
| 401 | Unauthorized | Missing, invalid, or expired API token. |
| 402 | Payment required | Insufficient credits for the requested operation. |
| 408 | Request timeout | Data Extraction API request exceeded the five-minute processing limit. |
| 413 | Payload too large | File exceeds the maximum supported size. |
| 422 | Unprocessable entity | Remote URL couldn’t be downloaded or was rejected by the extract endpoint. |
| 429 | Too many requests | Rate limit exceeded for your subscription. |
| 500 | Internal server error | Backend processing failure. Retry or contact Support. |
| 503 | Service unavailable | Processing backend is temporarily unavailable. Retry later. |
Error examples
The following examples show the response format for common error categories.
Validation or input error (400)
The API returns this error when the request has invalid parameters or the input document can’t be processed as provided. This includes malformed or empty files, unsupported file formats, and password-protected PDFs:
{ "status": 400, "requestId": "req_err_001", "errorMessage": "The request is malformed", "errorDetails": { "source": "request", "code": "invalid_request", "failingPaths": [ { "path": "$.file", "details": "unsupported file format: video/mp4" }, { "path": "$.mode", "details": "invalid mode: 'turbo'. Expected: text, structure, understand, agentic" } ] }}Insufficient credits (402)
The API returns this error when the account doesn’t have enough credits to process the request:
{ "status": 402, "requestId": "req_err_002", "errorMessage": "Insufficient credits. This request requires 2 credits, 0 remaining."}With pay-as-you-go enabled (on the free plan or a paid plan), the API returns this error only after you reach your spending cap. Below the cap, pay-as-you-go adds credits automatically, and requests continue. Without pay-as-you-go, free plan and paid plan quotas return 402 when the account exhausts its included allowance.
Processing error (500)
The API returns this error when the backend encounters an internal service error during extraction. Input-specific failures — such as malformed, empty, unsupported, or password-protected PDFs — return 400 instead:
{ "status": 500, "requestId": "req_err_003", "errorMessage": "Processing failed. Please retry or contact support with the requestId.", "errorDetails": { "source": "maestro", "code": "maestro_error" }}Extract endpoint errors
The extract endpoint uses the same error shape as parse, plus cases specific to schema-driven extraction. For endpoint details, refer to the extract endpoint guide.
Schema validation errors (400)
The API rejects a request when the schema is missing or uses an unsupported structure. The failingPaths entry points to $.schema:
{ "status": 400, "requestId": "req_err_002", "errorMessage": "The request is malformed", "errorDetails": { "source": "request", "failingPaths": [ { "path": "$.schema", "details": "root schema type must be \"object\", got \"array\"" } ] }}Common causes include a missing schema; a root type other than object; or unsupported keywords such as $ref, composition keywords, and validation ranges. For the supported subset and limits, refer to the define a schema guide.
Remote URL rejected (422)
The API returns this error when it can’t download a url input or rejects the URL:
{ "status": 422, "requestId": "req_err_url", "errorMessage": "The request is malformed", "errorDetails": { "source": "request", "failingPaths": [{ "path": "$.url", "details": "URL is not allowed" }] }}Insufficient credits (402)
The extract endpoint returns a different body shape for insufficient credits than the parse endpoint:
{ "error": "insufficient_credits", "message": "Your organization has insufficient credits for this operation.", "credits_available": "0"}Branch on the HTTP status code, 402, rather than the body shape so your error handling works across both endpoints.
As with the parse endpoint, with pay-as-you-go enabled, the API returns the 402 response only after you reach your spending cap. Below the cap, pay-as-you-go adds credits automatically, and requests continue.
Handle errors in code
The following examples show how to read error fields from a response.
import requests
response = requests.post( "https://api.nutrient.io/extraction/parse", headers={"Authorization": "Bearer your_api_key_goes_here"}, files={"file": open("document.pdf", "rb")},)
result = response.json()
if result.get("status") != 200: print(f"Error {result['status']}: {result['errorMessage']}") print(f"Request ID: {result['requestId']}") if "errorDetails" in result: if result["errorDetails"].get("code"): print(f"Error code: {result['errorDetails']['code']}") for path in result["errorDetails"].get("failingPaths", []): print(f" {path['path']}: {path['details']}")else: print(f"Extracted {len(result['output'].get('elements', []))} elements")const response = await fetch("https://api.nutrient.io/extraction/parse", { method: "POST", headers: { Authorization: "Bearer your_api_key_goes_here" }, body: form,});
const result = await response.json();
if (result.status !== 200) { console.error(`Error ${result.status}: ${result.errorMessage}`); console.error(`Request ID: ${result.requestId}`); if (result.errorDetails?.code) { console.error(`Error code: ${result.errorDetails.code}`); } if (result.errorDetails?.failingPaths) { result.errorDetails.failingPaths.forEach((p) => { console.error(` ${p.path}: ${p.details}`); }); }} else { console.log(`Extracted ${result.output.elements?.length ?? 0} elements`);}Troubleshooting
Diagnose common request failures by status code and symptom.
Request returns 401
Verify that the Authorization header uses the format Bearer pdf_live_....
Request returns 400
Check the request parameters and input document. The API reports malformed, empty, unsupported, and password-protected PDFs as 400 responses. Treat them as bad input rather than transient service failures, and fix or replace the input before retrying.
Request returns 413
A direct upload exceeded the 150 MB limit for the whole request on a live key. Reduce the file size or split multipage documents before uploading. For file requirements, refer to the supported file types guide.
Request returns 408
The request exceeded the maximum processing time of five minutes. Split large documents or submit smaller page ranges when processing takes too long.
Request returns 422
The API rejected the url input if it exceeded the 50 MB size limit, or the download failed if it exceeded the 30-second response timeout. A file larger than 50 MB returns file at URL exceeds maximum size on $.url. A download that fails or times out returns a failure on the same path. Upload the file directly for anything larger than 50 MB.
Request returns 429
You exceeded the rate limit. Wait and retry with exponential backoff. Check your plan limits in the Data Extraction API dashboard(opens in a new tab).
Request returns 500 or 503
These are server-side errors, not document validation failures. Retry the request after a short delay. If the error persists, contact Support and include the requestId from the response. For support details, refer to the support guide.