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": "eyJhbGciOiJIUzI1NiIs...",
"tokenType": "Bearer",
"expiresAt": "2026-08-27T11:00:00Z",
"wallet": "0x1111111111111111111111111111111111111111"
}
{
"code": "AUTHENTICATION_FAILED",
"message": "authentication failed",
"retryable": false
}
Public authentication
Exchange challenge for token
Exchange a signed challenge for a short-lived wallet-bound JWT.
POST
/
auth
/
token
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": "eyJhbGciOiJIUzI1NiIs...",
"tokenType": "Bearer",
"expiresAt": "2026-08-27T11:00:00Z",
"wallet": "0x1111111111111111111111111111111111111111"
}
{
"code": "AUTHENTICATION_FAILED",
"message": "authentication failed",
"retryable": false
}
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.
string
required
Lowercase 32-character challenge ID returned by
POST /auth/challenge.string
required
Canonical low-s, 65-byte EOA personal-sign signature. The recovery byte may be
0/1 or 27/28.curl --request POST \
--url https://relay.mainnet.kuru.io/auth/token \
--header 'Content-Type: application/json' \
--data '{"challengeId":"8c4a11c6eb574d16972fac2a8c85a6dc","signature":"0x<65-byte-signature>"}'
string
required
Short-lived wallet-bound JWT. Treat it as a secret and never log it.
string
required
Always
Bearer.string
required
Token expiration as an ISO 8601 timestamp. Testnet tokens last one hour.
string
required
Address to which the JWT is bound.
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"tokenType": "Bearer",
"expiresAt": "2026-08-27T11:00:00Z",
"wallet": "0x1111111111111111111111111111111111111111"
}
{
"code": "AUTHENTICATION_FAILED",
"message": "authentication failed",
"retryable": false
}