Skip to main content
All Conduit API errors follow RFC 9457 (Problem Details for HTTP APIs). Every error response includes a machine-readable public type field that uniquely identifies the error.
{
  "type": "VALIDATION_ERROR",
  "title": "Validation Error",
  "status": 400,
  "detail": "The field 'email' is not a valid email address.",
  "resolution": "Check the 'errors' array in the response for specific field-level issues and correct your request payload accordingly.",
  "docs": "https://conduit-v2.mintlify.app/errors#validation-error",
  "instance": "/v2/customers/cus_033NVvWNQgT5Arna7wIHO8",
  "correlationId": "corr_xyz789",
  "timestamp": "2026-01-15T09:30:00.000Z"
}
Always match on the type field for error handling logic, not on status or title. The type code is stable across API versions. The title is human-readable and may change.

Synchronous vs terminal failure codes

Conduit surfaces failures on two distinct channels. Branch your error-handling code on which channel a code arrives on, not on the code alone. Synchronous HTTP responses. RFC 9457 Problem Details bodies on the same response as the request that caused them. Validation (VALIDATION_ERROR, ONBOARDING_NOT_READY), authentication (AUTH_INVALID_API_KEY), conflicts (CONFLICT, IDEMPOTENCY_KEY_CONFLICT, RESOURCE_TERMINAL), preconditions (SANDBOX_TRANSACTION_NOT_FORCE_TERMINAL_READY), rate limits (RATE_LIMITED), and similar errors arrive here. A try/catch around the HTTP call sees these. Terminal failureCode values. Codes like AML_REJECTED, COMPLIANCE_HOLD, RETURNED_BY_SENDER, TRAVEL_RULE_REJECTED, USER_SIGNATURE_DECLINED, ROSTER_CHANGED, CHAIN_BROADCAST_FAILED never arrive on an HTTP response. They arrive as the failureCode field on:
  • transaction.failed / transaction.rejected events delivered to your registered webhook endpoint, and
  • GET /v2/transactions/{id} when polled after the transaction reaches a terminal state.
A try/catch around POST /v2/payouts only sees synchronous codes. Terminal codes arrive later via your webhook handler or the next read of the transaction. See webhooks for the webhook payload shape, the API reference for the synchronous error shapes per endpoint, and the transaction failure-code catalog below for terminal codes and their meanings. The “Channel” column on the failure-codes table names where each code is observable.

Field-level errors (errors[])

VALIDATION_ERROR, ONBOARDING_NOT_READY, and DOCUMENT_IDS_NOT_FOUND carry an errors array — one entry per invalid field — alongside the top-level fields above:
{
  "type": "ONBOARDING_NOT_READY",
  "title": "Onboarding Not Ready",
  "status": 422,
  "detail": "Validation failed",
  "errors": [
    { "pointer": "/businessInfo/taxId", "detail": "Tax ID is required", "category": "field" },
    { "pointer": "/documentIds", "detail": "At least one document is required", "category": "document" },
    { "pointer": "/ownership/persons", "detail": "At least 1 CONTROLLING_PERSON is required", "category": "individual" }
  ]
}
  • pointer is an RFC 6901 JSON Pointer to the offending field.
  • detail describes the problem (never echoes the rejected value).
  • category is optional; when set, it’s one of field, document, or individual and lets you group blockers without parsing pointers. field = form-field gap. document = missing or insufficient document (including per-UBO document slots — the pointer still names the person). individual = a required person is missing or has a non-document validation issue. The category is set by the requirements validator (ONBOARDING_NOT_READY and per-flow VALIDATION_ERROR); it’s omitted on top-level schema rejections that don’t carry the same context.

Transaction failure-code catalog

The table below is committed alongside the runtime enum; CI breaks if a code is added without updating it. Each code links to its recovery playbook.
CodeTerminal stateChannelDescriptionPlaybook
AML_REJECTEDfailedwebhook + polledAML screening rejected the transaction (sanctions-class signals route here)Playbook
CHAIN_BROADCAST_FAILEDfailedwebhook + polledThe signed payout could not be broadcast to the chain before reaching finality; no funds left the walletPlaybook
COMPLIANCE_HOLDfailedwebhook + polledCompliance review held the funds; manual remediation requiredPlaybook
COMPLIANCE_REJECTEDfailedwebhook + polledA compliance reviewer rejected the payout’s supporting documentation; reserved funds were returned (fires transaction.rejected, not transaction.failed)Playbook
CRYPTO_WALLET_MISCONFIGUREDfailedwebhook + polledThe source wallet is missing required custody configuration; the payout could not be signedPlaybook
INSUFFICIENT_FUNDS_AT_SETTLEfailedwebhook + polledSource funds were insufficient at the settlement attemptPlaybook
PROVIDER_REJECTEDfailedwebhook + polledThe crypto outbound provider declined the broadcast request before the transaction was submitted to the chainPlaybook
RAIL_POLICY_REJECTEDfailedwebhook + polledThe receiving rail rejected the payment per its policyPlaybook
RAIL_UNAVAILABLEfailedwebhook + polledThe chosen rail was temporarily unavailablePlaybook
RETURNED_BY_SENDERfailedwebhook + polledThe inbound transfer was returned by the originating institution before it could be creditedPlaybook
ROSTER_CHANGEDfailedwebhook + polledA signer on the customer’s roster was removed (or demoted out of the signing pool) while the payout was awaiting signatures; the half-collected stamps were voided so the fintech can re-initiatePlaybook
SENDER_INFO_TIMEOUTfailedwebhook + polledSender-information gate expired before resolutionPlaybook
TRAVEL_RULE_REJECTEDfailedwebhook + polledCounterparty rejected the Travel Rule request, or Travel Rule validation failed pre-broadcastPlaybook
USER_SIGNATURE_DECLINEDfailedwebhook + polledEnd user explicitly declined to signPlaybook
USER_SIGNATURE_REJECTED_BY_PROVIDERfailedwebhook + polledCustody provider rejected the signature payloadPlaybook
USER_SIGNATURE_TIMEOUTfailedwebhook + polledEnd user did not sign within the cosign windowPlaybook

Sandbox simulate endpoint errors

These codes are returned as HTTP errors by sandbox simulate endpoints. They are not failureCode values on transactions.
CodeHTTP statusDescriptionPlaybook
CONCURRENT_COSIGN_IN_FLIGHT409Source wallet has a non-custodial payout awaiting signature on the same chainPlaybook
INVALID_ADDRESS_FORMAT400EVM address must be all-lowercase or a correct EIP-55 checksumPlaybook
RESOURCE_TERMINAL409Tried to drive a simulate against an already-terminal entityPlaybook
SANDBOX_TRANSACTION_NOT_FORCE_TERMINAL_READY422Called a sandbox simulate endpoint whose requested outcome is not viable in the transaction’s current phase (e.g. simulate/settled or simulate/confirm against a payout parked at the document-review gate, or simulate/terminal with outcome:completed before a fiat route is selected)Playbook
For HTTP-level error responses (e.g., 400 VALIDATION_ERROR, 404 NOT_FOUND, 409 CONFLICT), see the per-status sections below.

