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.
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, DUPLICATE_CLIENT_REFERENCE_ID, 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 compliance_review_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:
  • 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.

Sandbox simulate endpoint errors

These codes are returned as HTTP errors by sandbox simulate endpoints. They are not failureCode values on transactions. 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.

API key not allowed from this IP

API_KEY_IP_NOT_ALLOWED — HTTP 403 The request came from an IP address that is not in this API key’s allowlist. Resolution: Add this IP to the key’s allowlist in the dashboard, or call from an allowed network.

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.

Step-Up Verification Required

STEP_UP_REQUIRED — HTTP 403 This action requires fresh multi-factor (step-up) verification before it can proceed. Resolution: Complete the multi-factor verification prompt and retry the request.

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.

Signer Session Invalid

SIGNER_SESSION_INVALID — HTTP 401 The signer session token is missing, malformed, has a bad signature, or has expired. Resolution: Re-authenticate with your passkey to obtain a fresh signer session token, then retry with it in the Authorization: Bearer header.

Signer Authentication Failed

SIGNER_AUTH_FAILED — HTTP 401 Passkey authentication failed: the stamp could not be verified, the sub-organization did not match, or no active signer was found for the verified identity. Resolution: Re-authenticate with your passkey against the correct sub-organization and retry.

Signature Rejected

SIGNATURE_REJECTED — HTTP 422 The signing provider rejected the stamped request. The signer is authenticated, but the signature itself could not be applied: the assertion may target the wrong sub-organization, the activity may have already completed or expired, or a policy denied the vote. Resolution: Do not re-authenticate — the session is still valid. Contact support and include the correlationId from the error response so we can investigate the underlying rejection.

Signing Provider Unavailable

SIGNING_PROVIDER_UNAVAILABLE — HTTP 502 The signing provider returned a transient upstream error (network failure, timeout, rate limit, or 5xx) rather than a definitive verdict on the stamped request. The signer is authenticated and the request itself is fine — the provider just couldn’t be reached right now. Resolution: Retry the request after a brief delay. Do not re-authenticate — the session is still valid.

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.

Duplicate Client Reference ID

DUPLICATE_CLIENT_REFERENCE_ID — HTTP 409 A resource with this client_reference_id already exists for your organization. A client_reference_id must be unique per resource type within your organization. Resolution: Use a different client_reference_id, or fetch the existing resource by that reference. To retry the same request idempotently, reuse the idempotency-key header instead of changing the client_reference_id.

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.

Policy Evaluation Unavailable

POLICY_EVALUATION_UNAVAILABLE — HTTP 503 The documentation policy could not be evaluated because a policy lookup did not complete. No transaction was created. Resolution: Retry the request using exponential backoff. If the error persists, contact support.

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.

Individual Not Found

INDIVIDUAL_NOT_FOUND — HTTP 404 No individual exists with the specified ID for this customer, or the customer belongs to a different organization. Resolution: Verify both the customer ID and individual ID are correct, and that the individual belongs to that customer.

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 Person Not Found

APPLICATION_PERSON_NOT_FOUND — HTTP 404 No ownership person with the specified reference ID exists on this application. Resolution: Verify the person reference ID from the application detail response.

Application Person Field Empty

APPLICATION_PERSON_FIELD_EMPTY — HTTP 404 The ownership person exists but the requested tier-2 field has no submitted value — e.g. a non-US person carries no tax identifier. Resolution: This is expected when the field does not apply to the person (a non-US person has no US TIN). No value can be revealed.

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.

Application Country Not Supported

APPLICATION_COUNTRY_NOT_SUPPORTED — HTTP 409 The application cannot be approved because a country it carries — the registered jurisdiction, or a person’s country — is either not a recognizable ISO 3166-1 code or not a jurisdiction Conduit supports, so a customer could not be created from it. Resolution: Correct the offending country on the application and retry the decision.

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, purpose, documents?, recipient }); ONRAMP orders require a crypto autoPayout ({ purpose, documents?, recipient: { rail: 'crypto', chain, address, attestation } }), self- or third-party-custody. purpose is required and drives the documentation / whitelist gate; documents are supporting-document ids. recipient.chain must match the destination wallet’s chain. 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, recipient.chain must match the destination wallet’s chain.

Non-Custodial Source Not Supported

