Every request to the Omnibook API is authenticated. There is no anonymous
access — even market data requires a key.
You authenticate by signing each request with your API key’s secret and sending
three headers. Nothing is sent as a bearer token, so intercepting a request does
not give anyone your key.
Create an API key
- Sign in at omnibook.xyz.
- Go to Settings → API keys (
/settings#keys).
- Click Create key, give it a name, and copy both values.
The secret is shown once and never again. Store it somewhere safe before you
close the panel. Copy the Key ID too — you need both, and the list view does
not show the secret again.If you lose a secret, revoke the key and create a new one. Revoking is immediate
and irreversible.
The canonical string
The signature covers the timestamp, method, request target and body, joined by
newlines, with a trailing newline after the target:
Concretely, for GET /v1/portfolio/balance with no body:
Three things that catch people out:
- The request target includes the query string. Sign
/v1/rounds?limit=5, not /v1/rounds.
- The body is the raw bytes you send, byte-for-byte. If you re-serialize
your JSON between signing and sending, the signature breaks.
- The signature covers the body, so you cannot sign once and replay with
different parameters.
Base64-decode your secret before using it as the HMAC key.The secret is 32 random bytes, handed to you as standard base64 — 44 characters,
which may contain + and /. The HMAC key is those 32 raw bytes, not the
44-character string.Using the string directly produces a perfectly valid-looking signature and a
permanent 401. This is the single most common integration bug.
Working examples
Clock skew
Your timestamp must be within ±5 seconds of the server’s clock. Outside that
window the request is rejected as a replay, with the same 401 as a bad
signature.
If you see intermittent 401s that go away on retry, check your clock before
you check your signing code.
Why a request failed
Every authentication failure returns the same response:
This is deliberate — an unknown key ID, a bad signature, and a stale timestamp
are indistinguishable, so probing tells an attacker nothing. Work through the
list in order:
- Did you base64-decode the secret?
- Does the signed target include the query string?
- Is the signed body byte-identical to what you sent?
- Is your clock within 5 seconds?
- Is the key still live? A revoked key cannot be restored.
Scopes
Keys carry scopes, and a bot key cannot withdraw funds. See
API keys and scopes.