Parseo

Error Registry

Complete list of error codes returned by the Parseo API.

All error responses use application/problem+json and follow this shape:

{
  "type": "https://docs.parseo.app/errors/error-registry",
  "title": "Invoice not found",
  "status": 404,
  "detail": "The specified invoice was not found",
  "instance": "/v1/invoices/inv_01HXYZ...",
  "requestId": "req_01HXYZ...",
  "code": "invoice.not_found"
}

The code field is the stable, machine-readable identifier — always branch on code, not on title or detail.

Authentication

CodeStatusDescriptionRemediation
auth.missing_credentials401No API key was provided.Send Authorization: Bearer <key> on every request.
auth.invalid_key401The API key does not exist or is malformed.Verify the key value and that it has not been deleted.
auth.key_revoked401The API key was explicitly revoked.Rotate to a new key from the dashboard.
auth.key_expired401The API key has passed its expiration date.Issue a new key or extend the expiration in the dashboard.
auth.too_many_failed_attempts429Too many failed authentication attempts from this source.Honor the Retry-After header and stop retrying with the invalid credential.

Authorization

CodeStatusDescriptionRemediation
auth.insufficient_scope403The API key lacks the scope required for this endpoint.Grant the missing scope in the dashboard or use a key that already has it.
auth.team_suspended403The account (team) this API key belongs to is suspended; all of the team's keys are rejected while the suspension is active.Contact support — access is restored automatically when the account is reactivated.
billing.suspended403Paid processing is suspended for this team after an unresolved billing problem (chargeback or failed payment). Distinct from auth.team_suspended: reads keep working, only work that costs credits is refused.Contact support and quote the case reference in the message — buying credits does not lift a suspension.
billing.team_paused403Document processing for this team is paused by the partner that manages it. Only processing is paused: reads and exports keep working.Contact the partner to resume processing. Buying credits does not lift a pause.
auth.ip_not_allowed403The request originated from an IP not in the key's allowlist.Add the caller's IP to the key's allowlist or call from an allowed network.
plan.api_access_disabled403Your team's plan does not include API access.Upgrade the team plan to one that includes public API access.
client.not_found404The X-Client-Id header references a client that does not exist.Verify the client ID and that it has not been deleted.
client.not_in_team403The referenced client does not belong to your team.Use a client ID owned by the authenticated team.
client.scope_mismatch403This key is scoped to a specific client and X-Client-Id must match it.Send the scoped client's ID, or use a team-scoped key.

Rate Limiting

CodeStatusDescriptionRemediation
rate_limit.exceeded429The per-key rate limit was exceeded.Back off until the Retry-After seconds elapse, then retry.

Ingestion

CodeStatusDescriptionRemediation
ingestion.queue_full503The ingestion queue is at capacity.Retry after a short delay with jittered backoff.

Credits

CodeStatusDescriptionRemediation
credits.insufficient402The team does not have enough processing credits for this request.Purchase credits, then retry. Do not retry without buying — the balance will not change on its own.

credits.insufficient returns 402, not 403. Clients that treat every 403 as "out of credits" must branch on code instead: 403 now means an authorization failure, and a failure of the credit check itself surfaces as a 5xx.

Invoices