Error Codes

Validation Error

VALIDATION_ERROR — HTTP 400 The request body or query parameters failed validation. One or more fields have invalid values, missing required properties, or incorrect types. Multipart file uploads that fail at the multipart-parser layer (unexpected form-field name, too many parts) carry an extra ‘field’ member naming the offending form-field. Resolution: Check the ‘errors’ array in the response for specific field-level issues and correct your request payload accordingly. For multipart uploads, also inspect the optional ‘field’ member.

Malformed JSON Body

MALFORMED_JSON — HTTP 400 The request body could not be parsed as JSON. Bodies declared as ‘application/json’ — and bodies with no Content-Type header, which are assumed to be JSON — must contain syntactically valid JSON. Resolution: Fix the JSON syntax in the request body. If you intended to send a different format, declare it in the Content-Type header instead; JSON endpoints only accept ‘application/json’.

Rate Limited

RATE_LIMITED — HTTP 429 Too many requests. This error is returned by three independent checks: the per-organization bucket applied to every authenticated API request; the per-IP bucket applied to unauthenticated traffic before an API key is validated; and the per-IP bucket applied when repeated invalid API keys are submitted from the same address. Honor the Retry-After header (also exposed as retryAfterSeconds in the body) before retrying. Current limits and remaining budget are visible in X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset on rate-limited route responses. Resolution: Sleep until Retry-After seconds have elapsed, then retry. For sustained workloads exceeding the per-organization defaults, request a rate-limit increase through your support contact.

Invalid Object ID Format

INVALID_OID_FORMAT — HTTP 400 A path or query parameter expected a valid object identifier but received a value that does not match the expected format. Resolution: Verify that all IDs in the request URL and query parameters are correctly formatted. IDs are typically prefixed strings like ‘cus_…’, ‘app_…’, or ‘doc_…’.

Invalid Cursor

INVALID_CURSOR — HTTP 400 The pagination cursor provided in the request is malformed or has expired. Resolution: Use a cursor value returned from a previous list response. Do not construct cursor values manually. If the cursor has expired, start pagination from the beginning.

API Key Missing

API_KEY_MISSING — HTTP 401 The request did not include an API key. All API requests must be authenticated. Resolution: Include your API key in the ‘x-api-key’ header with every request.

API Key Invalid

API_KEY_INVALID — HTTP 401 The provided API key is not recognized or has been revoked. Resolution: Verify that your API key is correct and has not been revoked. Generate a new key from the dashboard if needed.

Feature Not Enabled

FEATURE_NOT_ENABLED — HTTP 403 Your account does not have access to this feature. Features are enabled on a per-account basis. Resolution: Contact support to request access to this feature, or check your account settings to verify which features are enabled.

API Key Creation Disabled

API_KEY_CREATION_DISABLED — HTTP 403 API key creation is not currently enabled for this organization. Resolution: Contact Conduit to request API access for your organization.

API Key Is Read-Only

API_KEY_READ_ONLY — HTTP 403 This API key has read-only access and cannot perform write operations. Read-only keys may make read requests (GET, HEAD, OPTIONS) only. Resolution: Use a read-write API key for this request, or have an organization admin mint one from the dashboard.

Read-Write Key Requires Admin

API_KEY_WRITE_REQUIRES_ADMIN — HTTP 403 Only an organization admin can create a read-write API key. Developers may create read-only keys. Resolution: Ask an organization admin to create the read-write key, or create a read-only key instead.

Insufficient Role

INSUFFICIENT_ROLE — HTTP 403 Your user role does not permit this action. This operation requires a higher-privileged role. Resolution: Ask an organization admin to perform this action or to grant you the required role.

Last Organization Admin

LAST_ORG_ADMIN — HTTP 409 This user is the organization’s only admin. An organization must always have at least one admin. Resolution: Invite or assign another organization admin before removing this user.

Cannot Remove Self

CANNOT_REMOVE_SELF — HTTP 409 You cannot remove your own account from the organization. Resolution: Ask another organization admin to remove your account.

Internal Error

INTERNAL_ERROR — HTTP 500 An unexpected error occurred while processing your request. Resolution: Retry the request after a brief delay. If the error persists, contact support and include the correlationId from the error response for investigation.

Bad Request

BAD_REQUEST — HTTP 400 The request could not be understood or was missing required parameters. Resolution: Review the request format and ensure all required parameters are present and correctly typed.

Unauthorized

UNAUTHORIZED — HTTP 401 Authentication is required and has not been provided or is invalid. Resolution: Provide valid authentication credentials. Check that your API key or token has not expired.

Forbidden

FORBIDDEN — HTTP 403 You do not have permission to perform this action on the requested resource. Resolution: Verify that your account has the required permissions for this operation. Contact your administrator if you believe this is an error.

Not Found

NOT_FOUND — HTTP 404 The requested resource does not exist or you do not have access to it. Resolution: Check that the resource ID in the URL is correct. The resource may have been deleted or may belong to a different account.

Conflict

CONFLICT — HTTP 409 The request conflicts with the current state of the resource. This usually means a duplicate or a state transition that is not allowed. Resolution: Check the current state of the resource before retrying. If creating a resource, verify that a resource with the same unique fields does not already exist.

Gone

GONE — HTTP 410 The requested resource has been permanently removed and is no longer available. Resolution: This resource has been deleted and cannot be recovered. Remove any references to it in your system.

Precondition Failed

PRECONDITION_FAILED — HTTP 412 A precondition specified in the request headers was not met by the server. Resolution: Re-fetch the resource to get the current state and retry with the updated precondition values.

Unprocessable Entity

UNPROCESSABLE_ENTITY — HTTP 422 The request was well-formed but could not be processed due to semantic errors or business rule violations. Resolution: Review the error details and adjust your request to comply with the documented business rules for this endpoint.

Payload Too Large

PAYLOAD_TOO_LARGE — HTTP 413 The request body exceeds the maximum size accepted by the server. Resolution: Reduce the size of the request payload and retry. For file uploads, the response will instead carry the more specific FILE_TOO_LARGE code with the limit and offending field.

Unsupported Media Type

UNSUPPORTED_MEDIA_TYPE — HTTP 415 The request carries a body with a Content-Type this endpoint cannot parse. JSON endpoints accept ‘application/json’; a body with no Content-Type header at all is assumed to be JSON. File-upload endpoints accept only ‘multipart/form-data’ — JSON or undeclared bodies are rejected there. Resolution: Send the request body with the ‘Content-Type: application/json’ header. For file uploads, use ‘Content-Type: multipart/form-data’ — upload endpoints accept no other body type.