NON_CUSTODIAL_SOURCE_NOT_SUPPORTED — HTTP 422 Non-custodial source wallets are supported on EVM chains only. On non-EVM chains (Tron, Solana, Stellar, Bitcoin) the order is rejected at creation. Resolution: Use a custodial wallet as the source on non-EVM chains, or a non-custodial wallet on an EVM 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

Rate Unavailable (After Hours)

RATE_UNAVAILABLE_AFTER_HOURS — HTTP 503 The market for this currency pair is currently closed and no prior open-market rate is available to freeze, so a quote cannot be produced. Resolution: Retry once the market reopens. If the error persists during open hours, the rate provider for this currency pair may be experiencing an outage. Runbook: Rate Unavailable (After Hours)

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 be used at this time (e.g. a frozen non-custodial wallet cannot initiate a payout). Resolution: Check the wallet’s current status. Only ACTIVE wallets can receive deposits or initiate payouts; a frozen wallet must be cleared by Conduit before it can move funds again.

Wallet Rotation Blocked: Balance Above Dust

WALLET_ROTATION_BLOCKED_BALANCE — HTTP 422 The wallet holds a balance (available, pending, or frozen) above the asset’s dust floor and cannot be rotated. Rotation would strand those funds on the retired wallet record. A leftover at or below the dust floor does not block rotation — it is too small to be worth a transfer, so nothing will ever move it. Resolution: Move the 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.

No eligible banking provider

NO_ELIGIBLE_PROVIDER — HTTP 422 No banking provider is currently available to service a virtual account for this customer. Every provider that could serve the customer’s country and industry is either restricted or has been taken offline. Resolution: The customer cannot be provisioned a virtual account until a banking provider becomes available for their jurisdiction. This is an operational availability limit, not a fixable request error.

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 Account Not Provisioned

WALLET_NO_PROVIDER_ACCOUNT — HTTP 422 The customer does not yet have a wallet account on the underlying provider. Wallet addresses cannot be created until the customer claims non-custodial control. Resolution: Submit a non-custodial claim via POST /v2/customers/:id/wallets/claim-non-custodial to provision the wallet account, then retry creating the wallet.

Wallet Custody Not Claimed

WALLET_CUSTODY_NOT_CLAIMED — HTTP 409 The customer’s wallet account is custodial, but custodial wallets are not enabled for this organization. Wallet addresses cannot be issued on a custodial account unless the custodial wallet path is enabled, and a custodial account cannot be claimed as non-custodial. Resolution: If your organization should hold custody, contact your Conduit representative to enable the custodial wallet path; wallet creation then works directly. A custodial account cannot be converted to non-custodial via claim-non-custodial. If custodial wallets are intentionally disabled, this 409 is the expected gate.

Deposit Address Unavailable

DEPOSIT_ADDRESS_UNAVAILABLE — HTTP 409 A funding address for this customer is still being provisioned, so the order could not be given one. Nothing was created and no funds were moved. Resolution: Retry the same request shortly. Provisioning is a one-off per customer and chain, so a retry after a moment succeeds.

Wallet Provisioning Rejected

WALLET_PROVISIONING_REJECTED — HTTP 422 The custody provider rejected the wallet creation; no wallet was created and no funds were moved. Resolution: Retry with a new idempotency key. If the rejection persists, contact support.

Wallet Awaiting Admin Approval

WALLET_AWAITING_ADMIN_APPROVAL — HTTP 409 This wallet is being provisioned through a ceremony that is awaiting admin approval. Resolution: Wait for an admin to approve the ceremony, then check the wallet status again.

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.

Transaction Not Awaiting Signature

TRANSACTION_NOT_AWAITING_SIGNATURE — HTTP 409 The transaction has not reached signature collection, so there is no signing link to return. Non-custodial payouts are minted a signing link only after they clear compliance and document review; that link is delivered on the passkey_required variant of the transaction.awaiting_signature webhook, never by minting one through this endpoint. Resolution: Do not create a transaction_approval verification for a payout yourself. Wait for the transaction.awaiting_signature webhook and route your signers to the verificationUrl it carries (passkey_required mode). Re-fetch the payout to confirm it is still awaiting signature. SIGNING_LINK_NOT_HUMAN_SIGNABLE — HTTP 409 This payout’s wallet signs in a programmatic mode and its roster is machine-only — no human signer can approve it, so there is no verification link to return. The signing handle is delivered as a signingRequestId on the transaction.awaiting_signature webhook, and your machine integration approves or rejects it through the signing-requests API. A programmatic wallet that has an active passkey signer DOES return the human link here (that signer may approve on the verify page); this error means the roster carries no such signer. Resolution: Read the signingRequestId from the transaction.awaiting_signature webhook, fetch details with GET /v2/signing-requests/{id}, then approve via POST /v2/signing-requests/{id}/approve or reject via POST /v2/signing-requests/{id}/reject. If you expected a human signer to approve this payout, add an active passkey signer to the wallet’s roster.

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 API accepts one submission per deposit; later submissions are rejected. Resolution: Double-check the originator details before submitting — the API accepts only one submission per deposit. If the recorded information was incorrect, contact Conduit to have it corrected while the deposit is still under review.

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.

