ExchainDocs
DocsAPI

APIx402Co-sign an x402 payment

Co-sign an x402 payment

Co-sign one x402 payment from a guarded Safe.

  • Auth Node Token
  • Rate-limited Yes
  • Idempotency Idempotency-Key equal to batchId
  • Guide Co-sign a payment
POST
/v1/x402/cosign

Co-sign one x402 exact payment from a guarded Safe: an EIP-3009 TransferWithAuthorization, or a Permit2 PermitWitnessTransferFrom through x402ExactPermit2Proxy. A token without an EIP-3009 a Safe can sign (Ethereum USDT, Polygon USDT0) pays through Permit2 only; a SafeTx is refused here. agentSignature is the agent’s signature over the Safe message hash of typedData. Exchain verifies the typed data against intent, checks seller binding and the mandate of the asset intent.asset names, and returns every owner’s signature sorted by owner address, plus a guard receipt for the seller. The authorization window may be at most 600 seconds.

Authorization

nodeToken
headerAuthorizationBearer <token>

Node Token from the Exchain console. Works for wallets this node registered; the node’s network (preprod or mainnet) decides the network of the request. Use a preprod token in the playground.

Header Parameters

Idempotency-Key*string

Must equal batchId, which is the authorization nonce (for a SafeTx, the Safe nonce): 0x and 64 hex characters.

Match^0x[0-9a-fA-F]{64}$

Request Body

application/json
  1. body
batchId*string

The authorization nonce as 0x and 64 hex characters (a Permit2 uint256 nonce big-endian). Equal to the Idempotency-Key header.

Length1 <= length <= 128
walletId*WalletId
Match^wal_[0-9A-HJKMNP-TV-Z]{26}$
typedData*
agentSignature?string

The agent’s 65-byte signature over the Safe message hash of typedData. Required unless the wallet is a shadow wallet.

Match^0x[0-9a-f]{130}$
intent*
context?

Response Body

Allowed. Put signature in the payment payload and receipt at extensions["exchain-guard"].receipt.

application/json
  1. response
decisionId*DecisionId
Match^dec_[0-9A-HJKMNP-TV-Z]{26}$
safeMessageHash*Hex32
Match^0x[0-9a-f]{64}$
walletAddress*EvmAddress
Match^0x[0-9a-fA-F]{40}$
digest*Hex32
Match^0x[0-9a-f]{64}$
nonce*Hex32
Match^0x[0-9a-f]{64}$
quorumMembers?array<string>
signature?string

Every owner’s 65-byte signature, sorted by owner address, ready for the payment payload.

Match^0x([0-9a-f]{130})+$
receipt?string