Bad Gateway

BAD_GATEWAY — HTTP 502 An upstream service returned an invalid response while processing your request. Resolution: Retry the request after a brief delay. If the error persists, an upstream dependency may be experiencing issues.

Service Unavailable

SERVICE_UNAVAILABLE — HTTP 503 The service is temporarily unable to handle your request due to maintenance or capacity constraints. Resolution: Retry the request using exponential backoff. Check the status page for any ongoing incidents.

Customer Not Found

CUSTOMER_NOT_FOUND — HTTP 404 No customer exists with the specified ID, or the customer belongs to a different organization. Resolution: Verify the customer ID is correct. Use the list customers endpoint to find valid customer IDs for your organization.

Customer Not Onboarded

CUSTOMER_NOT_ONBOARDED — HTTP 422 This operation requires the customer to have completed onboarding, but the customer has not been fully onboarded yet. Resolution: Complete the customer onboarding process before attempting this operation. See the onboarding guide for the required steps. Runbook: Customer Not Onboarded

Document IDs Not Found

DOCUMENT_IDS_NOT_FOUND — HTTP 400 One or more document IDs provided in the request do not exist or do not belong to this customer. Resolution: Verify that all document IDs are correct and belong to the customer specified in the request.

Application Not Found

APPLICATION_NOT_FOUND — HTTP 404 No application exists with the specified ID, or the application belongs to a different organization. Resolution: Verify the application ID is correct. Use the list applications endpoint to find valid application IDs for your organization.

Application Invalid Status

APPLICATION_INVALID_STATUS — HTTP 409 The requested operation cannot be performed because the application is not in the required status. Resolution: Check the application’s current status and refer to the documentation for allowed status transitions.

Application Already Decided

APPLICATION_ALREADY_DECIDED — HTTP 409 The application has already reached a terminal status (approved, rejected, or cancelled) and cannot be decided again. Resolution: A decided application is final. Create a new application instead of re-deciding this one.

Rejection Category Not Applicable

REJECTION_CATEGORY_NOT_APPLICABLE — HTTP 422 The sandbox application-simulate category body field is only meaningful for KYB-pipeline applications. Other application types reject any category value. Resolution: Omit the category field (the service falls back to a generic sandbox-rejection sentinel) or call simulate/decision with outcome: "rejected" against a KYB-pipeline application. INVALID_LEGAL_STRUCTURE — HTTP 400 The submitted companyClassification.legalStructure is not a valid local structure for the registered country. Valid options are surfaced by the discovery endpoint (/v2/onboarding/requirements?country=...); the submission must use one of those exact option values. Resolution: Re-fetch the requirements for the registered country and submit one of the listed companyClassification.legalStructure option values verbatim.

Order Not Found

ORDER_NOT_FOUND — HTTP 404 No order exists with the specified ID, or the order has expired. Resolution: Verify the order ID is correct. Orders have a limited validity period; create a new order if the previous one has expired.

Unsupported Pair

UNSUPPORTED_PAIR — HTTP 422 The requested source and destination asset pair is not supported. Resolution: Check the configured trading pairs and submit a supported source/destination asset combination.

Invalid Order Combination

INVALID_ORDER_COMBO — HTTP 422 The requested order combination is not supported: same-asset same-chain moves, mismatched source and destination resources, or an autoPayout shape that does not match the order direction. OFFRAMP orders require a fiat autoPayout ({ rail, recipient }); ONRAMP orders require a crypto autoPayout ({ recipient: { rail: 'CRYPTO', chain, address, attestation } }), self- or third-party-custody. Crypto autoPayout addresses must be external; Conduit-managed wallet addresses are refused. Resolution: Adjust the source/destination pair to a supported combination, or align autoPayout with the order direction: fiat autoPayout for OFFRAMP, crypto autoPayout for ONRAMP. For ONRAMP, the recipient address must be external (not a Conduit-managed wallet) and match the destination wallet’s chain.

No Pricing Configured

NO_PRICING_CONFIGURED — HTTP 404 No active pricing profile contains a base pricing rule for the requested asset pair. Resolution: Configure a base pricing rule for the source/destination pair before requesting an order.

Missing Required Fields

MISSING_REQUIRED_FIELDS — HTTP 422 The order request is missing one or more fields required for the destination shape. Resolution: Review the order requirements response for the requested pair, country, rail, and recipient type.

Recipient Validation Failed

RECIPIENT_VALIDATION_FAILED — HTTP 422 The supplied recipient or destination details failed validation for the chosen rail, chain, or corridor. Resolution: Verify that the recipient or destination fields (e.g., destination address, account number, routing details) are valid for the chosen rail, chain, and country.

Amount Out of Range

AMOUNT_OUT_OF_RANGE — HTTP 422 The requested amount is below the minimum or above the maximum allowed for this order. Resolution: Adjust the amount to fall within the allowed range.

Rate Unavailable

RATE_UNAVAILABLE — HTTP 503 A live exchange rate could not be retrieved for the requested currency pair. The rate provider may be temporarily unavailable. Resolution: Retry the request after a short delay. If the error persists, the rate provider for this currency pair may be experiencing an outage. Runbook: Rate Unavailable

Order Not Executable

ORDER_NOT_EXECUTABLE — HTTP 409 The order cannot be executed because it is not in a pending state. Already-executed or failed orders cannot be re-executed. Resolution: Create a new order. An order can only be executed once and only while it is pending.

Order Expired

ORDER_EXPIRED — HTTP 409 The order has expired and can no longer be executed. Resolution: Create a new order to obtain a fresh price lock and execute that one instead.

Order Cannot Be Cancelled

ORDER_NOT_CANCELLABLE — HTTP 409 The order cannot be cancelled. Either it is already in a terminal state (succeeded or failed), or its execution has begun moving funds and the cancel path can no longer safely unwind it. Resolution: Read the order to confirm its current state. If it is already terminal, no action is required. If it is still pending while executing, wait for the order to reach a terminal state and react to that; once execution has started only the server can safely complete or reverse the order.

Provider unavailable

PROVIDER_UNAVAILABLE — HTTP 503 The order’s conversion provider was unavailable or returned a transient failure during execution. No funds were moved. Resolution: Retry by creating a new order. If the issue persists, contact support.

Provider rejected the conversion

PROVIDER_REJECTED — HTTP 422 The order’s conversion provider rejected the request (rate stale, recipient blocked, or other provider-side policy). No funds were moved. Resolution: Verify the order parameters (rate, recipient, amount) and submit a new order. Contact support if the cause is unclear.

Conversion cancelled

