For the complete documentation index, see llms.txt. This page is also available as Markdown.

Errors

Every error the API can return: the Problem Details envelope, how to handle it, and the full catalog of stable error codes.

Every non-2xx response — REST and GraphQL alike — speaks one error language. REST returns an RFC 9457 Problem Details object; GraphQL carries the same code vocabulary in errors[].extensions.code.

{
  "type": "https://docs.trustlesswork.com/trustless-work/v2-en/api-rest/errors/escrow-not-found",
  "title": "Not Found",
  "status": 404,
  "code": "ESCROW_NOT_FOUND",
  "detail": "Escrow does not exist.",
  "instance": "/escrow/single-release/v2/fund-escrow",
  "traceId": "d0f1…"
}

How to handle errors

  • Switch on code. It is stable and never renamed. detail is human prose and may change without notice.

  • type is a link to that code's page in this section.

  • extensions carries machine-readable context where it helps: extensions.errors[] on validation failures, extensions.restoreXdr on STELLAR_STATE_ARCHIVED, extensions.missing[] on ESCROW_RECEIVER_TRUSTLINE_MISSING, extensions.tokenContractId on token contract errors.

  • Include traceId when reporting a problem — it correlates your request with the server logs.

Escrow contract errors

Raised when the on-chain simulation of a build endpoint fails inside the escrow contract. They are grouped by the lifecycle phase where you will most likely hit them — note that a few codes can surface in more than one operation.

Deploy, update & configuration

Invalid roles, milestones or properties when deploying or updating an escrow.

Code
Status
Summary

ESCROW_ADMIN_ADDRESS_CANNOT_BE_CHANGED

422

Admin address cannot be changed after initialization.

ESCROW_ADMIN_ADDRESS_OVERLAPS_WITH_OTHER_ROLE

422

Admin address must not overlap with any other role.

ESCROW_ALREADY_INITIALIZED

409

Escrow is already initialized.

ESCROW_AMOUNT_CANNOT_BE_ZERO

422

Amount must be greater than zero.

ESCROW_APPROVERS_LIST_EMPTY

422

roles.approvers must contain at least one address.

ESCROW_DISPUTE_RESOLVERS_LIST_EMPTY

422

roles.dispute_resolvers must contain at least one address.

ESCROW_DISPUTE_RESOLVER_OVERLAPS_WITH_OTHER_ROLE

422

A dispute resolver cannot also appear in another role.

ESCROW_DUPLICATE_ADDRESS_IN_ROLE

422

A role list contains duplicate addresses.

ESCROW_FLAGS_MUST_BE_FALSE

422

Escrow flags (approved, disputed, released) must all be false for this action.

ESCROW_HAS_FUNDS

409

Escrow still holds funds; action blocked.

ESCROW_INCOMPATIBLE_WASM_HASH

422

Target contract is not an instance of the expected escrow type.

ESCROW_MILESTONE_APPROVED_CANT_CHANGE_PROPERTIES

409

Escrow properties cannot be modified after a milestone approval.

ESCROW_NO_MILESTONE_DEFINED

422

Escrow has no milestones defined.

ESCROW_PLATFORM_ADDRESS_CANNOT_BE_CHANGED

422

Platform address cannot be modified.

ESCROW_PLATFORM_FEE_TOO_HIGH

422

Platform fee cannot exceed 99%.

ESCROW_PROPERTIES_MISMATCH

409

Provided escrow properties do not match the on-chain state.

ESCROW_RELEASE_SIGNERS_LIST_EMPTY

422

roles.release_signers must contain at least one address.

ESCROW_ROLE_LIMIT_EXCEEDED

422

A role list exceeded its maximum size (5 addresses per list).

ESCROW_SERVICE_PROVIDERS_LIST_EMPTY

422

roles.service_providers must contain at least one address.

ESCROW_STRING_TOO_LONG

422

A String field exceeded its on-chain maximum length.

ESCROW_TARGET_CANNOT_BE_ZERO

422

A milestone approvals.target must be greater than zero.

