> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/api-reference/agents/register-agent.md).

# POST /agents/register

Register an agent key

Register an agent key.

`operationId`: `registerAgent`

> **Declared server:** `https://api.testnet.nexus.xyz/v1`. See [Networks](/api-reference/guides/networks.md).

> **Not reachable through CCXT.** Nexus-specific trading-agent registration. No CCXT equivalent — the closest unified concepts are API-key management, which CCXT deliberately leaves to the venue.

**Authentication:** a wallet signature carried in the request body. API-key headers and session tokens are ignored. The description below says what to sign. An unsigned call gets `401`.

## Register an agent key

> Register a new agent key for your wallet. An agent is an Ethereum-derived keypair that can sign trading requests on your behalf without exposing your main wallet. The registration is authorized by an EIP-712 signature from the wallet that will own the agent — no session token required.\
> \
> EIP-712 domain: \`{ name: 'Nexus Exchange', version: '1', chainId: \<per-network chain id>, salt: \<per-network salt> }\`. The \`chainId\` is a REQUEST field — you state it, and a wrong value costs you a registration (it recovers to the wrong signer) but proves nothing about which network you meant it for, since nothing server-side pins it. \`salt\` (ENG-11924) is what actually does that: \`keccak256(network)\` for \`network\` = \`testnet\`/\`mainnet\`/\`local\` (see \`x-nexus-networks.networks.\*.signing\_domain.salt\`, published directly there since it is a pure function of the network identifier, not server config — compute it locally or read it, the two must agree). Read \`signing\_domain.chain\_id\` from \`/metadata\` for the network you are connected to instead of hardcoding it, and refuse to sign if you cannot obtain it — a wrong domain either fails verification or produces a signature that is valid somewhere you did not intend. Mainnet is the real-funds exchange on Ethereum Mainnet, not a Nexus L1 chain, so a Nexus L1 chain id is never correct there. Because \`salt\` differs per network, a registration signed for one network does not verify on another; never replay one across networks.\
> Typed data type: \`RegisterAgent { address agent, uint64 expiresAt, uint64 nonce }\`.\
> \
> Once registered, the agent signs each request with the \`agentAuth\` scheme, whose description gives the canonical string and a test vector.

```json
{"openapi":"3.1.0","info":{"title":"Nexus Exchange API","version":"0.9.101"},"tags":[{"name":"Agents","description":"Agent key registration and management (EIP-712 signed, no session token required)"}],"servers":[{"url":"https://api.testnet.nexus.xyz/v1","description":"Public testnet (play funds) — the default server and /v1 transport base for unversioned paths."},{"url":"https://api.nexus.xyz/v1","description":"Mainnet — **REAL FUNDS**. Collateral is USDX bridged from Ethereum Mainnet; orders placed here move real money, and there is no faucet. The durable per-network base. Listed after testnet on purpose, so nothing that reaches for \"the first https server\" lands on the real-funds target. Not resolvable yet: DNS/TLS is a separate infra change."},{"url":"http://localhost:9090","description":"Local development — the indexer served directly. Not a public network; whatever your local instance holds."}],"paths":{"/agents/register":{"post":{"operationId":"registerAgent","tags":["Agents"],"summary":"Register an agent key","description":"Register a new agent key for your wallet. An agent is an Ethereum-derived keypair that can sign trading requests on your behalf without exposing your main wallet. The registration is authorized by an EIP-712 signature from the wallet that will own the agent — no session token required.\n\nEIP-712 domain: `{ name: 'Nexus Exchange', version: '1', chainId: <per-network chain id>, salt: <per-network salt> }`. The `chainId` is a REQUEST field — you state it, and a wrong value costs you a registration (it recovers to the wrong signer) but proves nothing about which network you meant it for, since nothing server-side pins it. `salt` (ENG-11924) is what actually does that: `keccak256(network)` for `network` = `testnet`/`mainnet`/`local` (see `x-nexus-networks.networks.*.signing_domain.salt`, published directly there since it is a pure function of the network identifier, not server config — compute it locally or read it, the two must agree). Read `signing_domain.chain_id` from `/metadata` for the network you are connected to instead of hardcoding it, and refuse to sign if you cannot obtain it — a wrong domain either fails verification or produces a signature that is valid somewhere you did not intend. Mainnet is the real-funds exchange on Ethereum Mainnet, not a Nexus L1 chain, so a Nexus L1 chain id is never correct there. Because `salt` differs per network, a registration signed for one network does not verify on another; never replay one across networks.\nTyped data type: `RegisterAgent { address agent, uint64 expiresAt, uint64 nonce }`.\n\nOnce registered, the agent signs each request with the `agentAuth` scheme, whose description gives the canonical string and a test vector.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegistrationRequest"}}}},"responses":{"200":{"description":"Agent registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegistrationResponse"}}}},"400":{"description":"Bad request: bad_wallet, bad_agent, expiry_out_of_range [1 d, 180 d from now] (the body carries a `message` saying which bound was missed), or invalid_json"},"401":{"description":"signature_invalid or signer_mismatch — the EIP-712 signature did not recover to the claimed wallet"},"409":{"description":"duplicate_agent — the agent address is already registered to this wallet"}}}}},"components":{"schemas":{"AgentRegistrationRequest":{"type":"object","description":"Delegates trading to an agent keypair without handing over the owner wallet's key. The signature is EIP-712 over `RegisterAgent{agent, expiresAt, nonce}`, produced by the **wallet** key, and the signing domain is per-network — a payload signed for one network is invalid on another and must never be replayed across them. Only `wallet`, `agent`, `nonce` and `signature` are required; note that `label` and `referral_code` sit outside the signed struct.","required":["wallet","agent","nonce","signature"],"properties":{"wallet":{"type":"string","description":"Owner wallet address (0x-prefixed, 20 bytes)"},"agent":{"type":"string","description":"Agent Ethereum address (0x-prefixed, 20 bytes) derived from the agent keypair"},"expires_at":{"type":"integer","format":"int64","description":"Expiry as Unix ms. Optional — defaults to now+30d. Must be in [now+1d, now+180d]."},"nonce":{"type":"integer","format":"int64","description":"Monotonic nonce. Use the current Unix timestamp in ms as a safe starting value."},"signature":{"type":"string","description":"EIP-712 signature over RegisterAgent{agent, expiresAt, nonce} from the wallet private key (0x-prefixed)"},"label":{"type":"string","description":"Optional human-readable label for the agent (e.g. 'my-bot')"},"referral_code":{"type":"string","description":"Referral code captured from a nexus.xyz/ref/<code> landing, if any. Not part of the signed EIP-712 payload. A missing or invalid code never fails registration; see the response's has_referrer/bound_by_this_call."}}},"AgentRegistrationResponse":{"type":"object","required":["agent_address","expires_at","scope","has_referrer","bound_by_this_call"],"properties":{"agent_address":{"type":"string","description":"The registered agent address (0x-prefixed)"},"expires_at":{"type":"integer","format":"int64","description":"Expiry as Unix ms, echoing the effective value (request value or the now+30d default)"},"scope":{"type":"string","description":"Always \"trade_only\" today — echoed so the client can show the user exactly what authority the key was granted."},"has_referrer":{"type":"boolean","description":"Whether this wallet has any referral edge at all, from this call or an earlier one. Never reveals the referrer's own identity."},"bound_by_this_call":{"type":"boolean","description":"True only the one time this exact call performed the referral bind. A retry of the same request, or a later registration on an already-bound wallet, reports has_referrer=true with bound_by_this_call=false — never a bare false that could be misread as \"binding failed\" when an edge already exists."}}}}}}
```

***

<sub>API version</sub> <sub></sub><sub>`0.9.131`</sub>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.nexus.xyz/api-reference/agents/register-agent.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