CANCELLED — HTTP 422 The order’s conversion was cancelled before completion (operator action or upstream condition). No funds were moved. Resolution: Submit a new order to retry.

User Not Found

USER_NOT_FOUND — HTTP 404 No user exists with the specified ID, or the user belongs to a different organization. Resolution: Verify the user ID is correct. Use the list users endpoint to find valid user IDs for your organization.

User Already Exists

USER_ALREADY_EXISTS — HTTP 409 A user with the same email address already exists in this organization. Resolution: Use the existing user or choose a different email address. Use the list users endpoint to find the existing user.

User Already Belongs to Organization

USER_ALREADY_BELONGS_TO_ORG — HTTP 409 The calling user is already linked to an organization. Each user can belong to one organization at a time; calling setup a second time on the same user is rejected. Resolution: Resolve the calling user’s existing organization (e.g. via GET /v2/portal/users/me) and route the user accordingly instead of retrying setup.

Wallet Not Found

WALLET_NOT_FOUND — HTTP 404 No wallet exists with the specified ID, or the wallet belongs to a different organization. Resolution: Verify the wallet ID is correct. Use the list wallets endpoint to find valid wallet IDs for your organization.

Cosign activity not found

COSIGN_ACTIVITY_NOT_FOUND — HTTP 404 Sandbox cosign activity could not be located. Resolution: Verify the activityId. Sandbox-only: activity IDs are issued during cosign creation. If you don’t have one, use POST /v2/sandbox/payouts/:id/simulate/cosign to resolve the cosign gate keyed by payout id instead.

Wallet Not Active

WALLET_NOT_ACTIVE — HTTP 422 The wallet is not in ACTIVE status and cannot accept deposits at this time. Resolution: Check the wallet’s current status. Only ACTIVE wallets can receive simulated deposits.

Wallet Rotation Blocked: Non-Zero Balance

WALLET_ROTATION_BLOCKED_BALANCE — HTTP 422 The wallet has a non-zero balance (available, pending, or frozen) and cannot be rotated. Rotation would strand the existing funds on the retired wallet record. Resolution: Move all funds out of the wallet (e.g. via a payout) and wait for any in-flight deposits to settle, then retry the rotation. Compliance-frozen balances must be released before rotation is possible.

Wallet Not Rotatable

WALLET_NOT_ROTATABLE — HTTP 409 Only an active wallet can be rotated. The wallet is no longer active — it may already have been rotated or disabled. Resolution: Fetch the wallet to check its current status. A retired wallet exposes the replacement via replacedByWalletId; rotate that one instead.

Wallet Rotation In Progress

WALLET_ROTATION_IN_PROGRESS — HTTP 409 A rotation for this wallet is already running. Concurrent rotations of the same wallet are rejected until the in-flight one completes. Resolution: Wait for the in-flight rotation to finish (the wallet’s address updates on completion), then retry if needed.

Wallet Has No Deposit Address

WALLET_NO_ADDRESS — HTTP 422 The wallet does not have a deposit address assigned. Address provisioning may still be in progress. Resolution: Wait for the wallet to be fully provisioned before simulating a deposit. If the issue persists, contact support.

Wallet Chain Mismatch

WALLET_CHAIN_MISMATCH — HTTP 422 The chain specified in the request does not match the chain the wallet is provisioned on. Resolution: Use the correct chain for this wallet. Fetch the wallet details to see which chain it is provisioned on.

Virtual Account Not Found

VIRTUAL_ACCOUNT_NOT_FOUND — HTTP 404 No virtual account exists for the requested customer and asset, or the virtual account belongs to a different organization. Resolution: Verify the customer has an active virtual account for the requested asset before creating a fiat payout.

Virtual Account Not Active

VIRTUAL_ACCOUNT_NOT_ACTIVE — HTTP 422 The virtual account is not in ACTIVE status and cannot accept deposits at this time. Resolution: Check the virtual account’s current status. Only ACTIVE virtual accounts can receive simulated deposits.

Virtual Account Asset Mismatch

VIRTUAL_ACCOUNT_ASSET_MISMATCH — HTTP 422 The asset or chain specified in the request does not match the virtual account’s configured asset. Resolution: Use the asset code matching the virtual account’s configured fiat asset. Fetch the virtual account details to see its asset.

Wallet Custody Not Claimed

WALLET_CUSTODY_NOT_CLAIMED — HTTP 409 The customer’s wallet account is still custodial. Wallet addresses cannot be issued until the customer claims non-custodial control of the account. Resolution: Have the customer claim non-custodial control before retrying. Fresh customers: POST /v2/customers/:id/wallets/claim-non-custodial with a signer roster and signing threshold. Existing custodial customers (post-CRYPTO_WALLET): submit a WALLET_CUSTODY_CONVERSION application via POST /v2/customers/:id/features and complete the passkey or OAuth verification.

Registered Address Not Found

REGISTERED_ADDRESS_NOT_FOUND — HTTP 404 No registered address exists with the specified ID, or the registered address belongs to a different organization. Resolution: Verify the registered address ID is correct. Use the list registered addresses endpoint to find valid IDs for the customer.

Transaction Not Found

TRANSACTION_NOT_FOUND — HTTP 404 No transaction exists with the specified ID, or the transaction belongs to a different organization. Resolution: Verify the transaction ID is correct. Use the list transactions endpoint to find valid IDs for your organization.

Transaction Type Not Simulatable

SANDBOX_TRANSACTION_TYPE_NOT_SIMULATABLE — HTTP 422 The sandbox simulate-terminal endpoint does not support this transaction type. Resolution: Supported types: WITHDRAWAL, ONRAMP, OFFRAMP, DEPOSIT. INTERNAL_TRANSFER is not supported. Check the response body for the current allowlist.

Transaction Not Force-Terminal Ready

SANDBOX_TRANSACTION_NOT_FORCE_TERMINAL_READY — HTTP 422 A sandbox simulate endpoint refused the request because the requested outcome is not viable in the transaction’s current phase. Common cases: a payout parked at the document-review gate receiving simulate/settled or simulate/confirm before review approval; a fiat payout with no selected settlement route receiving simulate/terminal with outcome: "completed". Resolution: If the payout carries documents, call POST /v2/sandbox/payouts/{id}/simulate-review-approve (or simulate-review-reject) first. For simulate/terminal callers, wait for the transaction to advance to the next phase or call with outcome: "failed" to terminalize from the current phase.

Deposit Not Awaiting Sender Information

UNREGISTERED_ADDRESS_NOT_AWAITING — HTTP 409 The deposit is not currently awaiting sender information. Sender information can only be submitted while the deposit is processing and waiting for those details. Resolution: Re-fetch the deposit to inspect its current public status. If the deposit has already progressed, no further sender-information submission is needed.