ESCROW_TARGET_EXCEEDS_APPROVERS

422

A milestone approvals.target cannot exceed roles.approvers.length.

ESCROW_TOO_MANY_MILESTONES

422

Too many milestones; the maximum is 50.

ESCROW_TOTAL_AMOUNT_CANNOT_BE_ZERO

422

Total amount cannot be zero.

Funding

Code
Status
Summary

ESCROW_INSUFFICIENT_FUNDS_FOR_FUNDING

409

Insufficient funds to fund the escrow.

ESCROW_NOT_FUNDED

409

Escrow has not been funded yet.

Milestones & approvals

Changing milestone status, approving milestones, and managing the milestone list.

Code
Status
Summary

ESCROW_APPROVER_ALREADY_APPROVED_MILESTONE

409

This approver already approved this milestone.

ESCROW_BATCH_MILESTONE_APPROVE_EMPTY

422

approve_milestones batch cannot be empty.

ESCROW_BATCH_MILESTONE_UPDATE_EMPTY

422

change_milestone_status batch cannot be empty.

ESCROW_BATCH_TOO_LARGE

422

Milestone batch exceeded the maximum size of 50 entries.

ESCROW_DUPLICATE_MILESTONE_INDEX

422

Duplicate milestone indices are not allowed in the batch.

ESCROW_EMPTY_MILESTONE_STATUS

422

Milestone status cannot be empty.

ESCROW_INVALID_MILESTONE_INDEX

422

Milestone index is out of range.

ESCROW_MILESTONE_HAS_ALREADY_BEEN_APPROVED

409

Milestone was already approved.

ESCROW_MILESTONE_NOT_COMPLETED

409

Milestone is not completed; action cannot proceed.

ESCROW_MILESTONE_NOT_FOUND

404

Milestone does not exist.

ESCROW_MILESTONE_TO_APPROVE_DOES_NOT_EXIST

404

Milestone to approve does not exist.

ESCROW_MILESTONE_TO_UPDATE_DOES_NOT_EXIST

404

Milestone to update does not exist.

ESCROW_MILESTONE_UPDATE_NOT_ALLOWED_WITH_FUNDS

409

Milestones cannot be edited while the escrow holds funds.

Disputes & resolution

Opening disputes and distributing funds when resolving them.

Code
Status
Summary

ESCROW_ALREADY_IN_DISPUTE

409

Escrow is already in dispute.

ESCROW_ALREADY_RESOLVED

409

Escrow dispute is already resolved.

ESCROW_AMOUNTS_TO_TRANSFER_SHOULD_BE_POSITIVE

422

Transfer amounts must be positive.

ESCROW_APPROVER_OR_RECEIVER_FUNDS_LESS_THAN_ZERO

422

Approver or receiver funds cannot be negative.

ESCROW_BATCH_MILESTONE_DISPUTE_EMPTY

422

dispute_milestones requires at least one milestone index.

ESCROW_DISTRIBUTIONS_MUST_EQUAL_BALANCE

422

Distributions must equal the total escrow balance.

ESCROW_INSUFFICIENT_FUNDS_FOR_RESOLUTION

409

Insufficient funds to resolve the dispute.

ESCROW_MILESTONE_ALREADY_DISPUTED

409

Targeted milestone is already in dispute.

ESCROW_MILESTONE_ALREADY_IN_DISPUTE

409

Milestone is already in dispute.

ESCROW_MILESTONE_ALREADY_RESOLVED

409

Milestone dispute is already resolved.

ESCROW_MILESTONE_NOT_IN_DISPUTE

409

Milestone is not currently in dispute.

ESCROW_MILESTONE_OPENED_FOR_DISPUTE_RESOLUTION

409

Milestone is opened for dispute resolution; action blocked.

ESCROW_NOT_IN_DISPUTE

409

Escrow is not currently in dispute.

ESCROW_OPENED_FOR_DISPUTE_RESOLUTION

409

Escrow is opened for dispute resolution; action blocked.

ESCROW_RECEIVER_AND_APPROVER_FUNDS_NOT_EQUAL

422