CodeStatusDescriptionRemediation
invoice.not_found404No invoice matches the supplied ID for this team.Verify the invoice ID and that the authenticated team owns it.
job.not_found404No processing job matches the supplied ID for this team.Verify the job_... ID returned by POST /invoices. Jobs are retained for 30 days after terminal state.
contact.not_found404No contact matches the supplied ID for this team.Verify the contact ID and that the authenticated team owns it.
auth.key_suspended403Ops has administratively suspended this API key.Contact support — partners cannot self-restore a suspended key.
invoice.reprocess_unavailable409The original source file is no longer retained for this invoice, so it cannot be reprocessed.Re-upload the source file to create a new invoice.
invoice.not_ready_for_export409The invoice is still queued or processing.Poll the invoice until status is completed, then retry the export.
invoice.export_unavailable_failed409Processing failed, so the invoice cannot be exported.Re-upload the source file or fix the parsing issue before exporting.
invoice.export_unavailable_preprocessing409Export preprocessing skipped the invoice — a required goods mapping is missing, a currency rate could not be resolved, or a cumulative line carries no code. The detail names the reason.Fix the invoice data named in detail (map the goods code, set the missing line code) and retry the export.
invoice.export_unavailable_temporary503The goods mappings for the invoice could not be loaded, so the export was stopped instead of being produced without them. Nothing was exported.Retry the export after a short delay with jittered backoff; contact support with the requestId if it persists.
invoice.not_editable409Invoice is still being processed and cannot be edited yet.Poll GET /invoices/{id}/status until the invoice reaches a terminal state (processed or failed), then retry the update.
invoice.split_lines_immutable409The invoice has lines split into parts in the dashboard, or the request submits a non-null lineItems[].split. Split lines cannot be edited through the API.Unsplit the line in the dashboard, then retry; omit lineItems (or send split: null) on invoices without split parts.

Assignment Review

Returned by POST /invoices/{id}/assignment/{approve,move,discard} when resolving an invoice blocked by the client-assignment gate (assignment.status = "needs_review").

CodeStatusDescriptionRemediation
invoice.assignment_not_reviewable409The invoice is not awaiting assignment review (it was confirmed, exempt, or never assessed).Only invoices with assignment.status = "needs_review" accept review actions.
invoice.assignment_conflict409A different review action was already applied to this invoice. The problem body carries the previously applied state.Treat the returned state as the authoritative resolution; repeating the same action returns 200.
invoice.assignment_move_needs_review409Reassessment against the destination client still requires review. The problem body carries the destination assessment (status, reasonCodes).Inspect the assessment; repeat the move with "force": true to move anyway, or pick a different destination.
invoice.assignment_destination_same_client400The move destination equals the invoice's current client.Approve instead of moving, or choose a different destination client.
invoice.assignment_direction_contradicts_identifiers400The requested direction contradicts the document: the client's registry code or VAT number was matched on the other party, which fixes the direction.Omit direction to let the assessment decide, or send the other value.

Exports

CodeStatusDescriptionRemediation
export.invalid_format400The requested export format is not supported.Use one of: rivile, finvalda, centas, agnum, json, xml.

Uploads

CodeStatusDescriptionRemediation
upload.no_file400The multipart body did not include a file part.Send the document as a multipart/form-data field named file.
upload.invalid_mime_type400The uploaded file's MIME type is not supported.Upload a application/pdf, image/jpeg, image/png, or image/webp file.
upload.file_too_large413The uploaded file exceeds the per-file size limit: 50 MB, or lower when your team has a smaller limit. limitMb carries the limit that applied.Compress or split the document and retry.
upload.too_many_pages422The PDF has more pages than your team's per-document page limit. pageCount and limitPages carry both numbers.Split the document into smaller PDFs and retry.
upload.filename_too_long400The filename is longer than 255 bytes.Rename the file to 255 bytes or fewer and retry.
upload.payload_too_large413The total request body exceeds the configured maximum (50 MB single / 500 MB batch).Reduce the payload size or split a batch into smaller requests.
upload.concurrent_limit_exceeded429Too many concurrent uploads from this team.Reduce parallelism or honor the Retry-After header.
invoice.upload_failed500The upload was accepted but a downstream step (storage, queue) failed before the job could be enqueued.Retry with the same Idempotency-Key.

Idempotency

CodeStatusDescriptionRemediation
idempotency.request_in_progress409A prior request using this Idempotency-Key is still being processed.Wait briefly and retry with the same key; the cached response will be returned once the original completes.
idempotency.key_reused_with_different_params409The Idempotency-Key was previously used with a different request body.Generate a new idempotency key for the new request, or resend the original body verbatim.
idempotency.backend_unavailable503The idempotency cache is temporarily unreachable; the request was rejected fail-closed to avoid double-execution.Honour the Retry-After header and retry with the same key — the original request was not executed.

Validation