Prefunding Source Must Be a House Account

PREFUNDING_SOURCE_NOT_HOUSE_ACCOUNT — HTTP 422 A prefunding transaction must originate from a Conduit house account. The source account for this request is not marked as a house account. Resolution: Send prefunding transactions only from an account marked as a house account, or remove the prefunding purpose.

Prefunding Destination Not Found

PREFUNDING_DESTINATION_NOT_FOUND — HTTP 422 The destination account specified for this prefunding transaction could not be found. Resolution: Verify the destination account identifier and retry.

Prefunding Match Is Ambiguous

PREFUNDING_AMBIGUOUS_MATCH — HTTP 422 More than one account matches the details given for this prefunding transaction, so Conduit cannot determine a single destination. Resolution: Provide additional identifying details to narrow the match to a single account.

Prefunding Rail Not Supported

PREFUNDING_UNSUPPORTED_RAIL — HTTP 422 Prefunding is not supported over the rail requested for this transaction. Resolution: Use a supported rail for prefunding transactions, or remove the prefunding purpose.

Order has no funding address to deposit to

SANDBOX_ORDER_NOT_DEPOSIT_FUNDED — HTTP 409 The order names its own funding source, so it publishes no Conduit-managed funding address. Only a deposit-funded order has one to deposit to. Resolution: Fund the named source directly, or create the order without a source so it returns a funding address in depositInstructions.

Order has no funding transfer awaiting a compliance decision

SANDBOX_ORDER_NO_PARKED_FUNDING — HTTP 404 No transfer into this order’s funding address is currently held for compliance review. It may not have landed yet, it may have cleared on its own, or it may already have reached a terminal state. Resolution: Fund the order with a scenario that holds the transfer for review, then retry. Poll the order until it stops reporting this before counting the decision as applied.

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.

Claim Not Found

CLAIM_NOT_FOUND — HTTP 404 No non-custodial claim exists with the specified ID for this customer. Resolution: Verify the claimId returned by POST /v2/customers/:id/wallets/claim-non-custodial and that it belongs to this customer.

Signer Not Enrollable

SIGNER_NOT_ENROLLABLE — HTTP 409 The signer is not in a state that admits enrollment, so there is no invite to reissue (it is already active, being removed, removed, or errored). Resolution: Only signers still completing enrollment (pending activation or activating) can have an invite reissued. Check the signer status via GET /v2/customers/:id/wallet-signers.

Signer Pending Admin Approval

SIGNER_PENDING_ADMIN_APPROVAL — HTTP 409 The signer has enrolled a passkey on a live roster and is now parked for a customer admin’s co-stamp — the blocker is an admin approval, not a lost enrollment invite. Reissuing the signer invite would send the wrong link. Resolution: Recover the admin approval link with POST /v2/customers/:customerId/wallet-signers/:signerId/reissue-admin-approval, and route it to an admin. Do not reissue the signer invite.

No Pending Admin Approval

SIGNER_NO_PENDING_ADMIN_APPROVAL — HTTP 409 The signer has no live admin-approval awaiting a co-stamp, so there is no admin link to recover. Resolution: This endpoint recovers the admin link only while a passkey add is parked for approval. Check the signer status via GET /v2/customers/:customerId/wallet-signers.

Verification Type Not Reissuable Here

VERIFICATION_TYPE_NOT_REISSUABLE — HTTP 422 This verification type cannot be initiated through the generic verifications route because it requires per-type context the route cannot supply. Resolution: Use the dedicated endpoint for this verification type. For wallet signer invites, POST /v2/customers/:customerId/wallet-signers/:signerId/reissue-invite.

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: Claim the wallet as non-custodial via POST /v2/customers/:id/wallets/claim-non-custodial 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 Supported in This Context