Receiver and approver distributions do not match.

ESCROW_TOO_MANY_DISTRIBUTIONS

422

Too many distributions; the maximum is 50.

ESCROW_TOTAL_DISPUTE_FUNDS_MUST_NOT_EXCEED_MILESTONE_AMOUNT

422

Total dispute funds cannot exceed the milestone amount.

Release, withdraw & refunds

Code
Status
Summary

ESCROW_ALREADY_RELEASED

409

Escrow funds were already released.

ESCROW_BALANCE_NOT_ENOUGH_TO_SEND_EARNINGS

409

Escrow balance is insufficient to release the earnings.

ESCROW_CANT_RELEASE_A_MILESTONE_IN_DISPUTE

409

Cannot release a milestone that is in dispute.

ESCROW_INSUFFICIENT_APPROVER_FUNDS_FOR_COMMISSIONS

409

Approver has insufficient funds for commissions.

ESCROW_INSUFFICIENT_ESCROW_FUNDS_TO_MAKE_REFUND

409

Insufficient escrow funds to make the refund.

ESCROW_INSUFFICIENT_FUNDS_FOR_REFUND

409

Insufficient funds for refund.

ESCROW_INSUFFICIENT_SERVICE_PROVIDER_FUNDS_FOR_COMMISSIONS

409

Service provider has insufficient funds for commissions.

ESCROW_MILESTONE_ALREADY_RELEASED

409

Milestone funds were already released.

ESCROW_NOT_COMPLETED

409

Escrow has pending milestones; action cannot proceed.

ESCROW_NOT_FULLY_PROCESSED

409

Escrow has not been fully processed.

ESCROW_RELEASE_MILESTONES_EMPTY

422

release_funds requires at least one milestone index.

Roles: who can do what

The signing wallet does not hold the role the action requires. Check the escrow's roles with a read endpoint before building the transaction.

Code
Status
Summary

ESCROW_DISPUTE_RESOLVER_CANNOT_DISPUTE

403

The dispute resolver cannot initiate a dispute.

ESCROW_DISPUTE_RESOLVER_CANNOT_DISPUTE_MILESTONE

403

The dispute resolver cannot initiate a dispute on a milestone.

ESCROW_ONLY_ADMIN_CAN_EXECUTE

403

Only the admin address can perform this action.

ESCROW_ONLY_APPROVER_CAN_CHANGE_MILESTONE_FLAG

403

Only the approver can change the milestone approval flag.

ESCROW_ONLY_DISPUTE_RESOLVER_CAN_EXECUTE

403

Only the dispute resolver can perform this action.

ESCROW_ONLY_PLATFORM_ADDRESS_CAN_EXECUTE

403

Only the platform address can perform this action.

ESCROW_ONLY_RELEASE_SIGNER_CAN_RELEASE

403

Only the designated release signer can release funds.

ESCROW_ONLY_SERVICE_PROVIDER_CAN_CHANGE_MILESTONE_STATUS

403

Only the service provider can change a milestone status.

ESCROW_SIGNER_MUST_BE_APPROVER_AND_RELEASE_SIGNER

403

The signer must be in both approvers and release_signers.

ESCROW_UNAUTHORIZED_APPROVER

403

Caller is not in roles.approvers.

ESCROW_UNAUTHORIZED_TO_CHANGE_DISPUTE_FLAG

403

Caller is not authorized to change the dispute flag.

Lookup & arithmetic

Cross-cutting: the escrow does not exist, or an amount overflowed on-chain.

Code
Status
Summary

ESCROW_DIVISION_ERROR

500

Arithmetic division error while processing the escrow.

ESCROW_NOT_FOUND

404

Escrow does not exist.

ESCROW_OVERFLOW

500

Arithmetic overflow while processing the escrow.

ESCROW_REENTRANCY

500

Reentrant call detected.

ESCROW_TOO_MANY_ESCROWS_REQUESTED

422

Too many escrows requested; the maximum is 20 per call.

ESCROW_UNDERFLOW

500

Arithmetic underflow while processing the escrow.