Transaction Is Not a Deposit

SENDER_INFO_NOT_A_DEPOSIT — HTTP 404 Sender information can only be submitted for deposits. The transaction with the specified ID exists but is not a deposit. Resolution: Verify the transaction ID. Sender-information submission applies only to inbound fiat deposits parked on an unregistered address.

Sender Information Already Recorded

SENDER_INFO_ALREADY_RECORDED — HTTP 409 Sender information has already been recorded for this deposit. The first submission wins; later submissions are rejected. Resolution: Re-fetch the deposit to inspect its current public status. The recorded sender information is final for this deposit.

Sender Information Submission In Flight

SENDER_INFO_SUBMISSION_IN_FLIGHT — HTTP 409 Another sender-information submission for this deposit is still being processed. Resolution: Wait for the in-flight submission to resolve, then re-fetch the deposit before retrying.

Deposit is not waiting for sender information

SANDBOX_SENDER_INFO_NOT_REQUIRED — HTTP 409 The deposit is not currently parked at the sender-information gate. It may have already been resolved, never required sender information, or reached a terminal state. Resolution: Inspect the deposit status. Only deposits that are pending and waiting for sender information accept this simulator.

Signer Not Found

SIGNER_NOT_FOUND — HTTP 404 No signer exists with the specified ID for this wallet. Resolution: Verify the signer ID is correct and that it belongs to the specified wallet.

Signer Not Active

SIGNER_NOT_ACTIVE — HTTP 409 The signer is not in an active state and cannot perform the requested operation. Resolution: Check the signer’s current status. Only active signers can sign transactions or be modified.

Signer Removal Forbidden

SIGNER_REMOVAL_FORBIDDEN — HTTP 403 The signer cannot be removed because it is the last remaining signer on the wallet or has a protected role. Resolution: Add another signer to the wallet before removing this one, or contact support if the signer has a protected role.

Signers Not Supported

SIGNERS_NOT_SUPPORTED — HTTP 422 Signers can only be managed on non-custodial wallets. This customer’s wallet is custodial, so the backend signs on its behalf. Resolution: Convert the wallet to non-custodial via the WALLET_CUSTODY_CONVERSION application flow before adding or removing signers.

Roster Below Minimum Admins

ROSTER_BELOW_MIN_ADMINS — HTTP 400 A non-custodial roster must contain at least 2 admin signers so no single person can lose access to the wallet. Resolution: Include at least 2 signers with role admin in the roster before submitting the claim.

Signing Threshold Exceeds Roster

THRESHOLD_EXCEEDS_ROSTER — HTTP 400 The requested signingThreshold is greater than the number of signers in the roster, which would make signing impossible. Resolution: Lower signingThreshold to at most the roster size, or add signers to the roster before raising the threshold.

Duplicate Signer Email

SIGNER_EMAIL_DUPLICATE — HTTP 400 The roster contains two or more signers with the same email address. Each signer must map to a distinct human. Resolution: Remove the duplicate entries so every signer in the roster has a unique email.

Machine Signer Credentials Not Yet Supported

API_KEY_CREDENTIAL_NOT_SUPPORTED — HTTP 422 The roster includes one or more signers with credentialType: api_key. Phase 0 sandbox does not install machine-signer public keys on the provider, so these signers would never be able to stamp. Real provider wiring lands with C2-1539. Resolution: Use credentialType: passkey for every roster member until the real provider integration ships. The wallet_signer.invited flow installs a passkey credential during enrollment.

Customer Already Non-Custodial

CUSTOMER_ALREADY_NON_CUSTODIAL — HTTP 409 Non-custodial control has already been claimed for this customer; the claim endpoint provisions only fresh customers. Resolution: Use the roster-management endpoints to add, remove, promote, or demote signers; the customer is already in the target state.

Customer Already Custodial

CUSTOMER_ALREADY_CUSTODIAL — HTTP 409 This customer already has a custodial wallet account from initial onboarding. The claim endpoint provisions only fresh customers; converting an existing custodial wallet to non-custodial is not yet supported. Resolution: Use the WALLET_CUSTODY_CONVERSION application flow to convert this customer to non-custodial, then manage signers via the per-signer add/remove endpoints. Multi-signer roster-style claim on existing custodial wallets will land in a follow-up.

Customer KYB Incomplete

CUSTOMER_KYB_INCOMPLETE — HTTP 422 Non-custodial control can only be claimed after the customer’s KYB application has been approved. Resolution: Complete and submit the customer’s KYB application, wait for approval, and retry the claim once the customer is active.

Signer Is Admin

SIGNER_IS_ROOT_MEMBER — HTTP 409 Admins cannot be removed directly. They must be demoted to a regular member first so the demote flow can verify that quorum and minimum-admin invariants are still satisfied. Resolution: Demote the signer to a non-admin role via the demote endpoint, then call remove.

Signer Already Admin

SIGNER_ALREADY_ADMIN — HTTP 409 The promotion target already has the admin role. Resolution: No action needed; the signer already holds the role you are trying to assign.

Signer Passkey Count Too Low

SIGNER_PASSKEY_COUNT_TOO_LOW — HTTP 422 Promotion to admin requires the signer to have at least 2 registered passkeys so they cannot lose admin access by losing a single device. Resolution: Have the signer register a second passkey from a different device, then retry the promotion.

Signer Not Admin

SIGNER_NOT_ADMIN — HTTP 409 The demotion target is not currently an admin, so there is nothing to demote. Resolution: Verify the signer ID; only signers with role admin are eligible for demotion.

Would Break Minimum Admins

WOULD_BREAK_MIN_ADMINS — HTTP 409 Demoting this signer would leave fewer than 2 admins on the roster, violating the minimum-admin invariant. Resolution: Promote another signer to admin first, then retry the demotion.

Ceremony In Flight

CEREMONY_IN_FLIGHT — HTTP 409 A roster-change ceremony for this signer is already in progress. Concurrent promote/demote requests against the same signer are rejected until the in-flight ceremony completes or fails. Resolution: Wait for the in-flight ceremony to terminate (the wallet_signer.promoted or wallet_signer.demoted webhook signals completion), then retry.

Provider Account Not Found

PROVIDER_ACCOUNT_NOT_FOUND — HTTP 404 No non-custodial provider account exists for the specified customer, so signing-quorum settings cannot be read or changed. Resolution: Verify the customer has completed non-custodial wallet onboarding before reading or changing signing-quorum settings.

Claim Reset Blocked by Referencing Rows

CLAIM_RESET_BLOCKED — HTTP 409 The sandbox simulate-reset-claim endpoint cannot wipe the customer’s non-custodial setup while transactions, deposits, or pending signature approvals still reference the wallets or signers. Hard-deleting them would FK-violate. Resolution: Terminalize the open transactions first (POST /v2/sandbox/transactions/:id/simulate/terminal), then call simulate-reset-claim again.

