> ## 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.

# Exchange challenge for token

> Exchange a signed challenge for a short-lived wallet-bound JWT.

Public endpoint. No JWT or `Authorization` header is required. It verifies the wallet's signed challenge, consumes the challenge, and returns a wallet-bound bearer token. A challenge succeeds at most once.

**challengeId** `string` *required*

Lowercase 32-character challenge ID returned by `POST /auth/challenge`.

**signature** `string` *required*

Canonical low-s, 65-byte EOA personal-sign signature. The recovery byte may be `0`/`1` or `27`/`28`.

```curl cURL theme={null}
curl --request POST \
  --url https://relay.mainnet.kuru.io/auth/token \
  --header 'Content-Type: application/json' \
  --data '{"challengeId":"8c4a11c6eb574d16972fac2a8c85a6dc","signature":"0x<65-byte-signature>"}'
```

**accessToken** `string` *required*

Short-lived wallet-bound JWT. Treat it as a secret and never log it.

**tokenType** `string` *required*

Always `Bearer`.

**expiresAt** `string` *required*

Token expiration as an ISO 8601 timestamp. Testnet tokens last one hour.

**wallet** `string` *required*

Address to which the JWT is bound.

```json 200 theme={null}
{
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "tokenType": "Bearer",
  "expiresAt": "2026-08-27T11:00:00Z",
  "wallet": "0x1111111111111111111111111111111111111111"
}
```

```json 401 theme={null}
{
  "code": "AUTHENTICATION_FAILED",
  "message": "authentication failed",
  "retryable": false
}
```


## OpenAPI

````yaml api/relay/openapi.yaml POST /auth/token
openapi: 3.1.0
info:
  title: Kuru Relay API
  version: 1.0.0
servers:
  - url: https://relay.mainnet.kuru.io
    description: Monad mainnet (default; submits real transactions)
  - url: https://relay.testnet.kuru.io
    description: Monad testnet
security: []
paths:
  /auth/token:
    post:
      summary: Exchange signed challenge for JWT
      operationId: exchangeToken
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - challengeId
                - signature
              properties:
                challengeId:
                  type: string
                signature:
                  type: string
      responses:
        '200':
          description: Wallet-bound JWT
      security: []

````

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