Token contract errors

Raised when the on-chain simulation of a build endpoint fails inside the escrow's token contract (the trustline asset) rather than the escrow itself — for example a fund signer with no trustline for the asset. extensions.tokenContractId names the token that raised it.

Code
Status
Summary

TOKEN_ACCOUNT_MISSING

422

The Stellar account does not exist on this network.

TOKEN_ACCOUNT_NOT_CLASSIC

422

The address is not a classic Stellar account.

TOKEN_ALLOWANCE_ERROR

409

The token allowance is insufficient or invalid.

TOKEN_ALREADY_INITIALIZED

409

The token contract is already initialized.

TOKEN_AUTHENTICATION_ERROR

403

The token contract could not authenticate the invocation.

TOKEN_BALANCE_DEAUTHORIZED

403

The asset issuer deauthorized the trustline.

TOKEN_BALANCE_INSUFFICIENT

409

The token balance is insufficient for this operation.

TOKEN_INTERNAL_ERROR

500

The token contract failed with an internal error.

TOKEN_NEGATIVE_AMOUNT

422

Token amounts must not be negative.

TOKEN_OPERATION_NOT_SUPPORTED

422

The token contract does not support this operation.

TOKEN_OVERFLOW

500

Arithmetic overflow inside the token contract.

TOKEN_TRUSTLINE_MISSING

422

The account has no trustline for the escrow token, or does not exist yet.

TOKEN_UNAUTHORIZED

403

The token contract rejected the caller as unauthorized.

API errors

Raised by the API itself before anything touches the chain.

Authentication, API keys & sessions

Code
Status
Summary

API_KEY_LIMIT_REACHED

409

You have reached the maximum number of active API keys.

AUTH_BOOTSTRAP_ALREADY_DONE

409

An admin already exists.

AUTH_BOOTSTRAP_EMAIL_TAKEN

409

A user with that email already exists.

AUTH_BOOTSTRAP_INVALID_SECRET

401

Invalid bootstrap secret.

AUTH_BOOTSTRAP_SECRET_NOT_CONFIGURED

422

Bootstrap is disabled on this deployment.

AUTH_CREDENTIAL_MISSING

401

The request carries no API key or session token.

AUTH_INSUFFICIENT_ROLE

403

The credential does not have permission for this operation.

AUTH_INVALID_CREDENTIAL

401

Invalid API key or session token.

AUTH_INVALID_FORMAT

401

Invalid API key format.

AUTH_KEY_EXPIRY_IN_PAST

422

expiresAt must be in the future.

AUTH_KEY_EXPIRY_TOO_FAR

422

Requested key expiry exceeds the maximum lifetime.

AUTH_KEY_NOT_FOUND

404

API key not found.

AUTH_KEY_NO_ROLES

422

At least one role is required.

AUTH_ROLE_CEILING

403

Cannot grant a role higher than your own.

AUTH_SESSION_BAD_ALG

401

The JWT declares an unexpected signing algorithm.

AUTH_SESSION_BAD_SIGNATURE

401

The JWT signature does not verify.

AUTH_SESSION_EXPIRED

401

The session token is past its expiry.

AUTH_SESSION_INVALID

401

The JWT payload fails validation.

AUTH_SESSION_MALFORMED

401

The bearer token is not a parseable JWT.

AUTH_SESSION_NOT_CONFIGURED

422

Wallet-session auth is not configured on the server.

AUTH_SESSION_REVOKED

401

Session has been revoked. Sign in again.

AUTH_SESSION_UNAVAILABLE

401

Session auth is not enabled on this server.

AUTH_USER_ID_INVALID

422

userId must be a valid identifier.

AUTH_USER_INACTIVE

422

Cannot create API keys for inactive users.

AUTH_USER_NOT_FOUND

404

User not found.

Wallet auth: registration, login & recovery

SEP-10 challenge flows. Challenges are single-use and short-lived: always request a fresh one, sign it with the exact wallet, and submit it unmodified.

Code
Status
Summary

RECOVERY_BAD_SIGNATURE

403