API_KEY_CREDENTIAL_NOT_SUPPORTED — HTTP 422 The request includes a machine signer (credentialType: api_key) in a context where api_key signers cannot be enrolled. This is reserved for future compatibility and should not be seen in normal operation. Resolution: Use credentialType: passkey for this context, or include the api_key member in the claim-non-custodial roster instead.

Signing request not found

SIGNING_REQUEST_NOT_FOUND — HTTP 404 No signing request with this id exists for your account. The same response is returned for an id that belongs to another account, so a 404 never confirms that an id exists elsewhere. Resolution: List your actionable signing requests with GET /v2/signing-requests and use an id from that list. The transaction.awaiting_signature webhook also delivers the id directly as signingRequestId (programmatic mode).

Signing stamp was not attributed to the resolved signer

SIGNING_STAMP_ATTRIBUTION_MISMATCH — HTTP 422 The stamp verified locally and resolved to one of your machine signers, but the signing provider did not record a vote for that signer — the vote was attributed elsewhere or not recorded. Conduit fails closed rather than counting a vote toward quorum that it cannot attribute to the signer you submitted. Resolution: Re-fetch the signing request with GET /v2/signing-requests/{id} and resubmit with the machine signer whose public key is registered on this wallet’s roster. If it recurs, the signer’s provider registration may be out of sync — contact Conduit.

Signing stamp is invalid

SIGNING_STAMP_INVALID — HTTP 422 The submitted stamp could not be verified: it is not a well-formed P-256 stamp, its signature does not match the signed body, or the signed body does not authorize this exact signing request (its activity fingerprint, sub-organization, or request type does not match). Resolution: Re-fetch the signing request’s approval material with GET /v2/signing-requests/{id}, rebuild the approve/reject activity body exactly as returned, and stamp it with your machine signer’s P-256 api key. Guide: Programmatic payout signing

Signing stamp does not match an active machine signer

SIGNING_STAMP_SIGNER_UNKNOWN — HTTP 422 The stamp’s public key does not resolve to an ACTIVE machine (api_key) signer on the wallet’s roster. The signature verified, but the key is not one of this account’s provisioned api-key signers. Resolution: Stamp with the P-256 key you registered for an active api_key signer on this account’s roster, or add the signer to the roster before approving. Guide: Programmatic payout signing

Wallet is not configured for programmatic signing

SIGNING_MODE_NOT_PROGRAMMATIC — HTTP 409 This wallet’s signing mode requires human passkey approval, so machine (api-key) stamps are not accepted. The signing-requests API only serves accounts whose signing mode is programmatic or programmatic_unattended. Resolution: Have Conduit enable a programmatic signing mode for this customer, or approve the payout with a passkey on the Conduit-hosted verification page. Guide: Programmatic payout signing

Not enough machine signers to reach the signing threshold

PROGRAMMATIC_QUORUM_UNREACHABLE — HTTP 422 A programmatic (machine-key) roster must contain at least signingThreshold api_key signers so the customer’s backend can reach the signing quorum on its own. This roster has fewer api_key signers than the threshold. Resolution: Add api_key signers until their count is at least signingThreshold, or lower signingThreshold to at most the number of api_key signers. Guide: Programmatic payout signing

Verification method not supported for this verification type

VERIFICATION_METHOD_NOT_SUPPORTED_FOR_TYPE — HTTP 422 The supplied verification method cannot complete this verification type. A machine api-key (API_KEY) is an approval-relay credential only: it signs transaction and ceremony approvals, and is never used to enroll a signer or complete an identity verification. Resolution: Use the method the verification type expects — a passkey (or Google OAuth) for signer enrollment / identity, and API_KEY only to approve a transaction or ceremony.

Signer approved with a credential that does not match their enrolled type

SIGNER_CREDENTIAL_SCHEME_NOT_ADMISSIBLE — HTTP 422 A counted signer’s approval was stamped with a credential type that does not match the credential that signer is enrolled with: a passkey signer must stamp with their passkey, and a machine (api-key) signer must stamp with its P-256 api key. Substituting one for the other is rejected, as is any credential the wallet’s signing mode does not permit at all — passkey-required wallets accept only passkey approvals, and no credential other than an enrolled passkey or provisioned machine api-key is ever admissible. Resolution: Re-stamp the approval with the exact credential that signer is enrolled with — the enrolled passkey for a passkey signer, or the provisioned machine api-key for a machine signer — and make sure that credential type is allowed by the wallet’s signing mode.

