Skip to main content
A session key is a delegated EVM address (an EOA your client controls) that your wallet authorizes to sign actions on its behalf. Instead of exposing your wallet’s private key to a trading service, you mint a scoped, expiring key that can sign only the actions you permit, on only the subaccounts you allow. Every session key carries two independent scope sets on one record:
  • Protocol scopes — on-chain authority (trade, transfer, withdraw, …). Signed into each action and re-validated by the protocol.
  • Off-chain scopes — server-side capabilities (account_info, delete_session_key). Never signed; enforced by the server.
See Access scopes for the full scope catalog and per-route gating.

How session keys are used

Diagram showing the two distinct ways a session key signs. First, signed actions: the key produces EIP-712 typed-data signatures over an Action struct for state-changing operations such as trading, RFQs, withdrawals, and transfers, and the protocol re-validates the key's protocol scopes against each action. Second, login headers: the key produces EIP-191 signatures over the login payload to authenticate HTTP and WebSocket sessions, and the server enforces the key's off-chain scopes, IP whitelist, and expiry. The wallet delegates authority to the session key, which then performs both signing roles on the wallet's behalf without ever exposing the wallet's own private key.

Delegated attenuation

The key you create can never exceed the authority of the key that signs the creation action. A child key’s scopes, expiry, and subaccounts must each be a subset of its parent’s. A key without admin cannot mint an admin child; a key expiring next week cannot mint a child expiring next month. The protocol enforces this when the create action is applied. The signing parent must itself hold the create_session_key protocol scope.

Create a session key

private/create_session_key is a signed action: your wallet (or a parent session key with create_session_key scope) EIP-712-signs a create-session-key action, which you then submit to the API. See Action signing for how to build the nonce, signature, and signature_expiry_sec fields.
wallet
string
required
Wallet the session key is registered for (0x-prefixed).
public_session_key
string
required
The delegated EVM address being authorized (0x-prefixed).
expiry_sec
integer
required
Unix seconds (UTC) after which the key is expired. Must not exceed the parent’s expiry.
subaccount_ids
integer[]
Subaccounts this key may act on. Omit or empty ⇒ all current and future subaccounts. Must be a subset of the parent’s subaccounts.
protocol_scopes
string[]
required
Wire-string protocol scopes signed into the action (e.g. "trade:orderbook:all", "withdraw"). Validated and attenuated in-protocol. See Access scopes.
offchain_scopes
string[]
required
Off-chain scopes (account_info, delete_session_key). Backend-only, not signed.
label
string
Human-readable label.
ip_whitelist
string[]
If non-empty, the key may only authenticate from these IPs.
nonce
string
required
Strictly-increasing anti-replay nonce (see Action signing).
signer
string
required
Address that produced signature — the wallet or a parent session key.
signature
string
required
0x-prefixed 65-byte r||s||v EIP-712 signature over the create action.
signature_expiry_sec
integer
required
Unix seconds after which the signed action is rejected. A typical client default is now + 600 (10 min).
module
string
required
EIP-712 action module address (the CREATE_SESSION_KEY_MODULE). Part of the signed struct hash — client and server must agree. A fixed protocol constant, identical across deployments; see Action signing.
module is a fixed protocol constant (identical across deployments), but it must still match exactly or the signature will be rejected. Verify your encoding with the signing-preview helpers described in Action signing.

Edit a session key

private/edit_session_key updates off-chain fields only: label, ip_whitelist, and offchain_scopes. It requires no re-signing.
Protocol scopes are not editable. To change a key’s on-chain authority, mint a new key with create_session_key. This edit method only touches off-chain metadata.
Authorization depends on what you change:
  • Label only → requires the off-chain account_info scope.
  • IP whitelist or off-chain scopes → requires protocol admin (or the owning wallet).
wallet
string
required
Wallet the key belongs to.
public_session_key
string
required
The session key address to edit.
label
string
New label.
ip_whitelist
string[]
Replacement IP whitelist. Empty ⇒ no IP restriction.
offchain_scopes
string[]
Replacement off-chain scopes.

IP whitelist

If a key’s whitelist is non-empty, login from any other IP is rejected. An empty whitelist imposes no IP restriction.

Lifecycle at a glance

1

Create

Wallet (or a parent key with create_session_key scope) signs a create action granting a subset of its own scopes, expiry, and subaccounts.
2

Authenticate

The session key logs in via EIP-191 session login; its IP whitelist and expiry are enforced at this step.
3

Sign actions

The key EIP-712-signs each action; the protocol re-checks that the key’s scopes cover the action (see Action signing).
4

Edit metadata

Adjust label, IP whitelist, or off-chain scopes with edit_session_key. Protocol scopes require a fresh create_session_key.
5

Expire

The key stops working once expiry_sec passes.

Access scopes

The full protocol and off-chain scope catalog and per-route gating.

Action signing

How the create action (and every trading action) is signed with EIP-712.