HTTP API — Pay-as-you-go (Session)
A streaming payment channel built on an on-chain Escrow contract. The Buyer opens the channel and deposits funds; the Seller accumulates consumption via off-chain EIP-712 Vouchers; the channel finally settles on-chain and refunds the unused balance.
Base URL: https://web3.okx.com
Path prefix: /api/v6/pay/mpp/session
Network: X Layer (chainId 196)
Authentication
All endpoints require API Key authentication. The following headers must be provided:
Header Required Description OK-ACCESS-KEYYes API Key OK-ACCESS-SIGNYes Request signature OK-ACCESS-PASSPHRASEYes API passphrase OK-ACCESS-TIMESTAMPYes ISO 8601 timestamp Content-TypeYes application/json for POST requests
All responses use a unified envelope:
On business errors, code is non-"0" and data is null. See the Error codes section at the end of this page.
1. /api/v6/pay/mpp/session/open
POST
/api/v6/pay/mpp/session/open
Open a payment channel. Two modes are supported:
transaction mode : server-side opens — the Buyer provides an EIP-3009 authorization, and the Broker submits the on-chain openChannel transaction on their behalf
hash mode : the client opens the channel themselves and provides the broadcast transaction hash for the Broker to verify
Request parameters
Parameter Type Required Description challengeObjectYes The Challenge object issued by the server (echo back as-is). See Challenge payloadObjectYes Payment receipt payload.actionStringYes Always "open" payload.typeStringYes "transaction" (server-side opens) or "hash" (client-side already opened)payload.channelIdStringYes Channel ID (bytes32, client-precomputed) payload.authorizationObjectConditional Required when type="transaction"; the EIP-3009 authorization object payload.authorization.typeStringConditional Always "eip-3009" payload.authorization.fromStringConditional Payer address payload.authorization.toStringConditional Escrow contract address payload.authorization.valueStringConditional Deposit amount (base units) payload.authorization.validAfterStringConditional Authorization start Unix timestamp payload.authorization.validBeforeStringConditional Authorization expiry Unix timestamp payload.authorization.nonceStringConditional Random bytes32 payload.signatureStringConditional Required when type="transaction"; EIP-3009 signature (65 bytes) payload.hashStringConditional Required when type="hash"; on-chain open transaction hash payload.saltStringYes Random bytes32, used to compute channelId payload.authorizedSignerStringNo Delegated signer address; defaults to 0x0000...0000 sourceStringConditional Required when type="hash"; payer DID (did:pkh:eip155:196:0x...)
Response parameters
Parameter Type Description methodStringAlways "evm" intentStringAlways "session" statusStringAlways "success" timestampStringRFC 3339 response time channelIdStringChannel ID (bytes32) chainIdIntegerEVM chain ID, e.g. 196 referenceStringOn-chain transaction hash (returned in transaction mode) depositStringCurrently known on-chain deposit (base units)
Request example — hash mode (client-side opens)
Request example — transaction mode (server-side opens)
Response example
2. /api/v6/pay/mpp/session/topUp
POST
/api/v6/pay/mpp/session/topUp
Top up the deposit on an already-open channel. Supports transaction mode (server-side tops up) and hash mode (client-side already topped up).
Request parameters
Parameter Type Required Description challengeObjectNo Server-issued Challenge object. See Challenge payloadObjectYes Payment receipt payload.actionStringYes Always "topUp" payload.typeStringYes "transaction" (server-side tops up) or "hash" (client-side already topped up)payload.channelIdStringYes Channel ID (bytes32) payload.authorizationObjectConditional Required when type="transaction"; EIP-3009 authorization object payload.authorization.typeStringConditional Always "eip-3009" payload.authorization.fromStringConditional Payer address payload.authorization.toStringConditional Escrow contract address payload.authorization.valueStringConditional Top-up amount (base units) payload.authorization.validAfterStringConditional Authorization start Unix timestamp payload.authorization.validBeforeStringConditional Authorization expiry Unix timestamp payload.authorization.nonceStringConditional Random bytes32 payload.signatureStringConditional Required when type="transaction"; EIP-3009 signature (65 bytes) payload.hashStringConditional Required when type="hash"; on-chain topUp transaction hash payload.additionalDepositStringYes The amount being added this time (base units) payload.topUpSaltStringYes Random bytes32, required for topUp sourceStringConditional Required when type="hash"; payer DID (did:pkh:eip155:196:0x...)
Response parameters
Parameter Type Description methodStringAlways "evm" intentStringAlways "session" statusStringAlways "success" timestampStringRFC 3339 response time channelIdStringChannel ID (bytes32) chainIdIntegerEVM chain ID, e.g. 196 referenceStringOn-chain transaction hash (returned in transaction mode) depositStringCurrently known total on-chain deposit (base units)
Request example — transaction mode (server-side tops up)
Request example — hash mode (client-side already topped up)
Response example
3. /api/v6/pay/mpp/session/settle
POST
/api/v6/pay/mpp/session/settle
Mid-stream settle — the server submits the Voucher on-chain on behalf of the merchant. The merchant (payee) signs an EIP-712 SettleAuthorization with their own key; the Voucher signature (signed by payer or authorizedSigner) is uploaded with the request. The contract calls settleWithAuthorization.
Request parameters
Parameter Type Required Description payloadObjectYes Settle payload payload.actionStringNo "settle"payload.channelIdStringYes Channel ID (bytes32 hex, 0x-prefixed) payload.cumulativeAmountStringYes Cumulative amount to settle (token base units, uint128 decimal string). If <= settledOnChain the server short-circuits without going on-chain payload.voucherSignatureStringYes EIP-712 Voucher signature (65-byte r‖s‖v hex, 0x-prefixed). Signer = channel.authorizedSigner (or channel.payer if not set) payload.payeeSignatureStringYes EIP-712 SettleAuthorization signature (65 bytes). Signer = channel.payee payload.nonceStringYes uint256 decimal string, randomly generated by the merchant. The (payee, channelId, nonce) tuple is unique on-chain; reuse is rejected with NonceAlreadyUsed payload.deadlineStringYes Signature expiry Unix seconds. Rejected when current server time > deadline
Response parameters
Parameter Type Description methodStringAlways "evm" intentStringAlways "session" statusStringAlways "success" timestampStringRFC 3339 response time channelIdStringChannel ID (bytes32) chainIdIntegerEVM chain ID, e.g. 196 referenceStringOn-chain transaction hash depositStringCurrently known on-chain deposit (base units)
Request example
Response example
4. /api/v6/pay/mpp/session/close
POST
/api/v6/pay/mpp/session/close
Close the channel and finalize settlement. Uses max(client amount, server's highest held Voucher) to protect merchant revenue. After settlement, the Escrow contract refunds the unused deposit to the payer.
When cumulativeAmount <= settledOnChain, the waiver branch is taken (no new Voucher signature required).
Request parameters
Parameter Type Required Description payloadObjectYes Close payload payload.actionStringNo "close"payload.channelIdStringYes Channel ID (bytes32 hex, 0x-prefixed) payload.cumulativeAmountStringYes Final cumulative amount (token base units, uint128 decimal string). When <= settledOnChain the waiver branch is taken payload.voucherSignatureStringConditional EIP-712 Voucher signature (65-byte r‖s‖v hex). Required on the normal branch; can be empty "" on the waiver branch payload.payeeSignatureStringYes EIP-712 CloseAuthorization signature (65 bytes). Signer = channel.payee payload.nonceStringYes uint256 decimal string, randomly generated by the merchant. Shares the same (payee, channelId, nonce) used-set with SettleAuthorization — cannot be reused across types payload.deadlineStringYes Signature expiry Unix seconds. Rejected when current server time > deadline
Response parameters
Parameter Type Description methodStringAlways "evm" intentStringAlways "session" statusStringAlways "success" timestampStringRFC 3339 response time channelIdStringChannel ID (bytes32) chainIdIntegerEVM chain ID, e.g. 196 referenceStringOn-chain transaction hash depositStringCurrently known on-chain deposit (base units)
Request example
Response example
5. /api/v6/pay/mpp/session/status
GET
/api/v6/pay/mpp/session/status
Query the current state of a payment channel (read-only).
Request parameters
Parameter Location Type Required Description channelIdquery StringYes Channel ID (bytes32 hex)
Response parameters
Parameter Type Description channelIdStringChannel ID (bytes32) payerStringPayer address payeeStringPayee address tokenStringERC-20 token contract address depositStringTotal deposit amount (base units) settledOnChainStringAmount already settled on-chain (only updated after settle is called) sessionStatusStringChannel state: OPEN / CLOSING / CLOSED remainingBalanceStringRemaining balance (deposit - cumulativeAmount)
Request example
Response example
Common data structures
Challenge
The Challenge object issued by the server, echoed back by the client as-is.
Parameter Type Required Description idStringYes Challenge ID realmStringYes Protection space identifier methodStringYes Always "evm" intentStringYes Payment intent: "charge" / "session" requestStringYes base64url-encoded request parameters expiresStringYes Expiry time (ISO 8601)
Supported networks and tokens
Network Chain Index Status X Layer 196 Supported
Stablecoins supported on X Layer:
Token Contract address USDG 0x4ae46a509f6b1d9056937ba4500cb143933d2dc8USD₮0 0x779ded0c9e1022225f8e0630b35a9b54be713736
Error codes
Error responses use the unified envelope {"code": "<code>", "msg": "<message>", "data": null}.
1. Authentication errors (HTTP 401)
Code Description 50103 Header OK-ACCESS-KEY cannot be empty 50104 Header OK-ACCESS-PASSPHRASE cannot be empty 50105 Header OK-ACCESS-PASSPHRASE is invalid 50106 Header OK-ACCESS-SIGN cannot be empty 50107 Header OK-ACCESS-TIMESTAMP cannot be empty 50111 Invalid OK-ACCESS-KEY 50112 Invalid OK-ACCESS-TIMESTAMP 50113 Invalid signature
2. Request errors
Code HTTP status Description 50011 429 User request rate exceeds the per-endpoint limit 50014 400 Required parameter {param} cannot be empty
3. Business errors
Code Name Description 8000 SERVICE_ERROR Internal API service error 70000 invalid_params Missing required field or invalid format 70001 unsupported_chain Chain is not in the supported list 70002 payer_blocked Payer is blocklisted 70003 invalid_credential source missing, or txHash already used 70004 invalid_signature Signature verification failed 70005 split_sum_exceeds_total Split total >= primary amount 70006 split_count_exceeded Split count > 10 70007 tx_not_confirmed Transaction not confirmed on-chain 70008 channel_close On-chain contract channel is already closed 70009 challenge_invalid Challenge does not exist or has expired 70010 channel_not_found channelId does not exist 70011 grace_period_too_short Escrow contract grace period under 10 minutes — channel open rejected 70012 amount_exceeds_deposit cumulativeAmount exceeds the channel's deposit balance 70013 voucher_delta_too_small Voucher increment below minVoucherDelta 70014 channel_closing Channel is in CLOSING state and won't accept new Vouchers
Previous HTTP API - Batch Payment Up next Agent API