API Key Public Key Required

API_KEY_PUBLIC_KEY_REQUIRED — HTTP 400 credentialType=api_key requires a publicKey (a P-256 compressed public key in hex). Resolution: Include publicKey in the request body when credentialType is api_key.

API Key Public Key Invalid

API_KEY_PUBLIC_KEY_INVALID — HTTP 400 The provided publicKey is not a valid P-256 compressed public key. Expected 66 hex characters (33 bytes) with a 02 or 03 prefix. Resolution: Provide a valid P-256 compressed public key: 66 hex characters starting with 02 or 03.

Duplicate API Key Public Key

API_KEY_PUBLIC_KEY_DUPLICATE — HTTP 422 Two api_key (machine) roster members were submitted with the same publicKey. Each machine signer must have a distinct P-256 public key. Resolution: Give each api_key signer its own unique public key, or remove the duplicate roster entry.

API Key Public Key Already In Use

API_KEY_PUBLIC_KEY_IN_USE — HTTP 409 The publicKey on this add-signer request is already held by another active api_key signer on the customer’s roster. Each machine signer must have a distinct P-256 public key. Resolution: Add the signer with a public key that is not already registered on the roster.

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.

Claim Resume Roster Mismatch

CLAIM_RESUME_ROSTER_MISMATCH — HTTP 409 A stranded claim can be retried, but only with the same roster, signing threshold, and chains it was originally submitted with. This retry differs from what was committed, so it was refused — resuming with a different roster would register signers the wallet provider never provisioned. Resolution: Retry with the exact roster, signingThreshold, and chains from the original claim. If they need to change, contact support to reset the claim before submitting a new one.

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; an existing custodial wallet cannot be claimed as non-custodial. Resolution: Custodial wallets are operated by Conduit on the customer’s behalf; no signer roster applies. Claim non-custodial control only for customers that do not already have a custodial wallet.

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 a passkey-credential signer to have at least 2 registered passkeys so they cannot lose admin access by losing a single device. Machine (api_key) admins do not need passkeys and are exempt (allowed only in the fully-automated signing mode). Resolution: Have the passkey signer register a second passkey from a different device, then retry the promotion.

Passkey Attach Pending Admin Approval

PASSKEY_ATTACH_PENDING_ADMIN_APPROVAL — HTTP 409 The provider parked the passkey attach at CONSENSUS_NEEDED (post-activation policy). An admin has been notified and must approve the attach before the passkey becomes usable. Resolution: Wait for the admin to approve the pending request; retry the attach if the approval is declined or expires.

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. Because the root quorum runs at fixed capacity, a bare promote-then-demote sequence does not work: promoting a replacement admin also needs to unseat someone, so the swap has to happen in one ceremony. Resolution: Call the promote endpoint on the replacement signer with demoteSignerId set to this signer to swap them in one ceremony, instead of demoting standalone.

Root Quorum At Capacity

ROOT_AT_CAPACITY_SWAP_REQUIRED — HTTP 409 The root quorum already holds its full set of customer admin seats, so a new admin can only be seated by unseating an existing one. Promotion to root requires selecting the current root admin to demote in the same ceremony. Resolution: Retry the promotion with a demoteSignerId naming the current root admin to unseat.

Demote Target Not In Root Quorum

DEMOTE_TARGET_NOT_IN_ROOT — HTTP 409 The signer named to be unseated in the swap is not currently a member of the root quorum, so there is no root seat to free. Resolution: Choose a demoteSignerId that is a current root-quorum admin (see the customer’s root roster).

Swap Would Break Minimum Admins

SWAP_WOULD_BREAK_F12 — HTTP 409 The requested seat swap would leave fewer than 2 admins on the roster, violating the minimum-admin invariant that keeps both the root path and recovery satisfiable. Resolution: Add or promote another admin so the roster keeps at least 2 admins after the swap, then retry.

Roster Threshold Exceeded

ROSTER_THRESHOLD_EXCEEDED — HTTP 400 The signing threshold exceeds the number of active signers. Removing a signer would make the quorum unsatisfiable. Resolution: Lower the signing threshold or add more signers before removing this one.

