Skip to main content
Relay validates policy, availability, signatures, and broadcast before accepting a request. Both REST and WebSocket submission methods can fail immediately. A REST BROADCAST response only means that the provider accepted the transaction for broadcast: REST does not deliver later confirmation, replacement, or revert information. REST clients must independently query chain receipts and reverts. A WebSocket client can receive the same immediate response and, when it subscribes with transaction.subscribe, receive a later terminal outcome. Branch on the stable code, HTTP status, and retryable field. Do not branch on message text. Messages are diagnostic and may change.

Immediate response states

Public error codes

Retry only when retryable is true, using bounded backoff and any supplied retryAfterMs. Never blindly create a new logical transaction after BROADCAST_RESULT_UNKNOWN. STATE_UNAVAILABLE is about the state snapshot needed to plan safely. SIGNER_QUEUE_FULL is capacity exhaustion; SIGNER_LANE_UNAVAILABLE means the wallet’s pinned sponsor lane is unsafe. BROADCAST_REJECTED is definitive provider rejection, while BROADCAST_RESULT_UNKNOWN is uncertainty. SIGNER_POLICY_DECLINED is a deterministic signer-policy decision; an unchanged retry will not help.

Client flow examples

Validation rejection (REST):
Successful REST submission:
The REST response ends here; query the chain yourself for receipt, replacement, or revert. WebSocket rejection and broadcast:
After subscribing, the same WebSocket can deliver transaction.outcome with CONFIRMED, REVERTED, REPLACED, or UNKNOWN. A reverted custom error includes its pinned selector/name; an undecodable revert keeps selector/data and uses message unknown.

WebSocket transaction outcomes

Subscribe after an accepted submission with:
The immediate response is SUBSCRIBED, or an outcome replay if the transaction is already terminal. Later delivery is:
CONFIRMED means included successfully with finalized terminal evidence; REVERTED means included but the EVM reverted; REPLACED means the candidate was replaced (with replacementTxHash when known); UNKNOWN means no stronger terminal result is available. Revert sources are trace, historical_call, post_block_call (lower confidence), or unknown.

Connection closure and recovery

The current testnet deployment allows 64 pending outcome subscriptions on one client WebSocket. If the connection is full, Relay may close it while registering another outcome after writing that transaction’s BROADCAST response. This does not roll back the broadcast. Nor does it mean Relay ran out of sponsor nonces: the signer has a separate unconfirmed-transaction window. The 64 value is configuration, not a permanent API guarantee. After a disconnect, preserve all unresolved requestId/txHash pairs and the last observed transaction.outcome. Reconnect with a fresh wallet-bound session; resubscribe to known transactions while their outcomes are retained, and use chain receipts or state to resolve those no longer available from Relay. Treat a submission whose broadcast response was lost as uncertain: reconcile it before signing or submitting a replacement logical action. Use bounded, asynchronous recovery work so receipt/log lookups do not halt the trading submission loop. A roughly 50-second pause during reconnect is not a Relay-prescribed backoff; investigate the client connector’s reconciliation and RPC queries. Revert decoding recognizes Solidity Error(string) (0x08c379a0) and Panic(uint256) (0x4e487b71), plus custom errors from the pinned compiled ABI catalog. Unknown selectors retain exact selector and data, with name omitted and message unknown. Decoded text is bounded and untrusted.

Outcome subscription errors

transaction.subscribe can return MALFORMED_REQUEST, INVALID_BINDING, TRANSACTION_OUTCOME_NOT_FOUND, TRANSACTION_OUTCOME_ALREADY_SUBSCRIBED, TRANSACTION_OUTCOME_EXPIRED, STATE_UNAVAILABLE, or INTERNAL_ERROR. These errors refer to lookup/subscription state, not a new broadcast attempt.

Generated custom-error appendix

The following entries are generated from the pinned AccountCore and KuruTradingWallet bindings. They are decoding names only; they are not Relay error codes. Regenerate this appendix whenever the pinned generated bindings or ABI catalog changes.