Signature does not prove ownership of the address.

RECOVERY_CHALLENGE_REUSED

403

This challenge has already been used.

RECOVERY_KEY_LIMIT_REACHED

409

This account is at its active API-key limit.

RECOVERY_WALLET_NOT_REGISTERED

404

No registered account is linked to this wallet.

REGISTRATION_BAD_SIGNATURE

403

Signature does not prove ownership of the address.

REGISTRATION_CHALLENGE_REUSED

403

This challenge has already been used.

REGISTRATION_CLOSED

403

Self-registration is disabled.

REGISTRATION_EMAIL_TAKEN

409

A user with that email already exists.

REGISTRATION_WALLET_TAKEN

409

This wallet is already registered.

SESSION_BAD_SIGNATURE

403

Signature does not prove ownership of the address.

SESSION_CHALLENGE_REUSED

403

This challenge has already been used.

SESSION_USER_INACTIVE

403

This account is deactivated.

SESSION_WALLET_NOT_REGISTERED

404

No registered account is linked to this wallet.

WALLET_BAD_SIGNATURE

403

Signature does not prove ownership of the address.

WALLET_CANNOT_REMOVE_LAST

409

You cannot remove your last verified wallet.

WALLET_CHALLENGE_EXPIRED

422

The challenge has expired. Request a new one.

WALLET_LINK_NOT_FOUND

404

No wallet-link challenge found.

WALLET_NOT_FOUND

404

No such wallet is linked to your account.

WALLET_OWNED_BY_OTHER

422

This address is already linked to another account.

Users, platforms & subjects

Code
Status
Summary

PLATFORM_ID_INVALID

422

platformId must be a numeric string.

PLATFORM_NOT_FOUND

404

Platform not found for this account.

PLATFORM_REQUIRED

422

This account has no active platform for this operation.

SUBJECT_EXTERNAL_ID_TAKEN

409

Another subject of this platform already uses that externalId.

SUBJECT_NOT_FOUND

404

Subject not found under this platform.

USER_EMAIL_TAKEN

409

A user with that email already exists.

USER_ID_INVALID

422

userId must be a valid identifier.

USER_NOT_FOUND

404

User not found.

USER_NO_ROLES

422

At least one role is required.

Request validation

Code
Status
Summary

AMOUNT_INVALID

422

amount is too large to be represented exactly.

AMOUNT_OUT_OF_RANGE

422

amount is larger than the maximum on-chain value (i128).

AMOUNT_PRECISION_UNSUPPORTED

422

An amount has more decimal places than the asset supports.

ESCROW_FILTER_FORBIDDEN

403

The credential cannot use the requested escrow filter.

ESCROW_MILESTONE_TARGET_OUT_OF_RANGE

422

A milestone target does not fit in a u32.

ESCROW_RECEIVER_MEMO_OUT_OF_RANGE

422

receiverMemo does not fit in a u32.

INVALID_CURSOR

422

Malformed pagination cursor.

PLATFORM_FEE_TOO_HIGH

422

platformFee plus the Trustless Work fee would exceed 100%.

Trustlines & assets

Code
Status
Summary

ESCROW_RECEIVER_TRUSTLINE_MISSING

422

A role that receives escrow funds has no trustline for the escrow token.

STELLAR_TRUSTLINE_INVALID_FORMAT

422

trustline could not be resolved to an asset contract.

STELLAR_TRUSTLINE_MISSING

422

Escrow state carries no readable trustline address.

STELLAR_TRUSTLINE_NOT_FOUND

422

No contract deployed at the trustline address on this network.

STELLAR_TRUSTLINE_NOT_SEP41

422

The contract does not implement the SEP-41 token interface.

STELLAR_UNSUPPORTED_DECIMALS

500

The token reports decimals outside the supported range.

TRUSTLINE_DECIMALS_UNSUPPORTED

422

The asset decimals are outside the supported [0, 18] range.

Stellar network errors

Transaction submission

Raised by POST /stellar/send-transaction: either the envelope is rejected before broadcast (not built by this API, wrong shape) or the network refuses it.