Signer Is Last Admin

SIGNER_IS_LAST_ADMIN — HTTP 409 This is the last admin on the roster. At least one admin must remain for governance. Resolution: Promote another signer to admin before removing or demoting this one.

Role Requires Admin Approval

ROLE_REQUIRES_ADMIN_APPROVAL — HTTP 403 This roster change requires approval from an admin. The request was submitted but is pending admin sign-off. Resolution: Ask an admin signer to approve the pending ceremony.

Ceremony In Flight

CEREMONY_IN_FLIGHT — HTTP 409 A ceremony for this account is already in progress and the request would duplicate it. This happens for a signer roster change (a concurrent promote or demote of the same signer), or for a wallet create when a wallet for the same account is already being created (for example, requesting a second EVM chain while the first EVM chain’s wallet is still being set up — the EVM chains share one address). The request is rejected until the in-flight ceremony finishes. Resolution: Wait for the in-flight ceremony to finish, then retry. For a roster change, the wallet_signer.promoted / wallet_signer.demoted webhook signals completion; for a wallet create, the wallet.created webhook signals the wallet is ready.

Signer Enrollment Not Enabled

SIGNER_ENROLLMENT_NOT_ENABLED — HTTP 409 Adding this passkey needs a customer admin’s co-stamp, and that capability is temporarily unavailable. The request is rejected transiently. Resolution: Retry shortly. The condition clears on its own.

Provider Account Not Found

PROVIDER_ACCOUNT_NOT_FOUND — HTTP 404 No provider account exists for the specified customer for the requested operation. Reset-claim reports it when there is no wallet account to reset; signing-quorum and recovery operations report it when the customer has no non-custodial provider account. Resolution: Confirm the customer has an active wallet account before retrying. Signing-quorum and recovery operations require a non-custodial account specifically.

Claim Reset Blocked by Referencing Rows

CLAIM_RESET_BLOCKED — HTTP 409 The reset-claim endpoint cannot wipe the customer’s wallet setup while transactions, deposits, or pending signature approvals still reference the wallets or signers. Hard-deleting them would FK-violate. Resolution: Resolve any pending signature approvals first. Transactions and deposits permanently reference the wallet (their rows are never removed), so a customer that already has transaction or deposit history cannot be reset.

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.

Wallet Threshold Change Already Pending

WALLET_THRESHOLD_CHANGE_PENDING — HTTP 409 A signing-quorum threshold change ceremony is already in progress for this provider account. Concurrent threshold changes are rejected until the in-flight ceremony completes or fails. Resolution: Wait for the in-flight ceremony to terminate, then retry.

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 CEREMONY_APPROVAL 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, or a submitted value is not one of the accepted options for a closed-set field (e.g. a country-specific field like companyClassification.legalStructure). Each blocker is reported per field in errors[] with a category and, for closed-set fields, the accepted allowedValues. Resolution: Use the onboarding requirements endpoint to check which fields and documents are required and which values each field accepts, then submit valid values 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 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 Declined

REGISTERED_ADDRESS_COMPLIANCE_REJECTED — HTTP 409 This address could not be registered for the customer following compliance screening. Resolution: This address was declined in accordance with our standard compliance and risk management protocols. Contact support if you believe this is in error.

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 Tax ID Type

INVALID_TAX_ID_TYPE — HTTP 400 The tax ID type provided is not valid for the required TIN submission. Resolution: Use a supported tax 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.

Not Awaiting Signature

NOT_IN_AWAITING_SIGNATURE — HTTP 404 The payout — or the order’s source transfer — is not currently parked at the signature-collection gate. Either the signing quorum has already been resolved, or this transfer never required signatures. Resolution: Read the payout or order state. Only a non-custodial transfer with an active signing quorum accepts 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.

Payout Queue Full

PAYOUT_QUEUE_FULL — HTTP 422 This wallet and chain already has the maximum number of payouts waiting to collect signatures. Only one payout collects signatures at a time per wallet and chain; the rest wait in line. Resolution: Wait for an in-flight payout on this wallet and chain to finish signing, then retry. The cap is configurable by Conduit.

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 payout waited too long in the wallet’s signing queue (behind other in-flight payouts on the same wallet) and timed out before it could start collecting signatures. No funds were moved. Resolution: Submit a new payout once the wallet’s earlier payouts have finished signing.

User signature expired