Quorum Threshold Exceeds Eligible Signers

QUORUM_THRESHOLD_EXCEEDS_SIGNERS — HTTP 409 The requested signing-quorum threshold is greater than the number of active signers eligible to approve. A threshold can never exceed the signer count, or transactions would become impossible to sign. Resolution: Lower the requested threshold to at most the number of active signers, or add more signers before raising the threshold.

Wallet Quorum Override Cannot Raise Threshold

QUORUM_WALLET_OVERRIDE_CANNOT_RAISE — HTTP 422 A per-wallet signing-quorum override may not set a threshold higher than the customer-level threshold. The underlying signing policy cannot yet enforce a raised per-wallet threshold, so allowing it would leave the wallet under-protected. Resolution: Set the per-wallet override at or below the customer-level threshold, or raise the customer-level threshold instead.

Document Not Found

DOCUMENT_NOT_FOUND — HTTP 404 No document exists with the specified ID, or the document belongs to a different organization. Resolution: Verify the document ID is correct. Use GET /v2/documents to find valid document IDs.

Unsupported File Type

UNSUPPORTED_FILE_TYPE — HTTP 400 The uploaded file’s content does not match an allowed type. File type is determined by inspecting the file’s contents (magic bytes), not the filename extension or the Content-Type header. Allowed types: PDF, JPEG, PNG. Resolution: Re-upload using one of the supported formats. Renaming a file or changing its Content-Type header does not change its content type — convert the file to PDF, JPEG, or PNG instead.

File Too Large

FILE_TOO_LARGE — HTTP 413 The uploaded file exceeds the maximum allowed size (10 MB). The response carries an extra ‘field’ member naming the form-field that exceeded the limit (typically ‘file’). Resolution: Reduce the file size and re-upload. Multi-page PDFs that exceed the limit should be split into smaller files. High-resolution images may be downscaled or re-encoded with stronger compression.

Invalid File Name

INVALID_FILE_NAME — HTTP 400 The uploaded file’s name contains characters that are not allowed (path separators, control characters, NUL bytes, or path traversal sequences). Resolution: Rename the file using only printable characters and re-upload. Do not include directory separators (/, \), .., or control characters in the filename.

Verification Not Found

VERIFICATION_NOT_FOUND — HTTP 404 No verification exists with the specified ID, or the verification belongs to a different organization. Resolution: Verify the verification ID is correct. Use the list verifications endpoint to find valid verification IDs.

Verification Not Declinable

VERIFICATION_NOT_DECLINABLE — HTTP 409 The verification type does not support the decline operation. Only TRANSACTION_APPROVAL and QUORUM_CONFIG_CHANGE verifications can be declined; other types are resolved by abandonment or expiry. Resolution: Do not call the decline endpoint for this verification type. WALLET_* verifications expire automatically via their TTL.

Verification Decline Failed

VERIFICATION_DECLINE_FAILED — HTTP 409 The reject stamp did not land as a rejection on the underlying signing activity. The decline could not be recorded. Resolution: Re-fetch the verification context and retry the decline with a freshly stamped reject credential.

Verification Invalid Status

VERIFICATION_INVALID_STATUS — HTTP 409 The requested operation cannot be performed because the verification is not in the expected status. Resolution: Check the verification’s current status. Verifications can only be completed while in PENDING status.

Verification Token Invalid

VERIFICATION_TOKEN_INVALID — HTTP 400 The verification token is malformed, expired, or does not match any pending verification. Resolution: Request a new verification link. Tokens are single-use and expire after a short window.

Feature Already Exists

FEATURE_ALREADY_EXISTS — HTTP 409 A feature with the same identifier already exists for this account. Resolution: Use the existing feature or choose a different identifier.

Customer Update Already Pending

CUSTOMER_UPDATE_ALREADY_PENDING — HTTP 409 An update application for this customer is already pending or processing. Only one update can be in flight per customer. Resolution: Wait for the in-flight update application to reach a terminal status (approved, rejected, or cancelled) before submitting a new one. List the customer’s applications to find it.

Onboarding Not Ready

ONBOARDING_NOT_READY — HTTP 422 The onboarding submission cannot be completed because one or more required fields or documents are still missing. Resolution: Use the onboarding requirements endpoint to check which fields and documents are still required, then submit them before retrying.

Onboarding Already Submitted

ONBOARDING_ALREADY_SUBMITTED — HTTP 409 The onboarding application has already been submitted and cannot be submitted again. Resolution: The onboarding is already in review. Check the application status for updates on the review progress.

Customer Already Onboarded

CUSTOMER_ALREADY_ONBOARDED — HTTP 409 An approved customer already exists for this organization with the same tax identifier. Resolution: Use the existing customer (returned as details.customerId) rather than creating a new one. To replace it, decommission the existing customer first.

Webhook Endpoint Not Found

WEBHOOK_ENDPOINT_NOT_FOUND — HTTP 404 No webhook endpoint exists with the specified ID, or it belongs to a different organization. Resolution: Verify the endpoint ID is correct. Use the list webhook endpoints endpoint to find valid IDs for your organization.

Webhook Delivery Not Found

WEBHOOK_DELIVERY_NOT_FOUND — HTTP 404 No webhook delivery record exists with the specified ID. Resolution: Verify the delivery ID is correct. Use the list deliveries endpoint to find valid delivery IDs.

Webhook Delivery Not Retryable

WEBHOOK_DELIVERY_NOT_RETRYABLE — HTTP 422 The webhook delivery cannot be retried because it is not in a failed state or has exceeded the maximum retry attempts. Resolution: Only failed deliveries can be retried. Check the delivery status before attempting a retry.

Unsupported Asset

UNSUPPORTED_ASSET — HTTP 400 The requested asset and chain combination is not supported for this operation. Resolution: Check the list of supported assets for the target chain and retry with a valid combination.

Invalid or Expired Invitation

INVITATION_INVALID — HTTP 400 The invitation token is invalid, has already been used, or has expired. Resolution: Request a new invitation from your organization administrator.

Invitation Addressed to a Different Email

INVITATION_EMAIL_MISMATCH — HTTP 403 This invitation was sent to a different email address than the signed-in account. Resolution: Sign in with the email the invitation was sent to, or ask an admin to re-send it to your address.

Invitation Resend Rate Limited

INVITATION_RESEND_RATE_LIMITED — HTTP 429 This invitation was re-sent too recently. Resends are throttled per invitation with a short Redis cooldown so the invitee isn’t email-bombed by a double-clicked button or a repeated admin action. Resolution: Wait for the value in the Retry-After response header (also in the retryAfterSeconds body field) before resending.

Rate Alert Not Found

