Problem types
Errors are returned as RFC 9457 application/problem+json documents, never inside a 2xx body. The type member is a URI under https://api.spendone.tech/problems/ that identifies the problem; branch on it, never on the title or detail wording, which changes freely.
This page is generated from the API source at every documentation deploy: every type below is one the server can emit, and a type added to the source appears here with the next deploy. The full URI of a type is the base above plus its slug, and it dereferences: fetch it and the API returns that type's own documentation, as JSON for a client and as a page for a browser.
Extension fields
Beyond the standard RFC 9457 members, a problem document carries these extensions.
| Field | Carried by | Meaning |
|---|---|---|
request_id | every problem | The correlation id to quote to support. |
operation | every problem raised through the service error handler | The name of the failing operation. |
errors | the validation-error type | Array of {field, message} entries, one per failed field or row. |
field, field_message | single-field 400s | The offending field and the reason it was rejected. |
firewall_type, firewall_trigger | the firewall-blocked and firewall-rate-limited types | What the firewall blocked and which rule triggered it. |
Platform
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
bad-request | 400 | Bad Request | The request body or parameters are malformed and could not be processed. | |
conflict | 409 | Conflict | The request conflicts with the current state of the resource. | |
empty-tenant-id | 401 | Empty Tenant ID | The request carries an empty tenant identifier. | |
entity-locked | 409 | Entity Locked | This record is being modified by another operation. Try again. | |
forbidden | 403 | Forbidden | Changing roles, permissions, active state, or identity fields requires the user-management permission. | |
internal-error | 500 | Internal Server Error | An internal error occurred | |
invalid-tenant-id | 401 | Invalid Tenant ID | The request carries a tenant identifier that is not valid. | |
lock-conflict | 409 | Lock Conflict | This operation conflicted with another and was rolled back. Try again. | |
missing-tenant-id | 401 | Missing Tenant ID | The request is missing the tenant identifier. | |
not-found | 404 | Not Found | The addressed resource does not exist (or is masked as absent for this caller). | |
read-only-transaction | 500 | Internal Server Error | An internal error occurred | |
request-timeout | 503 | Request Timeout | This request took too long to complete. Try again. | |
statement-timeout | 503 | Statement Timeout | This request took too long to complete. Try again. | |
unauthorized | 401 | Unauthorized | The request lacks valid authentication credentials. | |
unprocessable-entity | 422 | Unprocessable Entity | The request is well-formed but semantically invalid for the target resource. | |
validation-error | 400 | Validation Error | errors | A request field failed validation; the errors extension lists each field and reason. |
forbiddenis raised by more than one module: platform, users.
Firewall
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
firewall-blocked | 403 | Request blocked by firewall | firewall_trigger, firewall_type | Firewall blocked this request. |
firewall-rate-limited | 429 | Request blocked by firewall | firewall_trigger, firewall_type | Firewall blocked this request. |
Invoices
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
accountant-verification-step-invalid | 400 | Accountant Verification Step Invalid | The verification step must be formal_check or order_match. | |
accountant-verification-too-early | 409 | Accountant Verification Too Early | The invoice has not reached accounting yet. | |
allocation-coverage-mismatch | 422 | Allocation does not reconcile to the invoice total | The per-purchase-order amounts must reconcile to the invoice total per bucket (charges, discounts, net, VAT). | |
allocation-duplicate-po | 422 | Purchase order allocated twice | Each purchase order may appear in at most one allocation. | |
allocation-empty | 422 | No allocations | At least one allocation is required. | |
allocation-legal-entity-mismatch | 422 | Purchase orders from different legal entities | Every purchase order this invoice settles must belong to the same legal entity. | |
allocation-line-not-found | 422 | Unknown invoice line | The submission references a line that is not part of this invoice; reload the editor. | |
allocation-lines-unassigned | 422 | Not every invoice line is assigned | Assign every invoice line to exactly one of the selected purchase orders before submitting. | |
allocation-no-lines | 422 | Allocation without lines | Each purchase order allocation needs at least one invoice line. | |
allocation-po-not-found | 422 | Purchase order not found | The submission references a purchase order that does not exist or was deleted. | |
allocation-supplier-mismatch | 422 | Purchase order from a different supplier | Every purchase order this invoice settles must belong to the same supplier as the invoice. | |
allocation-supplier-missing | 422 | Invoice has no supplier | Set the invoice's supplier before allocating it across purchase orders. | |
allocation-totals-pending | 422 | Invoice totals not extracted yet | The invoice has no document totals yet; allocation requires extracted totals. | |
booking-proposal-not-found | 404 | Booking-Proposal Not Found | Booking-Proposal was not found | |
booking-tax-code-unmapped | 400 | Booking Tax Code Unmapped | A booking line's VAT rate and category have no tax code configured for the target FI system. | |
booking-total-exceeds-invoice-total | 400 | Booking Total Exceeds Invoice Total | The booking lines total more than the invoice total. | |
document-adjustment-index-out-of-range | 400 | Document Adjustment Index Out Of Range | The invoice has no document-level charge or allowance at the requested index. Refresh the invoice and try again. | |
invalid-workflow-transition | 400 | Invalid Workflow Transition | The requested action cannot be executed from the invoice's current workflow status. | |
invoice-access-forbidden | 403 | Forbidden | ||
invoice-already-sent-to-accounting | 409 | Invoice Already Sent To Accounting | The invoice was already sent to accounting and can no longer be amended. | |
invoice-buyer-not-found | 404 | Invoice-Buyer Not Found | Invoice-Buyer was not found | |
invoice-correction-invalid-amount | 400 | Invalid Amount Format | invalid amount format | |
invoice-correction-invalid-date | 400 | Invalid Date Format | invalid date format | |
invoice-currency-invalid | 400 | Invalid Invoice Currency | The currency must be a three-letter ISO 4217 code, such as EUR or USD. | |
invoice-currency-missing | 409 | Invoice Currency Missing | The invoice has no currency. Set the invoice currency before transferring the invoice to the FI tool. | |
invoice-duplicate-file | 409 | Duplicate Invoice File | existing_invoice_code, existing_invoice_number, existing_purchase_order_code, existing_workflow_status | An invoice with an identical file already exists. |
invoice-duplicate-park-not-allowed | 409 | Invoice Cannot Be Parked As A Duplicate | This invoice has already progressed into accounting, so it cannot be marked as a duplicate. An accountant can reject it back to the buyer, who can then park or delete it. | |
invoice-gross-missing | 409 | Invoice Amount Missing | The invoice has no total amount. Enter the invoice amount before continuing. | |
invoice-hand-over-invalid-state | 409 | Invoice cannot be handed over | This invoice changed status since it was loaded and can no longer be handed over to accounting. Please refresh and try again. | |
invoice-has-collective-allocation | 409 | Invoice settles several purchase orders | This invoice is allocated across several purchase orders; edit the allocation there instead of reassigning a single one. | |
invoice-key-changed-during-handover | 409 | Invoice Changed During Hand-Over | The invoice's stated total or issue date changed while the hand-over was starting. Retry it. | |
invoice-line-index-out-of-range | 400 | Invoice Line Index Out Of Range | The invoice has no line at the requested index. Refresh the invoice and try again. | |
invoice-line-part-of-allocation | 409 | Invoice Line Part Of Allocation | This line belongs to a collective invoice's allocation and cannot be deleted directly. Adjust the allocation instead. | |
invoice-parked-as-duplicate | 409 | Invoice Parked As Duplicate | This invoice is parked as a duplicate and can no longer be advanced. Work on the invoice it duplicates instead. | |
invoice-po-not-reassignable | 409 | Conflict | ||
invoice-recipient-mismatch-unacknowledged | 422 | Invoice Recipient Does Not Match The Legal Entity | mismatched_fields | This invoice is addressed to a different legal entity than the purchase; correct it or supply an override to advance it. |
invoice-seller-not-found | 404 | Invoice-Seller Not Found | Invoice-Seller was not found | |
invoice-tax-validation-incomplete | 422 | Tax Validation Incomplete | missing_fields | This invoice is missing mandatory §14 UStG fields; supply an override to advance it. |
invoice-unsupported-file | 400 | Unsupported Invoice File | The uploaded file must be a PDF, an image (PNG, JPEG, TIFF, WebP) or an e-invoice XML. | |
invoice-upload-unauthorized | 401 | Unauthorized | A resolvable user identity is required to upload invoices. | |
invoice-vat-breakdown-not-single-rate | 422 | Invoice VAT Breakdown Is Not Single Rate | This invoice states more than one VAT rate, so it has no single document rate to correct. Correct the rate on the line items instead. | |
matching-result-not-found | 404 | Matching-Result Not Found | Matching-Result was not found | |
purchase-order-canceled | 409 | Purchase order is canceled | This purchase order has been canceled and can no longer be linked to an invoice. Pick another order, or reopen this one first if the document credits an invoice already booked against it. | |
purchase-order-completed | 409 | Purchase order is completed | This purchase order is completed and can no longer take a new invoice. Pick another order, or reopen this one first if the document credits an invoice already booked against it. | |
purchase-order-not-accepting-invoices | 409 | Purchase Order Not Accepting Invoices | allowed_states | The purchase order is not in a status that accepts an invoice upload. |
reconciliation-comment-required | 422 | Reconciliation Comment Required | missing_comment_fields | A low match needs the buyer's explanation before the invoice moves on. |
reject-intent-invalid | 422 | Reject Intent Invalid | The rejection intent must be replace or correct when given. | |
reject-not-allowed-from-status | 409 | Reject Not Allowed From Current Status | The invoice cannot be rejected back to the buyer from its current workflow status. | |
reject-reason-required | 422 | Reject Reason Required | A non-empty reason is required to reject an invoice back to the buyer. | |
resume-requires-purchase-order | 409 | Resume Requires A Purchase Order | This rejected invoice has no purchase order, so it cannot be resumed. An accountant assigns one first. | |
workflow-step-mismatch | 409 | Workflow Step Mismatch | current_status, expected_status | This step can only be confirmed while the invoice is in that step; it has already moved on. |
Purchase orders
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
invalid-delivery-line | 400 | Invalid Delivery Line | Each delivery line's line_item_id must belong to the purchase order's purchase request, and its quantity must not exceed that line's ordered quantity. | |
invalid-inquiry-sub-type | 400 | Invalid Inquiry Sub-Type | The inquiry sub_type must be one of invoice_missing, invoice_verification, po_matching, or delivery. | |
purchase-order-access-forbidden | 403 | Purchase order access forbidden | You are not authorized to perform this action on the purchase order. | |
purchase-order-card-cancel-forbidden | 403 | Purchase order cancellation reserved to accounting | Only accounting can cancel this purchase order, or resolve its dispute as not delivered, because an active credit card exists for it. Please ask accounting to take over the dispute. | |
purchase-order-card-confirmation-required | 422 | Card confirmation required | Please confirm that the credit card for this order was not used before canceling it. | |
purchase-order-credit-card-required | 409 | Credit card required | Generate the credit card for this purchase order before placing the order. | |
purchase-order-invalid-transition | 409 | Invalid purchase order transition | This action is not allowed in the purchase order's current status. Please refresh and try again. | |
purchase-order-invoice-not-cancellable | 409 | Purchase order cannot be canceled | This purchase order can't be canceled because one of its invoices is already being exported to your accounting system. | |
purchase-order-stale-status | 409 | Purchase order status changed | This purchase order changed status since it was loaded. Please refresh and try again. |
Purchase requests
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
approval-no-approvers-assignable | 409 | No approver could be assigned | The approval rules matched but named no approver that could be resolved. | |
approval-plan-already-live | 409 | Approval already in progress | This purchase request already has an approval in progress, so it was left unchanged. Refresh it and try again. | |
blocked-supplier | 422 | Supplier not permitted by company policy | block_reason_key, block_reason_url, supplier_code, supplier_name | |
blocked-supplier-help-not-allowed | 422 | Procurement help not available | Procurement help can only be requested for a blocked supplier. | |
cost-center-split-invalid | 400 | Invalid Cost Center Split | Cost center splits must use unique cost centers and percentages summing to 100.00. | |
cost_center-not-found | 404 | Cost_center Not Found | Cost_center was not found | |
document-not-readable | 400 | Document not readable | No text could be read out of the document. | |
pay-on-invoice-not-permitted | 403 | Paying on invoice not permitted | You are not allowed to pay on invoice. | |
procurement-contacts-unavailable | 409 | Procurement contacts unavailable | No procurement contact is currently configured. | |
purchase-flow-not-eligible | 403 | Purchase flow not available | You are not eligible for this purchase flow. | |
purchase-list-view-unsupported-sort | 400 | Unsupported sort parameter | sort_by or order is not one of the supported values. | |
purchase-on-behalf-not-permitted | 403 | Purchasing on behalf not permitted | You are not allowed to purchase on behalf of other users. | |
purchase-request-access-forbidden | 403 | Purchase request access forbidden | You are not authorized to modify this purchase request. | |
purchase-request-malformed-code | 400 | Malformed Purchase-Request Code | The code is not in a valid format | |
purchase-request-not-in-draft | 409 | Purchase request not editable | The purchase request can only be updated while in DRAFT status. | |
purchase_request-not-found | 404 | Purchase_request Not Found | Purchase_request was not found | |
quote-document-too-large | 413 | Payload Too Large | The document exceeds the size limit for a quote read. | |
self-approval-no-approver | 409 | No other approver available | This tenant does not allow buyers to approve their own requests, and nobody else could approve this one. An administrator has to add an approval rule for this case or make sure the tenant has an active administrator. | |
supplier-not-found | 404 | Supplier Not Found | Supplier was not found | |
unsupported-document-type | 400 | Unsupported document type | The document has to be a PDF, an accepted image format, or e-invoice XML. |
cost_center-not-foundis raised by more than one module: purchase_requests, subscriptions.purchase_request-not-foundis raised by more than one module: purchase_requests, subscriptions.supplier-not-foundis raised by more than one module: purchase_requests, suppliers.
Approvals
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
approval-malformed-code | 400 | Malformed Approval Code | The code is not in a valid format | |
approval-task-conflict | 409 | Approval Task Conflict | The approval task has already been completed | |
approval-task-tag-required | 409 | Approval Task Has No Tag | Only a task assigned to a tag (expert group) can be assigned to a user | |
cannot-assign-own-approval | 409 | Cannot Assign Own Approval | This approval cannot be assigned to the requester or buyer of the purchase; a second person must approve it (four-eyes principle). | |
purchase-request-stale-status | 409 | Purchase request status changed | This purchase request changed status since it was loaded. Please refresh and try again. | |
self-approval-not-permitted | 403 | Self Approval Not Permitted | You cannot approve your own purchase request | |
task-not-found | 404 | Task Not Found | Task was not found |
purchase-request-stale-statusis raised by more than one module: approvals, purchase_requests, subscriptions.
Accounting and exports
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
accounting-malformed-code | 400 | Malformed Accounting Code | The code is not in a valid format | |
datev-config-incomplete | 422 | DATEV Configuration Incomplete | code, missing | The DATEV configuration for this tenant is incomplete for the selected export mode. |
datev-not-found | 404 | Datev Not Found | Datev was not found | |
equivalent-invoice-already-transferred | 409 | Equivalent Invoice Already Transferred | existing_invoice_code, existing_purchase_order_code | An invoice with the same document number has already been transferred to the FI tool. |
export-config-not-found | 404 | Export-Config Not Found | Export-Config was not found | |
export-formatter-invalid | 400 | Invalid Formatter Configuration | The field formatter configuration is invalid | |
export-job-not-found | 404 | Export-Job Not Found | Export-Job was not found | |
export-job-required | 400 | Export Job Required | job_code is required | |
export-lookup-invalid | 400 | Invalid Lookup Configuration | The lookup table or rule configuration is invalid | |
export-lookup-rule-not-found | 404 | Export-Lookup-Rule Not Found | Export-Lookup-Rule was not found | |
export-lookup-rule-priority-exists | 409 | Export-Lookup-Rule Priority Already Exists | A export-lookup-rule with this priority already exists | |
export-lookup-table-not-found | 404 | Export-Lookup-Table Not Found | Export-Lookup-Table was not found | |
export-profile-field-not-found | 404 | Export-Profile-Field Not Found | Export-Profile-Field was not found | |
export-profile-not-found | 404 | Export-Profile Not Found | Export-Profile was not found | |
export-profile-type-invalid | 400 | Invalid Profile Type | The profile_type is not one of the CSV profile types this endpoint supports | |
export-profiles-not-configured | 409 | FI Export Not Configured | FI export is not configured. Ask an admin to set up at least one active export profile before sending. | |
export-target-not-found | 404 | Export-Target Not Found | Export-Target was not found | |
export-target-not-s3 | 422 | Target Is Not An S3 Target | The export target does not have S3 configured | |
export-target-not-sftp | 422 | Target Is Not An SFTP Target | The export target does not have SFTP configured | |
export-tasks-not-stampable | 409 | Selected Tasks Already Exporting | One or more selected tasks belong to an export that is still running, or no longer exist. Reload the queue and select again. | |
invoice-not-found | 404 | Invoice Not Found | Invoice was not found | |
journal-entry-malformed-code | 400 | Malformed Journal-Entry Code | The code is not in a valid format | |
no-invoices-to-export | 409 | No Invoices To Export | None of the selected invoices is eligible for export. | |
no-purchase-order-invoices-found | 409 | No Purchase Order Invoices Found | The selected purchase orders carry no invoice ready for export. | |
purchase-order-invoices-parked | 409 | Purchase Order Invoices Parked As Duplicates | Every invoice on the selected purchase orders is parked as a duplicate, so there is nothing to forward. Work on the invoices they duplicate instead. | |
s3-connection-failed | 503 | S3 Connection Failed | error_code | The S3 connection test failed. |
sap-export-not-found | 404 | SAP Export Not Found | The requested SAP export job was not found | |
sftp-connection-failed | 503 | SFTP Connection Failed | error_code | The SFTP connection test failed. Check the host, port, credentials and remote path. |
equivalent-invoice-already-transferredis raised by more than one module: accounting, invoices.export-job-not-foundis raised by more than one module: accounting, transaction_events.invoice-not-foundis raised by more than one module: accounting, invoices.
Credit cards
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
active-card-changed | 409 | Active card changed | The active credit card for this purchase order changed; resolve the current card and retry. | |
card-billing-account-not-configured | 409 | Card billing account not configured | The legal entity has no card provider account for this kind of purchase. An administrator must set it on the legal entity before a card can be issued. | |
card-data-proxy-failed | 502 | Card data proxy failed | The Payrails proxy did not forward the request, so Mastercard never received it. | |
card-provider-not-configured | 503 | Card provider not configured | This environment has no Mastercard credentials configured, so the request cannot be served. | |
card-provider-request-invalid | 400 | Card provider rejected the request | Mastercard rejected the request as invalid. Correct the named field and retry. | |
card-provider-resource-not-found | 404 | Card provider resource not found | The referenced entity or card does not exist at Mastercard. | |
card-provider-rule-violation | 409 | Card provider refused the request | Mastercard understood the request but refused it in the current state of the account. | |
card-provider-unavailable | 503 | Card provider unavailable | The card provider appears to be unreachable and may be down. Please try again later. | |
credit-card-access-forbidden | 403 | Credit card access forbidden | You are not authorized to access this credit card. | |
credit-card-malformed-code | 400 | Malformed Credit-Card Code | The code is not in a valid format | |
credit-card-not-found | 404 | Credit-Card Not Found | Credit-Card was not found | |
credit-card-not-revealable | 409 | Credit card not revealable | This card is no longer active, so its details can no longer be shown. | |
mastercard-orphaned-card | 409 | Mastercard card exists without a SpendOne record | A virtual card for this purchase order already exists at Mastercard and was never recorded here. Resolve it before issuing again. | |
mastercard-real-card-not-registered | 409 | No Mastercard real card registered | This legal entity is set to issue Mastercard cards but has no registered real card. | |
purchase-order-malformed-code | 400 | Malformed Purchase-Order Code | The code is not in a valid format | |
purchase-order-not-eligible | 409 | Purchase order not eligible | The purchase order is not in a state that allows credit card issuance. | |
real-card-already-registered | 409 | Real card already registered | This legal entity already has a different real card registered. | |
real-card-duplicate-number | 409 | Real card already registered at the provider | Mastercard has this card number registered already. Reconcile the existing registration before retrying. | |
real-card-last-four-taken | 409 | Real card last 4 already in use | Another legal entity of this tenant already holds a real card ending in the same four digits. | |
statement-not-found | 404 | Statement Not Found | Statement was not found |
active-card-changedis raised by more than one module: credit_cards, subscriptions.card-billing-account-not-configuredis raised by more than one module: credit_cards, subscriptions.credit-card-not-foundis raised by more than one module: credit_cards, subscriptions.purchase-order-malformed-codeis raised by more than one module: credit_cards, purchase_orders.
Users and identity
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
organizational-unit-code-exists | 409 | Organizational-Unit Code Already Exists | A organizational-unit with this code already exists | |
organizational-unit-malformed-code | 400 | Malformed Organizational-Unit Code | The code is not in a valid format | |
organizational-unit-member-not-found | 404 | Organizational-Unit-Member Not Found | Organizational-Unit-Member was not found | |
organizational-unit-not-found | 404 | Organizational-Unit Not Found | Organizational-Unit was not found | |
permission-set-not-assignable | 409 | Permission Set Not Assignable | The permission set was deleted or deactivated and can no longer be assigned. | |
user-already-onboarded | 409 | User Already Onboarded | This user has already completed onboarding and cannot receive a new invitation email. | |
user-email-exists | 409 | User Email Already Exists | A user with this email already exists | |
user-malformed-code | 400 | Malformed User Code | The code is not in a valid format | |
user-must-have-role | 400 | User Must Have A Role | A user must keep at least one role, granted directly or via a permission set. | |
user-zitadel-id-already-set | 409 | User Already Linked | This user is already linked to a Zitadel account. |
Accountant tasks
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
accountant-task-malformed-code | 400 | Malformed Accountant-Task Code | The code is not in a valid format | |
accountant-verification-missing | 409 | Accountant Verification Missing | An accountant must confirm the formal check and the order match before the invoice can be transferred to the FI tool. | |
accountant_task-not-found | 404 | Accountant_task Not Found | Accountant_task was not found | |
assign-to-others-not-permitted | 403 | Assigning To Others Not Permitted | Assigning a task to another user requires the assign-to-others permission; you can still assign it to yourself. | |
assignee-out-of-entity-scope | 422 | Assignee Out Of Entity Scope | The selected assignee's org units do not reach this task's legal entity; choose an assignee who works in that entity. | |
cannot-assign-own-purchase | 409 | Cannot Assign Own Purchase | This task cannot be assigned to the requester or buyer of the purchase; a second person must do the booking (four-eyes principle). | |
cannot-process-own-purchase | 403 | Cannot Process Own Purchase | You cannot complete the accounting steps for your own purchase; a second person must do the booking (four-eyes principle). | |
fi-transfer-owned-by-export | 409 | FI Transfer Owned By The Export | The FI export closes this task itself once it has delivered the invoice; complete it by running the export. | |
invalid-resolution-reason | 400 | Bad Request | resolution_reason must be one of: resolved_externally, not_an_invoice, duplicate. | |
invalid-task-status-transition | 409 | Invalid Task Status Transition | The task cannot be transitioned from its current status; canceled or completed tasks are terminal. | |
invoice-not-ready-for-fi-transfer | 409 | Invoice Not Ready For FI Transfer | The invoice is not in the workflow status required for this FI transfer. Refresh and try again. | |
lifecycle-task-not-retirable | 409 | Lifecycle Task Not Retirable | This task follows its invoice through the accounting workflow and cannot be canceled or deleted on its own; move the invoice instead. | |
purchase-order-not-found | 404 | Purchase-Order Not Found | Purchase-Order was not found | |
task-held-by-another-user | 409 | Task Held By Another User | This task is assigned to another user; assign it to yourself before completing it. |
accountant-verification-missingis raised by more than one module: accountant_tasks, invoices.cannot-process-own-purchaseis raised by more than one module: accountant_tasks, invoices.invoice-not-ready-for-fi-transferis raised by more than one module: accountant_tasks, invoices.purchase-order-not-foundis raised by more than one module: accountant_tasks, credit_cards, invoices.
Admin processes
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
process-not-reassignable | 409 | Process No Longer Open For Reassignment | One of the selected processes was closed, decided or canceled before the reassignment ran. Reload the overview and select again. | |
process-target-on-requesting-side | 409 | Target Cannot Do Their Own Work | The selected user is the buyer or requester behind one of the approvals or accountant tasks in this batch and could never act on it. Pick a different user. | |
user-not-found | 404 | User Not Found | User was not found |
user-not-foundis raised by more than one module: admin_processes, purchase_requests, user_inbound_addresses, users, vacation_substitutions.
Audit Log
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
audit-log-malformed-code | 400 | Malformed Audit-Log Code | The code is not in a valid format | |
audit-log-not-found | 404 | Audit-Log Not Found | Audit-Log was not found |
Auth
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
pool-exhausted | 503 | Service Busy | The service is at capacity. Try again. |
pool-exhaustedis raised by more than one module: auth, platform.
Authorization
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
permission-malformed-code | 400 | Malformed Permission Code | The code is not in a valid format | |
permission-set-has-users | 409 | Permission Set Has Assigned Users | Permission set cannot be deleted while users are assigned | |
permission-set-inactive | 409 | Permission Set Inactive | Operation not allowed on inactive permission set | |
permission-set-malformed-code | 400 | Malformed Permission-Set Code | The code is not in a valid format | |
permission-set-unknown-permission | 400 | Unknown Permission | The permission set names a permission that does not exist | |
permission_set-not-found | 404 | Permission_set Not Found | Permission_set was not found |
Branding
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
branding-branding-exists | 409 | Branding Branding Already Exists | A branding with this branding already exists | |
branding-invalid-color | 400 | Bad Request | Invalid color value | |
branding-invalid-dimensions | 400 | Bad Request | Uploaded image dimensions exceed the limit | |
branding-invalid-file-type | 400 | Bad Request | Unsupported upload content type | |
branding-invalid-font | 400 | Bad Request | Invalid font family | |
branding-invalid-radius | 400 | Bad Request | Invalid corner radius | |
branding-missing-file | 400 | Bad Request | Missing upload file | |
branding-not-found | 404 | Branding Not Found | Branding was not found | |
upload-too-large | 413 | Payload Too Large | Uploaded file exceeds the size limit |
Chart of accounts
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
chart-of-accounts-code-exists | 409 | Account Code Already Exists | Another account already uses that code | |
chart-of-accounts-custom-not-enabled | 409 | Custom Chart Of Accounts Not Enabled | This legal entity has not enabled a custom chart of accounts; enable it first via the legal-entities endpoint | |
chart-of-accounts-import-missing-file | 400 | Missing Upload File | The multipart request is missing the required "file" form field | |
chart-of-accounts-import-too-large | 413 | Upload Too Large | The uploaded file exceeds the maximum allowed size | |
chart-of-accounts-invalid-code | 400 | Invalid Account Code | The account code must be 4-18 alphanumeric characters | |
chart-of-accounts-invalid-name | 400 | Invalid Account Name | The account name must not be empty | |
chart-of-accounts-legal-entity-not-found | 404 | Legal Entity Not Found | No legal entity exists with the given legal_entity_code | |
chart-of-accounts-malformed-code | 400 | Malformed Chart-Of-Accounts Code | The code is not in a valid format | |
chart-of-accounts-not-found | 404 | Account Not Found | No account exists with the given code | |
chart-of-accounts-referenced | 409 | Account In Use | The account is still referenced by a supplier or a posted journal entry; deactivate it instead of deleting or recoding it |
Config
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
config-malformed-code | 400 | Malformed Config Code | The code is not in a valid format | |
config-not-found | 404 | Config Not Found | Config was not found | |
config-setting-exists | 409 | Config Setting Already Exists | A config with this setting already exists | |
custom-field-not-found | 404 | Custom-Field Not Found | Custom-Field was not found |
Cost centers
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
cost-center-code-exists | 409 | Cost-Center Code Already Exists | A cost-center with this code already exists | |
cost-center-malformed-code | 400 | Malformed Cost-Center Code | The code is not in a valid format | |
cost-center-not-found | 404 | Cost-Center Not Found | Cost-Center was not found |
cost-center-not-foundis raised by more than one module: cost_centers, users.
Credit Card Limit Increases
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
credit-card-limit-increase-not-found | 404 | Credit-Card-Limit-Increase Not Found | Credit-Card-Limit-Increase was not found |
Data import
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
access-key-not-found | 404 | Access-Key Not Found | Access-Key was not found | |
data-import-malformed-code | 400 | Malformed Data-Import Code | The code is not in a valid format | |
dataimport-upload-too-large | 413 | Upload Too Large | uploaded file exceeds the maximum allowed size of … bytes | |
import-job-not-found | 404 | Import-Job Not Found | Import-Job was not found | |
import-kind-not-found | 404 | Import-Kind Not Found | Import-Kind was not found |
FI tax mapping
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
fi-tax-mapping-conflict | 409 | Tax Mapping Already Exists | A tax mapping for this combination of FI system, VAT rate, VAT category, and seller region already exists | |
fi-tax-mapping-invalid-category | 400 | Invalid VAT Category Code | The vat_category_code field must not be blank | |
fi-tax-mapping-invalid-fi-system | 400 | Invalid FI System | The target_fi_system field is not a recognized financial integration system; accepted values: DATEV, SAP | |
fi-tax-mapping-invalid-rate | 400 | Invalid VAT Rate | The vat_rate field is required, must be between 0 and 100, and must carry at most 3 decimal places | |
fi-tax-mapping-invalid-seller-region | 400 | Invalid Seller Region | The seller_region field must be EU, NON_EU, or blank for suppliers from anywhere | |
fi-tax-mapping-invalid-target-code | 400 | Invalid Target Tax Code | The target_tax_code field must not be blank | |
fi-tax-mapping-label-too-long | 400 | Tax Mapping Label Too Long | The label field must be at most 100 characters | |
fi-tax-mapping-legal-entity-not-found | 404 | Legal Entity Not Found | No legal entity exists with the given legal_entity_code | |
fi-tax-mapping-not-found | 404 | Tax Mapping Not Found | No tax mapping exists with the given id |
Global Config
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
global-config-malformed-code | 400 | Malformed Global-Config Code | The code is not in a valid format |
Groups
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
group-invalid-kind | 400 | Invalid Group Kind | Only static and dynamic groups can be managed | |
group-malformed-code | 400 | Malformed Group Code | The code is not in a valid format | |
group-not-found | 404 | Group Not Found | Group was not found | |
group-system-read-only | 409 | System Group Is Read-Only | System-derived groups (role, ou) cannot be modified |
Inbound emails
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
attachment-not-found | 404 | Attachment Not Found | Attachment was not found | |
inbound-attachment-already-matched | 409 | Attachment Already Matched | purchase_order_code | |
inbound-attachment-attachment-id-required | 400 | Bad Request | ||
inbound-attachment-delete-forbidden | 403 | Forbidden | ||
inbound-attachment-invalid-document-intent | 400 | Bad Request | ||
inbound-attachment-invalid-id | 400 | Bad Request | ||
inbound-attachment-malformed-code | 400 | Malformed Inbound-Attachment Code | The code is not in a valid format | |
inbound-attachment-not-parked | 409 | Attachment Not Parked | ||
inbound-attachment-owner-mismatch | 403 | Forbidden | ||
inbound-attachment-purchase-order-code-required | 400 | Bad Request | ||
inbound-attachment-restore-forbidden | 403 | Forbidden | ||
purchase_order-not-found | 404 | Purchase_order Not Found | Purchase_order was not found |
purchase_order-not-foundis raised by more than one module: inbound_emails, purchase_orders.
Inbox
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
notification-id-invalid | 400 | Invalid Notification ID | The notification id is not a well-formed id. | |
notification-not-found | 404 | Notification Not Found | Notification was not found |
Legal entities
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
card-vault-not-configured | 503 | Card Vault Not Configured | No Payrails card vault is configured, so a real card cannot be tokenized | |
instrument-has-no-card-number | 422 | Instrument Has No Card Number | The tokenized instrument carries no card number field | |
legal-entity-malformed-code | 400 | Malformed Legal-Entity Code | The code is not in a valid format | |
legal-entity-not-found | 404 | Legal Entity Not Found | No legal entity exists with the given code | |
unreadable-tokenized-card | 422 | Unreadable Tokenized Card | The vault's masked card number or expiry could not be read |
legal-entity-not-foundis raised by more than one module: legal_entities, users.
MCP access
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
mcp-access-not-configured | 503 | MCP Access Not Configured | This environment has no MCP server to enable | |
mcp-access-not-entitled | 403 | MCP Access Not Entitled | The MCP server is not part of this tenant's contract |
Notification Configs
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
notification-config-not-found | 404 | Notification Config Not Found | No notification config exists for that notification type | |
notification-scope-settings-not-found | 404 | Notification Scope Settings Not Found | No notification scope settings exist for that scope |
Notification digests
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
digest-code-exists | 409 | Digest Code Already Exists | A digest with this code already exists | |
digest-disabled | 409 | Digest Is Switched Off | This digest is switched off and does not batch anything, so it takes no personal settings | |
digest-invalid-fire-time | 400 | Invalid Digest Send Time | The digest send time must be a valid HH:MM time | |
digest-name-required | 400 | Digest Name Required | The digest needs a name | |
digest-not-found | 404 | Digest Not Found | Digest was not found | |
digest-not-user-configurable | 403 | Digest Is Admin-Managed | This digest is managed by an administrator and cannot be changed per user | |
digest-type-already-assigned | 409 | Notification Type Already In A Digest | A selected notification type already belongs to another digest | |
digest-type-not-emailable | 400 | Notification Type Cannot Be Emailed | A selected notification type has no email template and cannot be digested | |
digest-types-required | 400 | Digest Needs Notification Types | A digest must bundle at least one notification type | |
digest-user-code-required | 400 | User Code Required | A personal digest setting needs the user it belongs to | |
digest-user-not-found | 404 | Digest-User Not Found | Digest-User was not found | |
digest-user-setting-not-found | 404 | Digest-User-Setting Not Found | Digest-User-Setting was not found | |
notification-digest-malformed-code | 400 | Malformed Notification-Digest Code | The code is not in a valid format |
Payment methods
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
payment-method-malformed-code | 400 | Malformed Payment-Method Code | The code is not in a valid format | |
payment_method-not-found | 404 | Payment_method Not Found | Payment_method was not found |
Personal access tokens
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
api-token-expiry-in-past | 400 | Token Expiry In The Past | expires_at must be in the future | |
personal-access-token-limit-reached | 409 | Personal Access Token Limit Reached | A user may hold at most … active personal access tokens | |
personal-access-token-not-found | 404 | Personal-Access-Token Not Found | Personal-Access-Token was not found |
Product scraper
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
product-scrape-auth-required | 422 | Authentication Required | code, retry_count, url | The target site requires authentication and could not be scraped |
product-scrape-failed | 422 | Scrape Failed | code, url | The page could not be scraped |
product-scrape-no-content | 422 | No Scrapable Content | code, url | The page loaded but contained no scrapable product data |
product-scrape-timeout | 504 | Scrape Timeout | code, elapsed_ms, url | The target site took too long to respond |
product-scrape-unsupported-language | 422 | Unsupported Language | code, detected_language, url | The page's detected language is not supported |
product-scrape-url-blocked | 400 | URL Not Allowed | code, reason, url | The requested URL is not permitted (scheme, userinfo, or address range) |
Products
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
[product category-not-found](https://api.spendone.tech/problems/product category-not-found) | 404 | Product Category Not Found | Product Category was not found | |
product-category-malformed-code | 400 | Malformed Product-Category Code | The code is not in a valid format | |
product-category-protected | 409 | Product Category Protected | This built-in product category cannot be deactivated or deleted. | |
product-malformed-code | 400 | Malformed Product Code | The code is not in a valid format | |
product-not-found | 404 | Product Not Found | Product was not found | |
product_categories-code-exists | 409 | Product_categories Code Already Exists | A product_categories with this code already exists | |
products-code-exists | 409 | Products Code Already Exists | A products with this code already exists | |
products-name-exists | 409 | Products Name Already Exists | A products with this name already exists |
Punchout
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
punchout-ariba-setting-invalid | 422 | Punchout Ariba Setting Invalid | expected, field, value | A connection declared platform=ariba carries a setting SAP Business Network cannot work with, or omits one the onboarding must decide. |
punchout-connection-code-exists | 409 | Punchout-Connection Code Already Exists | A punchout-connection with this code already exists | |
punchout-connection-inactive | 409 | Punchout Connection Inactive | The connection is inactive | |
punchout-connection-not-found | 404 | Punchout-Connection Not Found | Punchout-Connection was not found | |
punchout-credential-not-found | 404 | Punchout-Credential Not Found | Punchout-Credential was not found | |
punchout-credential-secret-exists | 409 | Punchout-Credential Secret Already Exists | A punchout-credential with this secret already exists | |
punchout-credential-tenant-mismatch | 401 | Punchout Credential Tenant Mismatch | Credential tenant mismatch | |
punchout-delivery-url-invalid | 400 | Punchout Delivery URL Invalid | The delivery URL is not an allowed endpoint | |
punchout-document-not-failed | 409 | Punchout Document Not Failed | Only a failed document can be reprocessed | |
punchout-document-not-found | 404 | Punchout-Document Not Found | Punchout-Document was not found | |
punchout-document-not-redeliverable | 409 | Punchout Document Not Redeliverable | Only a delivery-failed or held outbound document can be redelivered | |
punchout-document-payload-exists | 409 | Punchout-Document Payload Already Exists | A punchout-document with this payload already exists | |
punchout-encryption-key-unavailable | 409 | Punchout Encryption Key Unavailable | No usable PUNCHOUT_ENCRYPTION_KEY is configured, so the stored outbound secret cannot be resolved | |
punchout-identity-mismatch | 401 | Punchout Identity Mismatch | Buyer identity mismatch | |
punchout-imported-secret-invalid | 400 | Punchout Imported Secret Invalid | The imported shared secret was not accepted | |
punchout-legal-entity-not-bookable | 422 | Punchout Legal Entity Not Bookable | field, legal_entity_code | The connection's legal_entity_code names no legal entity that can be booked against. |
punchout-malformed-code | 400 | Malformed Punchout Code | The code is not in a valid format | |
punchout-order-contact-not-ownable | 422 | Punchout Order Contact Not Ownable | The order's contact names no active user holding a cost center | |
punchout-outbound-not-configured | 409 | Punchout Outbound Not Configured | The connection has no outbound delivery configuration | |
punchout-outbound-secret-invalid | 400 | Punchout Outbound Secret Invalid | The outbound shared secret was not accepted |
Purchase Flows
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
purchase-flow-malformed-code | 400 | Malformed Purchase-Flow Code | The code is not in a valid format | |
purchase-flow-not-found | 404 | Purchase-Flow Not Found | Purchase-Flow was not found |
Push
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
device-registration-invalid | 400 | Invalid Device Registration | The device token is missing or too long, or the platform is not one of ios, android, web. |
Recommendations
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
service-unavailable | 503 | Service Unavailable | Temporary upstream service unavailable |
Approval rules
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
invalid-rule-type | 400 | Invalid Rule Type | ||
rule-in-use | 409 | Rule In Use | used_by_flows | This rule is referenced by one or more active purchase flows and cannot be deactivated or deleted |
rule-malformed-code | 400 | Malformed Rule Code | The code is not in a valid format | |
rule-not-found | 404 | Rule Not Found | Rule was not found |
SCIM
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
[scim token-not-found](https://api.spendone.tech/problems/scim token-not-found) | 404 | Scim Token Not Found | Scim Token was not found |
Subscriptions
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
cost-center-split-duplicate | 400 | Duplicate Cost Center In Split | Each cost center may appear at most once in the split. | |
cost-center-split-sum-invalid | 400 | Cost-Center Split Must Sum To 100% | The cost-center allocation must sum to exactly 100%. | |
early-replacement-no-headroom | 409 | No Remaining Card Limit | The card being replaced is fully spent, so there is no limit to carry over. Request a limit increase instead. | |
early-replacement-reason-required | 400 | Replacement Reason Required | This card is not yet close to expiry. Replacing it early requires a reason. | |
early-replacement-reason-too-long | 400 | Replacement Reason Too Long | The replacement reason exceeds the maximum length of 500 characters. | |
follow-up-card-budget-exhausted | 409 | Follow-Up Card Budget Exhausted | The remaining subscription budget is exhausted. Request a limit increase before generating a follow-up card. | |
follow-up-card-no-remaining-term | 409 | Subscription Term Fully Covered | The subscription term is already fully covered by existing cards; no further follow-up card is needed. | |
subscription-malformed-code | 400 | Malformed Subscription Code | The code is not in a valid format | |
subscription-not-found | 404 | Subscription Not Found | Subscription was not found |
Suppliers
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
supplier-malformed-code | 400 | Malformed Supplier Code | The code is not in a valid format |
System banners
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
[system banner-not-found](https://api.spendone.tech/problems/system banner-not-found) | 404 | System Banner Not Found | System Banner was not found | |
system-banner-malformed-code | 400 | Malformed System-Banner Code | The code is not in a valid format |
Transaction events
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
export-job-in-progress | 409 | Export Job In Progress | export job is already in progress | |
transaction-event-malformed-code | 400 | Malformed Transaction-Event Code | The code is not in a valid format |
User inbound addresses
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
address-not-found | 404 | Address Not Found | Address was not found | |
user-inbound-address-cannot-promote-disabled | 409 | Cannot make a disabled address the default | Re-enable the address before making it the default. | |
user-inbound-address-invalid-localpart | 400 | Invalid Localpart | A localpart may contain only lowercase letters, digits, dots, hyphens and underscores. | |
user-inbound-address-primary-required | 409 | Cannot disable primary address | Disable a non-primary address; or add a new primary first which will demote this one to secondary. |
Vacation substitutions
| Type | Status | Title | Extensions | Returned when |
|---|---|---|---|---|
invalid-date-range | 400 | Invalid Date Range | End date must be on or after start date | |
self-substitution | 409 | Self Substitution | User cannot substitute for themselves | |
start-date-in-past | 400 | Start Date In Past | Start date cannot be in the past | |
substitute-not-active | 400 | Substitute Not Active | Substitute user is not active | |
substitute-on-vacation | 409 | Substitute On Vacation | Substitute user is also on vacation | |
vacation-access-forbidden | 403 | Vacation Access Forbidden | You are not authorized to manage this vacation substitution. | |
vacation-already-exists | 409 | Vacation Already Exists | User already has an active or scheduled vacation | |
vacation-not-cancellable | 409 | Vacation Not Cancellable | Vacation cannot be canceled in its current status | |
vacation-not-scheduled | 409 | Vacation Not Scheduled | Vacation can only be updated when scheduled | |
vacation-status-conflict | 409 | Vacation Status Conflict | The vacation substitution changed state while the request was in flight; re-read it and retry. | |
vacation-substitution-malformed-code | 400 | Malformed Vacation-Substitution Code | The code is not in a valid format | |
vacation_substitution-not-found | 404 | Vacation_substitution Not Found | Vacation_substitution was not found |