USER_SIGNATURE_EXPIRED — HTTP 422 The customer did not approve the payout across the allowed signing windows (the request is re-offered with a fresh link each time and only fails after the final window), so the request 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.

Crypto wallet feature not approved

CRYPTO_FEATURE_NOT_APPROVED — HTTP 422 Non-custodial control can only be claimed after the customer’s CRYPTO_WALLET feature application has been approved. Either no feature application exists yet, or it is still pending review. Resolution: Submit POST /v2/customers/:id/features { type: crypto_wallet } and wait for the application to reach status: approved before retrying. In sandbox the default is auto-approve; in live the application may need ops review unless the org has opted out of the review gate.

Roster does not match the customer’s signing mode

SIGNING_MODE_ROSTER_INVALID — HTTP 422 The submitted signer roster is not valid for this customer’s configured signing mode. In PASSKEY_REQUIRED mode all signers must be passkeys; in PROGRAMMATIC mode machine (api_key) signers must have role=signer and governance admins must be passkeys. Resolution: Adjust the roster to the customer’s signing mode, or ask your Conduit representative to change the mode. To use machine signers at all, the customer must be in PROGRAMMATIC or PROGRAMMATIC_UNATTENDED; machine admins require PROGRAMMATIC_UNATTENDED. Guide: Programmatic payout signing

Crypto not available in this jurisdiction

CRYPTO_NOT_AVAILABLE_IN_JURISDICTION — HTTP 422 Crypto wallet provisioning is not available for customers in this jurisdiction. The customer’s registered country is on Conduit’s restricted-country list for crypto products. Resolution: Crypto rails are not legally available in the customer’s country. KYB customers in this country may still use other rails (e.g., fiat virtual accounts) but cannot enable the CRYPTO_WALLET feature.

Crypto wallet operation requires approval

CRYPTO_WALLET_CONSENSUS_REQUIRED — HTTP 422 This wallet operation needs a customer admin’s approval before it can complete; it could not be finished synchronously. No funds were moved and no wallet was created. Resolution: Do not retry blindly — the operation only completes once a customer admin approves it. Complete the pending approval, then re-check the wallet state.

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

COMPLIANCE_REVIEW_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 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.

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/{customerId}/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/{customerId}/whitelist-recipients and wait for the whitelist_recipient.registered webhook. For crypto destinations, register the wallet address via POST /v2/customers/{customerId}/wallets/registered-addresses (synchronous). Then resubmit under the same 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.

Capability Suspended

CAPABILITY_SUSPENDED — HTTP 403 This account is currently restricted from initiating this type of money movement. Resolution: Contact support if you believe this is an error.

Ceremony Not Found

CEREMONY_NOT_FOUND — HTTP 404 No recovery ceremony matching the given ID was found. Resolution: Verify the ceremony ID.

Ceremony Not Cancellable

CEREMONY_NOT_CANCELLABLE — HTTP 409 The ceremony is not in a PENDING state and cannot be cancelled. Resolution: Only PENDING ceremonies can be cancelled.

Replacement Admin Not Enrolled

RECOVERY_REPLACEMENT_NOT_ENROLLED — HTTP 409 The replacement admin for an admin-recovery must have completed enrollment (be ACTIVE with a provider credential) before being seated into the root quorum. Resolution: Complete the replacement admin’s enrollment before initiating admin recovery.

RFI Not Found

RFI_NOT_FOUND — HTTP 404 No request-for-information exists with the specified ID, the RFI belongs to a different organization, or (on a client-facing surface) the RFI is still a draft and has never been published. Resolution: Verify the RFI ID is correct. Draft RFIs are never visible on client-facing surfaces — wait until the RFI is published.

RFI Not Open For Response

RFI_NOT_OPEN_FOR_RESPONSE — HTTP 409 A response can only be submitted while the RFI is open. This RFI is not open — the current round may already be answered, or the RFI has been resolved or cancelled. Resolution: Re-fetch the RFI to check its current status. If it is awaiting internal review (responded) or already closed, no further response can be submitted.

RFI Invalid Status Transition

RFI_INVALID_STATUS_TRANSITION — HTTP 409 The requested action cannot be performed from the RFI’s current status. Each RFI action (publish, request-more-info, resolve, cancel, patch) is only valid from a specific set of prior statuses. Resolution: Re-fetch the RFI to check its current status and refer to the documented lifecycle transitions before retrying.