> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kuru.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Relay

> Gas sponsorship for Kuru account and trading actions.

Kuru Relay sponsors gas for Kuru accounts. A user signs an AccountCore or trading-wallet action, and the Relay validates that signed intent, constructs the expected calldata, pays the outer transaction's gas, and broadcasts it.

```text theme={null}
Mainnet REST (playground default): https://relay.mainnet.kuru.io
Mainnet WebSocket: wss://relay.mainnet.kuru.io/relay/ws
Testnet REST: https://relay.testnet.kuru.io
Testnet WebSocket: wss://relay.testnet.kuru.io/relay/ws
```

Select testnet in the REST playground's server dropdown when testing there. **Mainnet Relay submissions can broadcast real transactions.** Confirm the selected host, chain ID, market, signer authorization, wallet-bound JWT, and signed payload before submitting. Switching servers never re-signs an intent or exchanges a JWT between networks. The copyable signed-action cURL examples are mainnet-only templates; selecting testnet does not rewrite their hard-coded host or fields. Request payloads containing placeholder signatures are illustrations, not executable signed actions.

The sponsor cannot create or change the user's signed action. It only submits supported account and trading operations so the secondary trading wallet does not need to hold native gas tokens.

Authenticate the trading wallet with the two public endpoints below, then use either the REST or WebSocket method references.

See [Relay errors and outcomes](/api/relay/errors) for stable error codes, retry guidance, and WebSocket transaction-outcome delivery.

Read [Relay security and operating model](/api/relay/security) before deploying a signer.

<Info>
  Using the TypeScript SDK? Follow [Trading-wallet signing](/sdk/trading-wallet)
  and [Relay](/sdk/relay). Their testnet examples use Monad chain ID `10143`.
</Info>

## Authentication

The two authentication endpoints are public POST APIs. They do not require a JWT.

<CardGroup cols={2}>
  <Card title="Create challenge" icon="key" href="/api/relay/reference/create-challenge">
    Public endpoint that creates the exact message a secondary trading EOA must
    sign.
  </Card>

  <Card title="Exchange token" icon="ticket" href="/api/relay/reference/exchange-token">
    Public endpoint that verifies the signed challenge and returns a
    wallet-bound JWT.
  </Card>
</CardGroup>

Request a challenge for the secondary EOA, sign the exact returned UTF-8 message with Ethereum `personal_sign`, and exchange that signature for a short-lived JWT. Challenges expire after five minutes and can be consumed only once. Use the returned `expiresAt` rather than assuming the same JWT lifetime on both networks.

The JWT authenticates Relay access only. It does not grant AccountCore permission, install EIP-7702 delegation, replace method-specific signatures, or revoke on-chain rights when it expires.

## Enabled REST methods

<CardGroup cols={2}>
  <Card title="Authorize account signer" icon="user-check" href="/api/relay/reference/authorize-account-signer">
    Grant AccountCore permission and optionally install EIP-7702 delegation.
  </Card>

  <Card title="Execute order batch" icon="layer-group" href="/api/relay/reference/execute-batch">
    Place readable native orders, cancel slots, or perform both atomically.
  </Card>

  <Card title="Execute packed replacement" icon="compress" href="/api/relay/reference/execute-replace-by-slot">
    Submit compact 32-byte maker-slot operations.
  </Card>

  <Card title="Cancel conditional order" icon="ban" href="/api/relay/reference/cancel-trigger">
    Cancel an active trigger with a signed one-shot nonce.
  </Card>
</CardGroup>

## Conditional actions — coming soon

<CardGroup cols={2}>
  <Card title="Create batch trigger" icon="clock" href="/api/relay/reference/create-batch-trigger">
    Inspect the conditional native-order batch contract.
  </Card>

  <Card title="Create packed trigger" icon="clock" href="/api/relay/reference/create-replace-trigger">
    Inspect the conditional packed-replacement contract.
  </Card>
</CardGroup>

## WebSocket

For sessions that submit many actions, connect once and send the same typed methods over a wallet-bound WebSocket.

```http theme={null}
GET /relay/ws HTTP/1.1
Host: relay.mainnet.kuru.io
Upgrade: websocket
Connection: Upgrade
Authorization: Bearer <JWT bound to the trading wallet>
```

The JWT binds the connection to one secondary EOA, so messages omit REST's `wallet` field and replace `requestId` with a connection-local `id`. Open a separate connection for each wallet.

<Info>The WebSocket reference renders typed messages and network selection, but its browser viewer cannot open Relay's authenticated connection because the upgrade requires an `Authorization` header. Use a WebSocket client that supports custom upgrade headers, or the [TypeScript SDK](/sdk/relay), to send live Relay messages. Do not put JWTs in a URL query string.</Info>

<CardGroup cols={2}>
  <Card title="Authorize account signer" icon="user-check" href="/api/relay/websocket-reference/authorize-account-signer">
    Grant AccountCore trading permission.
  </Card>

  <Card title="Execute order batch" icon="layer-group" href="/api/relay/websocket-reference/execute-batch">
    Place orders and cancel slots.
  </Card>

  <Card title="Execute packed replacement" icon="compress" href="/api/relay/websocket-reference/execute-replace-by-slot">
    Submit compact maker-slot operations.
  </Card>

  <Card title="Cancel conditional order" icon="ban" href="/api/relay/websocket-reference/cancel-trigger">
    Cancel an active trigger.
  </Card>

  <Card title="Create batch trigger" icon="clock" href="/api/relay/websocket-reference/create-batch-trigger">
    Defined for reference but not a supported live Relay flow.
  </Card>

  <Card title="Create packed trigger" icon="clock" href="/api/relay/websocket-reference/create-replace-trigger">
    Defined for reference but not a supported live Relay flow.
  </Card>
</CardGroup>

Several messages may be in flight. Each accepted `id` receives one correlated immediate response. Immediate wallet-intent nonces must increase within a connection. A `BROADCAST` response includes the sponsor nonce and transaction hash, but it is not a terminal outcome.

The current testnet Relay configuration tracks at most **64 pending transaction outcomes per client WebSocket connection**. This is an outcome-delivery limit, not a limit on assigned sponsor nonces or the signer's total unconfirmed transactions. Once all 64 slots are occupied, a further transaction may already have been broadcast when outcome tracking fails and Relay closes that WebSocket. Do not treat a closed socket as proof that the last transaction failed or was never sent. Bound outstanding submissions below this limit, drain terminal outcomes, and retain each request ID and transaction hash for recovery. The limit is deployment-configurable; clients should handle closure even when operating below it.

On reconnect, establish a new wallet-bound session and reconcile unresolved transactions by their existing identities. Keep this recovery bounded and asynchronous so receipt or log queries do not block new submissions for tens of seconds. Relay does not impose a 50-second reconnect backoff; a long pause of that kind can arise in the client connector's reconciliation path. See [Relay errors and outcomes](/api/relay/errors#websocket-transaction-outcomes) for outcome delivery and recovery details.

## Shared request rules

Every `POST /relay` request includes a lowercase UUIDv7 `requestId`, an exact `method`, the secondary EOA in `wallet`, a method-specific signed `payload`, and an optional `authorization7702` object.

All integer request fields are canonical unsigned decimal strings. Addresses and byte values use exact-width `0x` hexadecimal. Unknown and duplicate JSON fields are rejected. The request wallet must match the bearer JWT's wallet claim.

<Warning>
  `BROADCAST` means an RPC accepted the signed transaction. It does not prove
  execution or finality. Track the transaction receipt and verify the expected
  event or state transition.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.