CodeStatusDescriptionRemediation
validation.invalid_body400One or more request body fields failed validation. Per-field details are returned in the errors[] array.Inspect errors[].field and errors[].code to see which fields failed and correct them.
validation.failed400/422Generic validation failure when no per-field detail is available.Inspect detail for the human-readable explanation and correct the request.
validation.invalid_idempotency_key400The Idempotency-Key header is empty, exceeds 255 bytes, or contains control characters.Use a non-empty UTF-8 string of 1–255 printable characters (a UUID is fine).
validation.client_mode_mismatch400The referenced client's mode (live/test) does not match the authenticating key's mode.Use a client that matches the key's mode, or authenticate with a key whose mode matches the client. Live and test resources cannot cross-reference.

Field-level validation codes

These appear inside the errors[].code array on validation.invalid_body responses (one entry per failing field).

CodeDescription
validation.invalid_valueGeneric value-shape failure (default fallback).
validation.invalid_formatValue did not match a required format (UUID, email, URL, ISO 8601, etc.).
validation.requiredA required field was missing or empty.
validation.lengthString/array length was outside the allowed bounds.
validation.invalid_enumValue was not one of the allowed enum members.
validation.invalid_typeValue was the wrong type (e.g. string where number expected).
validation.invalid_public_idA public ID had the wrong prefix or was structurally invalid.
validation.client_requiredA live upload was submitted without a client association. Set the X-Client-Id header or use a client-scoped API key.
validation.client_required_in_test_modeA test-mode upload was submitted without a client association. Set the X-Client-Id header or use a client-scoped API key.
webhook.secret_rotation_grace_activeA second webhook-secret rotation was attempted while the previous one is still inside its 24h grace window. Wait until the grace period ends.

Pagination

CodeStatusDescriptionRemediation
pagination.filter_mismatch400The cursor was issued for a different filter set than the current request.Start a new pagination from page 1 without the cursor; keep filters consistent thereafter.
pagination.cursor_invalid400The cursor is malformed or produced by an incompatible API version.Start a new pagination without the cursor.

Webhooks

CodeStatusDescriptionRemediation
webhook.not_found404No webhook endpoint matches the supplied ID for this team.Verify the endpoint ID and that it has not been deleted.
webhook.endpoint_limit_exceeded422The team has reached the maximum of 20 webhook endpoints.Delete an unused endpoint before creating a new one.
webhook.url_not_https400The webhook URL must use the https:// scheme.Use an HTTPS URL.
webhook.url_invalid_hostname400The hostname is not a valid public DNS name.Use a publicly resolvable hostname (no localhost, IPs, or .internal domains).
webhook.url_resolves_to_private_ip400The hostname resolves to a private or reserved IP range.Host the endpoint on a publicly routable address.
webhook.url_port_not_allowed400The URL specifies a disallowed port. Only port 443 is permitted.Remove the explicit port or use :443.
webhook.url_too_long400The URL exceeds 2048 characters.Shorten the URL.
webhook.test_rate_limit_exceeded429The per-endpoint test-delivery rate limit (10/hour) was exceeded.Wait for the hour window to roll over before sending more test deliveries.
webhook.delivery_not_found404No delivery attempt matches the supplied ID for this endpoint.Verify the delivery ID returned by GET /webhooks/{id}/deliveries.
webhook.delivery_payload_unavailable409The original payload is no longer retained for this delivery (past the 30-day retention window).Retrigger the event upstream instead of retrying this specific delivery.

Service

CodeStatusDescriptionRemediation
service.maintenance503The public API is temporarily unavailable for maintenance.Honor the Retry-After header and retry after the indicated interval.
internal.server_error500An unexpected server error occurred.Retry the request; if it persists, include the requestId when contacting support.

Generic HTTP fallbacks

These codes are emitted when an underlying exception didn't carry its own machine-readable identifier (rare — most public-API errors map to a specific code above). Branch on these only as a last-resort default.

CodeStatusDescription
http.unauthorized401Generic 401 fallback.
http.forbidden403Generic 403 fallback.
http.not_found404Generic 404 fallback (e.g. an unknown route).
http.conflict409Generic 409 fallback.

On this page