Skip to main content
POST
/
api
/
v1
/
api-keys
Create API key
curl --request POST \
  --url https://staging.zerolatencylabs.com/api/v1/api-keys \
  --header 'Content-Type: application/json' \
  --header 'X-PUBLIC-KEY: <api-key>' \
  --header 'X-REQUEST-ID: <api-key>' \
  --header 'X-SIGNATURE: <api-key>' \
  --data '
{
  "account_id": 12345,
  "key_name": "trading-bot",
  "subaccount_index": 1
}
'
{
  "api_key": "k8Jq...redacted",
  "created_at": "2026-06-23T16:00:00.000Z",
  "id": "0190b6c2-7e4a-7c3b-9f21-2b6a1c4e5d8f",
  "key_name": "trading-bot"
}

Authorizations

X-PUBLIC-KEY
string
header
required

Base64 ed25519 session public key. Part of the SessionSig triple; not an API key.

X-REQUEST-ID
string
header
required

UUIDv7 replay nonce; its embedded timestamp must fall inside the skew window [now-15s, now+5s]. Part of the SessionSig triple.

X-SIGNATURE
string
header
required

Base64 ed25519 signature over the canonical request message. Part of the SessionSig triple.

Body

application/json

Request payload for creating a new API key. subaccount_index is None for an admin-scope (unpinned) key and Some(idx) for a subaccount-pinned key. Signing material lives in the X-PUBLIC-KEY / X-SIGNATURE / X-REQUEST-ID headers ([SessionSigAuth]); deny_unknown_fields rejects stray JSON fields. A legacy client that omits the new headers is rejected with a missing-header 401 by SessionSigAuth (extracted before the body), not a 400.

account_id
integer<int64>
required
Required range: x >= 0
Example:

12345

key_name
string
required
Example:

"trading-bot"

subaccount_index
null | integer<int32>

A unique identifier for a subaccount within an account.

Required range: x >= 0

Response

API key created (raw key returned once)

api_key
string
required
Example:

"k8Jq...redacted"

created_at
string<date-time>
required
Example:

"2026-06-23T16:00:00.000Z"

id
string<uuid>
required
Example:

"0190b6c2-7e4a-7c3b-9f21-2b6a1c4e5d8f"

key_name
string
required
Example:

"trading-bot"