RATE_ALERT_NOT_FOUND — HTTP 404 No rate alert exists with the specified ID. Resolution: Check the alert ID and try again.

Invalid Address Format

INVALID_ADDRESS_FORMAT — HTTP 400 The provided blockchain address does not match the expected format for the specified chain. Resolution: Verify the address is a valid address for the specified chain and retry.

Registered Address Suspended

REGISTERED_ADDRESS_SUSPENDED — HTTP 409 This address is currently suspended for the customer and cannot be re-registered. Resolution: Unsuspend the existing registration via the internal portal before re-registering.

Registered Address Invalid Status Transition

REGISTERED_ADDRESS_INVALID_TRANSITION — HTTP 409 The requested status transition is not allowed for the registered address in its current state. Resolution: Check the registered address’s current status before performing status-change operations.

Invalid Government ID Type

INVALID_GOVERNMENT_ID_TYPE — HTTP 400 The government ID type provided is not valid for the required TIN submission. Resolution: Use a supported government ID type for TIN submissions. Refer to the documentation for the list of supported types.

Invalid Phone Format

INVALID_PHONE_FORMAT — HTTP 400 The contact phone number is not in the required E.164 format (e.g., +14155551234). Resolution: Update the business record with a phone number in E.164 format and retry.

Payout Not Found

PAYOUT_NOT_FOUND — HTTP 404 No payout exists with the specified ID, or the payout belongs to a different organization. Resolution: Verify the payout ID is correct. Use the list payouts endpoint to find valid payout IDs for your organization.

Payout Not Awaiting Signature

PAYOUT_NOT_IN_AWAITING_SIGNATURE — HTTP 404 The payout is not currently parked at the signature-collection gate. Either the cosign quorum has already been resolved, or the payout never required one. Resolution: Read the payout state. Only payouts with an active non-custodial signing quorum accept stamps.

Payout Cannot Be Cancelled

PAYOUT_NOT_CANCELLABLE — HTTP 409 The payout cannot be cancelled. Either it is already in a terminal state (completed, failed, or cancelled; re-cancelling a cancelled payout returns 200 idempotently, every other terminal returns 409), or its on-chain broadcast has begun and the cancel path can no longer safely unwind it. Resolution: Read the payout to confirm its current state. If it is already terminal, no action is required. If broadcast has begun, wait for the payout to reach a terminal state and react to that.

Concurrent Cosign In Flight

CONCURRENT_COSIGN_IN_FLIGHT — HTTP 409 The source wallet already has a non-custodial payout awaiting user signature. Only one cosign activity per wallet per chain may be in flight at a time so that nonces stay consistent on the destination chain. Resolution: Wait for the prior payout from this wallet to reach a terminal state (signed and broadcast, declined, or timed out) before creating a new one. Retry with exponential backoff is safe.

Idempotency-Key header required

IDEMPOTENCY_KEY_REQUIRED — HTTP 400 This endpoint requires an Idempotency-Key header to prevent duplicate processing. Generate a unique key per logical request and resend the request. Resolution: Add an Idempotency-Key header with a UUID or other unique value scoped to the request.

Idempotency Key Conflict

IDEMPOTENCY_KEY_CONFLICT — HTTP 409 The idempotency key was previously used with a different request body. Idempotency keys are bound to the exact request shape — replays must match the original. Resolution: Use a fresh idempotency key for the new request, or replay the original request unchanged.

Idempotency body too deeply nested

IDEMPOTENCY_BODY_TOO_NESTED — HTTP 400 The request body exceeds the maximum nesting depth allowed by the idempotency fingerprint hasher. Deeply-nested arrays or objects are rejected as a malformed payload. Resolution: Flatten the request body to a reasonable nesting depth (no more than 64 levels). If you believe your payload is legitimately deeper, contact support.

Idempotency-Key header invalid

IDEMPOTENCY_KEY_INVALID — HTTP 400 The Idempotency-Key header value did not match the required shape (1-128 characters, letters / digits / underscore / dot / colon / hyphen). Resolution: Resend the request with an Idempotency-Key matching ^[A-Za-z0-9_.:-]{1,128}$ — for example, a UUID.

Idempotency Key Request In Progress

IDEMPOTENCY_KEY_REQUEST_IN_PROGRESS — HTTP 409 A request with this idempotency key is already being processed and has not yet completed. Concurrent requests with the same key are rejected to prevent duplicate execution. Resolution: Wait for the original request to complete, then retry the identical request to replay its result. Retry with exponential backoff is safe.

Insufficient Funds

INSUFFICIENT_FUNDS — HTTP 422 The customer’s available balance for the order’s source resource is below the requested amount plus fee. Resolution: Verify the customer’s available balance on the order’s source resource and retry with a smaller amount, or top up the source.

Travel Rule counterparty rejected

TRAVEL_RULE_REJECTED — HTTP 422 The counterparty VASP rejected the Travel Rule transfer before the on-chain broadcast. The payout did not broadcast and no funds were moved. Resolution: Confirm beneficiary details with the recipient. Submit a new payout once the underlying counterparty issue has been addressed.

User signature timeout

USER_SIGNATURE_TIMEOUT — HTTP 422 The customer did not approve the payout before the signing window expired. No funds were moved. Resolution: Submit a new payout when the customer is ready to sign.

User signature declined

USER_SIGNATURE_DECLINED — HTTP 422 The customer declined the payout from the approval page. No funds were moved. Resolution: Submit a new payout if the decline was unintentional.

Customer signature could not be accepted

USER_SIGNATURE_REJECTED_BY_PROVIDER — HTTP 422 The customer’s passkey approval could not be accepted. No funds were moved. Resolution: Submit a new payout. If the same customer or wallet hits this repeatedly, contact support.

Signer roster changed

ROSTER_CHANGED — HTTP 422 A signer was removed (or moved out of the signing pool) while their stamp was on this in-flight payout. No funds were moved. Resolution: Re-initiate the payout; the new attempt collects approvals from the current roster.

On-chain broadcast failed

CHAIN_BROADCAST_FAILED — HTTP 422 The payout could not be signed or broadcast to the blockchain before reaching finality. No funds left the wallet. Resolution: Submit a new payout. If the same wallet hits this repeatedly, contact support.

Crypto wallet misconfigured

CRYPTO_WALLET_MISCONFIGURED — HTTP 422 The wallet’s configuration prevents Conduit from moving funds from it. No funds were moved. Resolution: Conduit is investigating automatically. Contact support if the wallet is needed for a time-sensitive payout.

Transaction held for compliance review

COMPLIANCE_HOLD — HTTP 422 This transaction is held pending a regulatory compliance review and could not be completed. The transaction’s funds are held, not returned, pending the review. Resolution: Contact support. This cannot be retried without a compliance review.

