Skip to main content
The relayer is a transmitter, not a coordinator. Anyone can submit a signed order on-chain directly; the relayer is a convenience that fronts gas and earns feeBps. There are two endpoints and no authentication. The schemas below mirror the @caplane/shared wire types exactly; the machine-readable spec is published at /api/openapi.json. Two conventions hold across the API:
  • uint256 fields cross the wire as decimal strings (amount, nonce, validAfter, validBefore, feeCollected), to avoid JavaScript number precision loss. feeBps and chainId are small integers.
  • The order is transmitted exactly as signed. The relayer recomputes orderHash from the order itself and never mutates a field; any change breaks the binding and the token rejects it.

POST /broker

Transmit a consumer-signed order. The relayer recomputes orderHash, enforces its fee floor, checks the window, pre-simulates, then broadcasts. Returns a RelaySuccess (200) or a typed RelayFailure.

Request body (RelayRequest)

FieldTypeDescription
orderOrderJsonThe order (see below).
signature{ v: integer, r: hex, s: hex }The consumer’s EIP-3009 signature.
validAfterstringDecimal unix seconds; the authorization lower bound.
validBeforestringDecimal unix seconds; the authorization upper bound.
chainIdintegerRoutes to the registry entry (421614 or 46630).
orderHashstring (optional)Lets the relayer fail fast with ORDERHASH_MISMATCH.
OrderJson fields: consumer, adapter, params, payToken, payee (addresses/hex); amount, nonce (decimal strings); feeBps (integer). It mirrors the Order struct.

Responses

StatusBodyWhen
200RelaySuccessSettled: payment and grant landed atomically.
400RelayFailureMALFORMED_ORDER or ORDERHASH_MISMATCH.
402RelayFailureFEE_BELOW_FLOOR.
422RelayFailureWOULD_REVERT or AUTH_EXPIRED.
502RelayFailureUPSTREAM_RPC.
503RelayFailureINSUFFICIENT_RELAYER_GAS.
429edgeRATE_LIMITED or SERVER_BUSY (only on the hardened edge).
RelaySuccess carries ok: true, txHash, orderHash, brokered ({ consumer, adapter, amount, orderHash }), receipt (the decoded adapter receipt), and feeCollected. RelayFailure carries ok: false, code, and message, and never any key or signature material. The codes are catalogued in errors and reverts.
{
  "order": {
    "consumer": "0x26E47C6963Ee0BaB1A70B9079cF5135e00e18d46",
    "adapter": "0x76C4F7d48Bba5f4fa36C47D9B34ba3b5Ea46FE43",
    "params": "0x0000000000000000000000000000000000000000000000000000000000000001",
    "payToken": "0x125959541Bb486058E7e3b55E49b3B04e49fBa5E",
    "amount": "5000000",
    "feeBps": 100,
    "payee": "0x000000000000000000000000000000000000bEEF",
    "nonce": "92043977228133022826366390371535562086103842654639431805352199450526986662800"
  },
  "signature": {
    "v": 27,
    "r": "0xce6b0efbfc11c2df83ae8e3b0678c851d50652b05e83fd4de790ef33d43736d8",
    "s": "0x5d5908b3f2e3a6d7a2877733e238bf4582ecc26cfce3c2a782bee869456d61cd"
  },
  "validAfter": "0",
  "validBefore": "1781204783",
  "chainId": 46630,
  "orderHash": "0x4c7aac9359ac3cf807e312c24fed6501aa61dfcc9c03a73c66618f6d7db9b0f9"
}
{
  "ok": true,
  "txHash": "0xb89a566248c40431342c32281b6875e6113cd797cd82fb2d9153646abcabd845",
  "orderHash": "0x4c7aac9359ac3cf807e312c24fed6501aa61dfcc9c03a73c66618f6d7db9b0f9",
  "brokered": {
    "consumer": "0x26E47C6963Ee0BaB1A70B9079cF5135e00e18d46",
    "adapter": "0x76C4F7d48Bba5f4fa36C47D9B34ba3b5Ea46FE43",
    "amount": "5000000",
    "orderHash": "0x4c7aac9359ac3cf807e312c24fed6501aa61dfcc9c03a73c66618f6d7db9b0f9"
  },
  "receipt": "0x0000000000000000000000000000000000000000000000000000000000000001",
  "feeCollected": "50000"
}
The example above is the real order from transaction 0xb89a56…abd845. The receipt decodes to slot id 1; feeCollected is 0.050000 TUSDC.

GET /info

The relayer’s public policy. No secrets; this is how a consumer shops relayers.

Response (RelayerInfo)

FieldTypeDescription
feeFloorBpsintegerThe minimum feeBps this relayer accepts.
supportedChainIdsinteger[]The chains this relayer serves.
relayeraddressThe relayer’s gas address (address only, never the key).
{
  "feeFloorBps": 50,
  "supportedChainIds": [46630],
  "relayer": "0x0000000000000000000000000000000000000000"
}
The hosted relayer is not yet live. The relayer is permissionless: run your own (pnpm --filter @caplane/relayer start) and point CAPLANE_RELAYER_URL at it, then GET /info and POST /broker are exercisable locally. The published OpenAPI spec describes both endpoints for any client. The relayer address shown above is a placeholder; a running relayer prints its real gas address on boot.

See also