Session keys sign writes, not reads. For read access, mint an API key or device key — see Read credentials.
What a session key is
A session key is Ed25519: a 32-byte public key and a 64-byte signature. Any master key — admin or scoped — can mint one (Master keys). Within its scope, the session authorizes order entry, cash movement, portfolio and subaccount writes, and key management. Its lifetime is set byvalid_until at mint time; the maximum 64-bit value means it never expires.
The session key signs requests two ways. For signed writes it goes in the Base64SignedPayload envelope with signature_type = 0 — see Signed payload. For a few header-signed endpoints (API-key management, device login) the same key signs a canonical message carried in the X-PUBLIC-KEY / X-SIGNATURE / X-REQUEST-ID triple — see Session signature.
Minting a session
A master key mints a session by registering your session public key and avalid_until.
Generate an Ed25519 keypair
Create the keypair client-side. The exchange never sees the private key.
Choose a scope
Pin the session to one subaccount, or leave it unpinned to inherit the master key’s reach. See Scope.
Set valid_until
A Unix-epoch nanosecond timestamp, or the maximum 64-bit value for a session that never expires.
Scope
You set the session’s scope at mint time. Scope decides which subaccounts the session reaches and whether it carries admin authority. A pinned session’s scope is a subaccount index. It acts only on that one subaccount, which must be reachable from the minting master key. An unpinned session’s scope is the maximum 32-bit value (the sentinel for “no pin”); it inherits the minting master key’s reach. An unpinned session minted under an admin master key is admin-rooted: it reaches the whole account and carries account-level authority. A common mistake: pinning a session under an admin master key does not make it admin-rooted. Pinning narrows reach to one subaccount and strips account-level authority, even when the parent is an admin key. Admin authority requires an unpinned session under an admin master key. The FullAccess / TradingOnly role a session inherits from its master key is separate from the admin-rooted requirement. A session can carry FullAccess and still not be admin-rooted if it is pinned or rooted on a scoped key.Operations that require an admin-rooted session
These operations reject any pinned session and any session rooted on a scoped master key, even when the signature is valid:- Create a subaccount.
- Withdraw cash — see Withdrawals security.
- Mint or delete an admin-scope (unpinned) API key.
Per-master-key cap
Each master key mints a limited number of live session keys. Minting beyond the cap is rejected withsession_rejected_max_sessions — revoke unused sessions to free slots.
The cap is per master key, not per account. An account with several master keys can hold more sessions in total, but no single master key exceeds its cap.
Lifetime and expiry
valid_until is fixed at mint time and cannot be extended. When it passes, the session stops signing — mint a new one.
- Set a finite
valid_untilfor sessions tied to a job, a host, or a key-rotation window. - Set the maximum 64-bit value for a session that never expires.
- A master key can revoke any session it sees before its
valid_until.
Reading the response
A session-mint or session-revoke call returns HTTP200 even when it is rejected — read the body for the success flag and status (error model).
Accepted signed writes signed by a session return a RequestAck — { status, processed_at_ns }. Branch on status; processed_at_ns is the exchange processing time in nanoseconds since the Unix epoch. See error codes for the full status set and rate limits for 429 and 413.