Transaction declined — compliance review required

AML_REJECTED — HTTP 422 This transaction could not be completed due to a regulatory compliance review. No funds were moved. Resolution: Contact support. This transaction cannot be retried without a compliance review.

Payout rejected in compliance review

COMPLIANCE_REJECTED — HTTP 422 A compliance reviewer rejected the payout’s supporting documentation. No funds were moved; the reserved amount was returned to the available balance. Resolution: Upload an acceptable supporting document via POST /v2/documents and submit a new payout with a fresh idempotency key. The transaction.rejected event lists the accepted document types.

Returned by sender

RETURNED_BY_SENDER — HTTP 422 The inbound transfer was returned by the sender’s institution, or compliance marked the deposit as returned before credit. The deposit was not credited. Resolution: Contact the sender’s bank or Conduit support for the return reason. The customer can attempt the transfer again from the source after the issue is resolved.

Payment rail rejected the transaction

RAIL_POLICY_REJECTED — HTTP 422 The payment rail’s policy rejected the transaction (for example, amount limit, frequency cap, or recipient restriction). Resolution: Adjust the amount, recipient, or wait period and submit a new transaction. Contact support if the cause is unclear.

Insufficient funds at settlement

INSUFFICIENT_FUNDS_AT_SETTLE — HTTP 422 Funds were available at reservation but not at settlement. No money was moved. Resolution: Top up the funding source and submit a new transaction.

Payment rail unavailable

RAIL_UNAVAILABLE — HTTP 503 No viable payment rail was available for the requested corridor. No funds were moved. Resolution: Retry later. If the corridor is persistently unavailable, contact support.

Sender information deadline expired

SENDER_INFO_TIMEOUT — HTTP 422 The sender-information gate timed out before the required Travel Rule details were provided. The deposit could not be completed. Resolution: Submit the deposit again with the sender details included up front.

Sandbox Not Provisioned

SANDBOX_NOT_PROVISIONED — HTTP 409 The API key is valid, but the sandbox organization it belongs to has not been provisioned yet. Sandbox access is provisioned from the live organization shortly after sign-up; this state means that provisioning has not completed (or previously failed). The key itself does not need to be rotated. Resolution: Wait a few moments and retry — provisioning is retried automatically. If the error persists, contact support to re-provision your sandbox environment.

KYC Inquiry Not Found

KYC_INQUIRY_NOT_FOUND — HTTP 404 No KYC inquiry id is persisted for the requested application + person index. Either the application did not spawn a KYC inquiry (e.g. mock sandbox path, kybRelianceEnabled=true), or the inquiry.created webhook from the KYC provider has not yet enriched the field verification row with the native inquiry id. Resolution: Wait a few seconds for the inquiry.created webhook to land, then retry. If the application was created in sandbox mode or with KYB reliance, no KYC inquiry exists for it. KYC_INQUIRY_LINK_UNAVAILABLE — HTTP 409 The KYC provider refused to generate a new one-time link for the inquiry, typically because the inquiry has expired, has already been completed, or has been resolved (approved/declined). This is a permanent state for that inquiry. Resolution: Check the inquiry status with the KYC provider. If the inquiry is expired or completed, no further hosted-flow link can be issued; start a new inquiry if a re-share is still needed.

KYC Upstream Unavailable

KYC_UPSTREAM_UNAVAILABLE — HTTP 502 The KYC provider returned a server error or the request did not reach it at all (network failure, timeout). The inquiry itself is fine; the provider just couldn’t be contacted right now. Resolution: Retry the request after a brief delay. If the failure persists, check the KYC provider’s status page before assuming the inquiry is broken. KYC_INQUIRY_LINK_RATE_LIMITED — HTTP 429 A regenerate-link request is already in flight for this UBO. The endpoint serialises requests per UBO with a short Redis lock so the KYC provider isn’t hammered with duplicate one-time-link requests from a double-click or a stuck retry. Resolution: Wait for the value in the Retry-After response header (also in the retryAfterSeconds body field) before retrying.

Verified Individual Cannot Be Edited

VERIFIED_INDIVIDUAL_LOCKED — HTTP 409 An individual whose identity verification has cleared cannot have their identity fields (firstName, lastName, email) changed in place — the verification was tied to those specific values. Organizational fields (roles, ownership percent, shares allocated) remain editable, and the individual can still be removed entirely. Resolution: Remove the individual from the application and add them again to change their identity, then have them complete identity verification under the new identity. Roles and ownership percent can be edited without removing the individual.

KYC Override Must Go Through the Field-Path Endpoint

KYC_OVERRIDE_VIA_FIELD_PATH_REQUIRED — HTTP 409 Operator overrides for an individual’s identity (KYC) compliance check are gated through the per-individual field-override path, not the compliance-check override endpoint. The blocker derivation explicitly excludes KYC compliance-check rows; writing the override on the compliance-check row would clear nothing. Resolution: Issue the override via PATCH /v2/internal/applications/:id/review with the individual’s ownership.persons.{i}.governmentIdNumber field path and verdict: APPROVED.

Whitelist Recipient Not Found

WHITELIST_RECIPIENT_NOT_FOUND — HTTP 404 No whitelist recipient with this id exists for your organization. Resolution: Check the id; list entries via GET /v2/customers//whitelist-recipients.

Invalid Whitelist Transition

WHITELIST_INVALID_TRANSITION — HTTP 409 The whitelist entry is not in a status that allows this action. Resolution: Fetch the entry to inspect its current status.

Whitelist Recipient Conflict

WHITELIST_RECIPIENT_CONFLICT — HTTP 409 An active whitelist entry already exists for these bank details with different attributes. Resolution: Fetch the existing entry; revoke it first if you need to change attributes, or resubmit with identical details.

Documentation Required

DOCUMENTATION_REQUIRED — HTTP 422 This payout purpose requires a supporting document and none was attached. Resolution: Upload a document via POST /v2/documents with purpose=transaction_support, attach its id in documents, and resubmit with a new idempotency key. acceptedDocumentTypes lists the kinds of evidence that satisfy review — any supported upload type is accepted at submission.

Recipient Not Whitelisted

RECIPIENT_NOT_WHITELISTED — HTTP 422 purpose=INTERCOMPANY requires the recipient to be a REGISTERED intercompany whitelist entry for this customer. Resolution: For bank recipients, register via POST /v2/customers//whitelist-recipients and wait for the whitelist_recipient.registered webhook. For crypto destinations, register the wallet address via POST /v2/customers//wallets/registered-addresses (synchronous). Then resubmit with a new idempotency key.

Transaction Blocked

TRANSACTION_BLOCKED — HTTP 422 The transaction is blocked by policy. This decision is terminal. Resolution: This transaction cannot be processed. Contact support if you believe this is an error.