Code
Status
Summary

STELLAR_INVALID_SIGNED_XDR

422

signedXdr is not a valid transaction envelope.

STELLAR_TX_BAD_AUTH

422

The signature does not match the source account.

STELLAR_TX_BAD_AUTH_EXTRA

422

The transaction includes signatures that no operation needs.

STELLAR_TX_BAD_SEQ

409

Stale sequence number; rebuild and resubmit.

STELLAR_TX_CONTRACT_NOT_ALLOWED

422

Transaction invokes a contract this API does not manage.

STELLAR_TX_FEE_BUMP_INNER_FAILED

422

The inner transaction of the fee bump failed.

STELLAR_TX_FEE_BUMP_REJECTED

422

Fee-bump transactions are not accepted.

STELLAR_TX_HOST_FN_NOT_ALLOWED

422

Only invokeContract host functions may be submitted.

STELLAR_TX_INSUFFICIENT_BALANCE

422

The source account cannot cover the fee.

STELLAR_TX_INSUFFICIENT_FEE

422

The fee is below what the network currently demands.

STELLAR_TX_INTERNAL_ERROR

503

The network reported a transient internal error.

STELLAR_TX_MISSING_OPERATION

422

The transaction does not contain any operations.

STELLAR_TX_NOT_SUPPORTED

422

Transaction type not supported on the current protocol.

STELLAR_TX_NO_OPS

422

Transaction carries no operations.

STELLAR_TX_NO_SOURCE_ACCOUNT

422

The source account does not exist on the network.

STELLAR_TX_OPERATION_FAILED

422

One or more operations failed.

STELLAR_TX_OP_NOT_ALLOWED

422

Only Soroban invokeHostFunction operations may be submitted.

STELLAR_TX_TOO_EARLY

422

Submitted before the transaction validity window.

STELLAR_TX_TOO_LATE

422

The transaction validity window has passed.

STELLAR_TX_UNPARSEABLE

422

signedXdr is not a valid transaction envelope.

Stellar infrastructure & state

RPC/Horizon connectivity, simulation plumbing, and archived contract state. Mostly retryable; report persistent ones with the traceId.

Code
Status
Summary

STELLAR_FACTORY_RETURN_SHAPE

500

The factory returned an unexpected value shape.

STELLAR_HORIZON_UNMAPPED

500

Horizon answered with an unrecognized error shape.

STELLAR_HORIZON_UNREACHABLE

500

Could not communicate with Horizon.

STELLAR_RESTORE_UNBUILDABLE

500

A state-restore transaction could not be built.

STELLAR_RETURN_VALUE_SHAPE

500

A contract returned data in an unexpected shape.

STELLAR_RPC_TIMEOUT

500

The Soroban RPC did not answer within the deadline.

STELLAR_RPC_UNAVAILABLE

500

The Soroban RPC is unreachable.

STELLAR_SIMULATION_FAILED

500

Contract simulation failed.

STELLAR_SIMULATION_MISSING

500

The RPC returned no simulation result.

STELLAR_STATE_ARCHIVED

409

Contract state is archived; sign the provided restoreXdr and retry.

STELLAR_TX_FAILED

500

The network rejected the transaction.

STELLAR_UNKNOWN_CONTRACT_METHOD

500

The target contract does not expose the invoked method.

Transport-level errors

Generic codes produced by the HTTP layer when no domain-specific code applies.

Code
Status
Summary

BAD_REQUEST

400

The request failed basic validation.

CONFLICT

409

The request conflicts with current state.

FORBIDDEN

403

The credential lacks permission.

HTTP_ERROR

500

A non-standard HTTP error status was produced.

INTERNAL_ERROR

500

An unexpected server error occurred.

NOT_FOUND

404

No route or resource matches the URL.

SERVICE_UNAVAILABLE

503

A dependency is temporarily unavailable.

TOO_MANY_REQUESTS

429

You exceeded the rate limit.

UNAUTHORIZED

401

Authentication is required or failed.

VALIDATION_ERROR

422

The request body failed validation.