Authentication
EVM wallet sign-in and API key management. Four operations.
Two credentials are involved, and they are not interchangeable:
Session token — obtained by signing a fixed message with your EVM wallet (EIP-191
personal_sign). It is aBearertoken, it lasts 24 hours, and it authenticates the/keysendpoints only. You cannot trade with it.API key — a
key_id+secretpair minted with the session token. Every trading and account request is HMAC-SHA256 signed with the secret. The secret is returned once at creation and is never stored or shown again.
POST /auth/login (wallet signature) → session Bearer token
POST /keys (Bearer) → key_id + secret
sign each request (HMAC over canonical str) → tradeFor delegated signing that avoids exposing your main wallet, see Agents.
Base URL for every example below: https://exchange.nexus.xyz/api/exchange.
POST /auth/login
Sign in with EVM wallet.
Submit an EIP-191 personal_sign signature to receive a session token. The session token is used to create and manage API keys via /keys endpoints. For trading, use HMAC API keys instead. Session tokens expire after 24 hours.
Authentication: None — the request authenticates itself with the wallet signature it carries.
Request body
LoginRequest — application/json, required.
message
string
Yes
Must be exactly: Sign in to Nexus Exchange
signature
string
Yes
EIP-191 personal_sign hex (0x-prefixed, 65 bytes)
The message is a fixed string, not a nonce challenge — there is no separate "request a challenge" call. Your wallet address is recovered from the signature, so it is not sent.
Responses
200
Session created. LoginResponse.
token
string
Session token (64-char hex). Use as Bearer token for /keys endpoints.
address
string
Recovered Ethereum address (0x-prefixed)
401
Signature verification failed.
Example
Response:
POST /keys
Create an API key.
Create a new HMAC API key for the authenticated wallet. Returns the secret once — it is never stored or shown again. Requires a session token (Bearer) from POST /auth/login.
Authentication: bearerAuth — session token.
Request body
None declared in the contract. Send the request with no body.
Gap: the guided quickstart on the live API-docs page sends an optional
{"label": "my-bot"}body to this endpoint, but spec 0.9.27 declares norequestBodyforcreateApiKey. Treatlabelas undocumented until the contract carries it.
Responses
200
Key created.
key_id
string
The key identifier. Send it as X-API-Key on signed requests.
secret
string
The HMAC secret, hex. Returned once. Persist it immediately — there is no recovery path.
The contract gives this response an example but no named schema.
401
Valid session token required.
Example
Response:
New keys are assigned the Pro tier by default. Tier assignment is an operator action — see PUT /admin/tiers — and per-tier ceilings are reported on every response in the X-RateLimit-* headers.
GET /keys
List your API keys.
Returns key IDs and tiers for all keys owned by the authenticated wallet. Secrets are not included.
Authentication: bearerAuth — session token.
Responses
200
The session's API keys. A bare array; the contract gives an example but no named schema.
key_id
string
The key identifier
tier
string
Rate-limit tier assigned to this key, e.g. Pro, Market Maker
401
Valid session token required.
Example
Response:
DELETE /keys/{key_id}
Delete an API key.
Delete a key you own. Cannot delete keys owned by other wallets.
Authentication: bearerAuth — session token.
Parameters
key_id
path
string
Yes
The key identifier to delete
Responses
200
Key deleted.
401
Valid session token required.
404
Key not found or not owned by you. Ownership failures are reported as 404, not 403 — you cannot probe for other wallets' key IDs.
Example
Signing a request with the key
Once you hold a key_id and secret, every hmacAuth operation needs three headers:
X-API-Key
Your key ID, e.g. nx_a1b2c3d4e5f67890
X-Timestamp
Current time in Unix milliseconds
X-Signature
hex(hmac_sha256(secret, canonical))
The canonical string is five newline-separated fields:
pathis the path as written in the contract — not the full URL path you called. The/api/exchangegateway mount is stripped before the request reaches the service that verifies your signature, so it must not be signed. Do include the/api/v1prefix when calling a versioned path, because that part is forwarded.You callYou signhttps://exchange.nexus.xyz/api/exchange/markets/marketshttps://exchange.nexus.xyz/api/exchange/api/v1/tickers/api/v1/tickersSigning the
/api/exchangeprefix is the second most common cause of an opaque401, after clock skew.queryis the raw query string, empty for none.For requests with no body, hash the empty string.
The timestamp must be within 30 seconds of server time. A skewed clock is the most common cause of an opaque
401.
The advisory X-Nexus-Api-Version and User-Agent headers are excluded from the canonical string.
All 401 responses return the same opaque body — {"code":"unauthorized"} — so the response will not tell you whether the key, the signature, or the clock was at fault. Check clock skew first, then the canonical string, then the key.
Status: testnet preview. Credentials, sessions, and rate-limit state are not yet durable across gateway restarts — treat API keys as re-creatable.
Last updated