Guard receipt: a compact EdDSA JWS by the journal key (kid did:web:<host>#journal, published at /.well-known/did.json) over {v, payer, network, asset, amount, payTo, resourceUrl, nonce, decisionId, journalLeaf, mandateHash, ownerBound, issuedAt}. Attach it to the payment payload at extensions["exchain-guard"].receipt.

shadow?boolean
members*array<|||||||>
Items1 <= items <= 1
boundsRemaining*
journalRef*string
asOf*string
Match^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
Formatdate-time
schemaVersion*string

Wire schema version, "1.1" today.

Value in"1.0""1.1"
chainTip*|null
Example Request
curl -X POST 'https://cosign.exchain.network/v1/x402/cosign' \  -H 'Idempotency-Key: 0xd830b1c61b024118f4e1dce0c305f81290222d28c2b830accf22c60b0304f946' \  -H 'Content-Type: application/json' \  -d '{  "batchId": "0xd830b1c61b024118f4e1dce0c305f81290222d28c2b830accf22c60b0304f946",  "walletId": "wal_01M53M3ZNQQ4DDNPE4262QAZ28",  "typedData": {    "domain": {      "name": "USDC",      "version": "2",      "chainId": 84532,      "verifyingContract": "0x036cbd53842c5426634e7929541ec2318f3dcf7e"    },    "types": {      "TransferWithAuthorization": [        {          "name": "from",          "type": "address"        },        {          "name": "to",          "type": "address"        },        {          "name": "value",          "type": "uint256"        },        {          "name": "validAfter",          "type": "uint256"        },        {          "name": "validBefore",          "type": "uint256"        },        {          "name": "nonce",          "type": "bytes32"        }      ]    },    "primaryType": "TransferWithAuthorization",    "message": {      "from": "0x9f2b6c1e4d7a3058b2e6f1c9d4a7b3e5f0c8a216",      "to": "0x6d2f8a4c1e9b3075d8a2f6c4e1b9d3a7f5c0e284",      "value": "500000",      "validAfter": "0",      "validBefore": "1793974027",      "nonce": "0xd830b1c61b024118f4e1dce0c305f81290222d28c2b830accf22c60b0304f946"    }  },  "agentSignature": "0x8a52bb619f12c4eb51b5297ac6bffd2eba6e81ff075e35d917b104352f93eae2b218c2eaa10c4aee2d8e8128de363bda0c853a72f6f1cfd1b7596ea3c862c7e41c",  "intent": {    "purchaseId": "att_01M53M3ZR1088SNXVGAJ9SFR2T",    "counterparty": "eip155:84532:0x6d2f8a4c1e9b3075d8a2f6c4e1b9d3a7f5c0e284",    "amount": "500000",    "asset": "eip155:84532/erc20:0x036cbd53842c5426634e7929541ec2318f3dcf7e",    "agentIdentifier": "research-agent",    "resource": "https://api.seller.example/v1/report"  }}'
Example Response
{  "decisionId": "dec_01M53M3ZR1088SNXVGAJ9SFR2V",  "safeMessageHash": "0x26ebe1acc814c822010eb2abe7e27178aebe0fcf2467a5e58e6b50be46ab7fab",  "walletAddress": "0x9f2b6c1e4d7a3058b2e6f1c9d4a7b3e5f0c8a216",  "digest": "0x9132f370787dedf90c6d69f0ff12a9f7a8471d58cfb86c0a842d69f4e72bd81f",  "nonce": "0xd830b1c61b024118f4e1dce0c305f81290222d28c2b830accf22c60b0304f946",  "quorumMembers": [    "exchain-eu-1a",    "exchain-eu-1b",    "exchain-eu-1c"  ],  "signature": "0x32d0fed30f3ccd8de52142a203227ea2d59c5f7ff529ab014b9d95023082dcafe190023975d13442ade43fa17a5ee4424a773791a1e4809d83ef786dbf6703491b7ad110a292193bfd59e7a8edb3e3d8fec0963c9c5b49b5e6e5c334bd1a9c803e58aa61dc2b210d7497844e5be671c1fd5a7f57f3545ffdbd8ef5b5b5788dc7f41b55570466ad06c009dd4dff5135a8e5b88cb20680a5e235b4d85c51d91ad1211213556442ee8a489a860e51048aab630d8695ed509393bbf1e49e8be23eae8f811b9d111cda2f3f27e05c6f3d19ea01e5176fe1c214e1f8bf0847577ba989a1ba3bf5ca770272fe92850b3cd7814c9b8be6202943343daf015e095ac3ee734d11fa1b",  "receipt": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDp3ZWI6Y29zaWduLmV4Y2hhaW4ubmV0d29yayNqb3VybmFsIiwidHlwIjoiZXhjaGFpbi1ndWFyZCtqd3MifQ.eyJ2IjoxLCJwYXllciI6ImVpcDE1NTo4NDUzMjoweDlmMmI2YzFlNGQ3YTMwNThiMmU2ZjFjOWQ0YTdiM2U1ZjBjOGEyMTYiLCJuZXR3b3JrIjoiZWlwMTU1Ojg0NTMyIiwiYXNzZXQiOiIweDAzNmNiZDUzODQyYzU0MjY2MzRlNzkyOTU0MWVjMjMxOGYzZGNmN2UiLCJhbW91bnQiOiI1MDAwMDAiLCJwYXlUbyI6IjB4NmQyZjhhNGMxZTliMzA3NWQ4YTJmNmM0ZTFiOWQzYTdmNWMwZTI4NCIsInJlc291cmNlVXJsIjoiaHR0cHM6Ly9hcGkuc2VsbGVyLmV4YW1wbGUvdjEvcmVwb3J0Iiwibm9uY2UiOiIweGQ4MzBiMWM2MWIwMjQxMThmNGUxZGNlMGMzMDVmODEyOTAyMjJkMjhjMmI4MzBhY2NmMjJjNjBiMDMwNGY5NDYiLCJkZWNpc2lvbklkIjoiZGVjXzAxTTUzTTNaUjEwODhTTlhWR0FKOVNGUjJWIiwiam91cm5hbExlYWYiOiJhNWJhOWE3N2QyZDYwYzRhOWI4ZmMwODQ3OGI4MjM2ZDQ3NjAyOTdkOTlkZWNkMjc4NzQwM2ZkNjdmMDFmYTAwIiwibWFuZGF0ZUhhc2giOiI0NzdmOTgxZjNhMWVkYmRjMWZhN2NiYzQ2Zjc4ZmVlYTNmZWQyYzY5M2IxMTZmYjRkYzZiMGFjZjU3OTRmNTQxIiwib3duZXJCb3VuZCI6dHJ1ZSwiaXNzdWVkQXQiOiIyMDI2LTExLTA1VDE0OjIyOjA4WiJ9.2VM9-XHV4ufm9gaDd89LACbfol_ksUsOdbbNacjDxob_G7r_FhTsXv0QIUzauM80d5ejCvRXPe7aFQ_q6ah_JQ",  "members": [    {      "purchaseId": "att_01M53M3ZR1088SNXVGAJ9SFR2T",      "outputIndex": 0,      "verdict": "allowed"    }  ],  "boundsRemaining": {    "per_tx_cap": {      "limit": "1000000",      "used": "500000",      "remaining": "500000"    },    "velocity_burst": {      "limit": "60",      "used": "1",      "remaining": "59",      "windowResetsAt": "2026-11-05T14:23:08Z"    },    "daily_outflow": {      "limit": "500000000",      "used": "12500000",      "remaining": "487500000",      "windowResetsAt": "2026-11-06T08:41:19Z"    },    "per_seller_cap": {      "limit": "50000000",      "used": "3500000",      "remaining": "46500000",      "windowResetsAt": "2026-11-06T08:41:19Z",      "scope": "eip155:84532:0x6d2f8a4c1e9b3075d8a2f6c4e1b9d3a7f5c0e284"    },    "per_agent_cap": {      "limit": "250000000",      "used": "12500000",      "remaining": "237500000",      "windowResetsAt": "2026-11-06T08:41:19Z",      "scope": "0x3c8e1f7a2b9d4e6c0a5f8b1d7e3c9a2f4b6d8e01"    },    "envelope": {      "limit": "20000000000",      "used": "86500000",      "remaining": "19913500000"    }  },  "journalRef": "https://cosign.exchain.network/v1/decisions/dec_01M53M3ZR1088SNXVGAJ9SFR2V",  "asOf": "2026-11-05T14:22:07.318Z",  "schemaVersion": "1.1",  "chainTip": null}

Errors

StatusCodeMeaning
400bad_requestThe body fails the schema, intent.amount is outside 1..10^18, or intent.counterparty is malformed.
400idempotency_key_mismatchThe Idempotency-Key header differs from batchId.
400batch_id_mismatchbatchId differs from the authorization nonce (for a SafeTx, the Safe nonce).
400clock_rejectedExchain’s clock check failed. Contact Exchain.
401unauthorizedThe bearer credential is missing, unknown or revoked.
401agent_signature_invalidagentSignature does not recover to the registered agent over the Safe message hash.
402fee_dueSign fee.typedData’s Safe message hash with the agent key, send it to POST /v1/x402/fees, then send the payment again.
404not_foundThe wallet is not an x402 wallet of this node.
409member_deniedThe payment was refused; members[0].denied has the code (mandate caps, counterparty_blocked, or seller binding: payee_unpinned, registry_gate, price_above_published, body_mismatch).
409asset_not_listedintent.asset is not one of the wallet’s governed assets, or Exchain disabled it on the network.
409body_mismatchThe typed data disagrees with intent or uses a method this route refuses; detail says how (for example payee, amount, window, method, nonce_reused, safe_nonce). Do not retry.
409clock_skewThe authorization window is not open now.
409reservation_conflictAnother payment holds a reservation; retry.
409idempotency_conflictThis nonce was decided before with different content (an Error body, not a refusal).
413payload_too_largeThe request body is larger than 64 KiB.
429rate_limitedOver the limit; retry after Retry-After seconds (also in retryAfterSec).
502rpc_failedThe chain could not be read (the Safe’s nonce, for a SafeTx payment or a fee Safe transaction); retry.
503quorum_unavailableFewer enclaves reachable than the threshold (Retry-After: 5), or detail: "stopped" when Exchain stopped signing (reachable: 0, no retryAfterSec and no Retry-After header).
503unavailabledetail: "record", the audit record could not be written (Retry-After: 5).

Every code and what to do about it: Errors and codes.