Reference

Authentication

Two kinds of keys for two audiences. Both are sent in a header, both carry scopes, both can be limited to an IP list and an expiry date.

#Sending a key

Partner APITrading API
HeaderX-Api-Key: <key>X-API-Key: qk_…
AlternativeAuthorization: Bearer <key>Authorization: Bearer qk_…
Who creates itCRM owner / admin, Settings › API & Webhooks › API keysThe client, in the trader under API access (Pro mode)
Belongs toThe company (all brands the key is allowed to see)One client and their trading accounts
FormatOpaque string, shown onceqk_ + 48 characters, shown once
Missing / wrong key401 invalid_api_key401 api_key_required / invalid_api_key / api_key_expired / api_key_revoked
Never in a URL
Keys go in headers only. Query strings end up in logs, proxies and browser history. The only token that travels in a URL is the short-lived WebSocket ticket.

#Partner API keys

A Partner key represents your backend. When it is created the owner picks the scopes it carries, optionally an IP allow-list (calls from other addresses answer 403 ip_not_allowed) and an expiry. Keys can be revoked at any time; the delivery log and every client history line show which key did what.

Check a key: GET /me
curl "https://api.your-brand.com/api/external/v1/me" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"

A key sees only the brands its company allows. Per brand the Partner API switch must be on, otherwise calls answer 403 brand_disabled.

#Partner scopes

A call that needs a scope the key does not carry answers 403 insufficient_scope. The scope each operation needs is shown as a chip on the endpoint.

clients:readRead the clients of the company, page by change time (GET /clients?updated_since=…).
clients:read_emailE-mail addresses in clear instead of masked.
clients:read_phonePhone numbers in clear instead of masked.
clients:read_ftdFirst-deposit date on clients.
clients:read_commentsClient comments.
clients:read_custom_fieldsCustom fields of the client.
users:writePUT /users/{external_id} - create or update a client by your id.
sso:issuePOST /users/{external_id}/sso - one-time login links; list and end sessions.
accounts:readAccounts, balance and positions of a user; quotes, bars and trending for your middleware.
accounts:writeOpen a trading account for a user.
trading:controlPause and resume trading for a user.
trading:actPlace, change and close orders FOR a user through the platform's own order path; every action lands in the client's history as done by your key.
balance:writePOST /users/{external_id}/transactions - book a deposit, withdrawal or credit. OFF by default: only the CRM owner (or an admin with the "Edit transactions" right) can put it on a key, and the brand's "Money posting" switch must be on.

#Trading API keys

A Trading key represents one client. The broker switches the Trading API on for the brand; the client then sees API access in the trader and creates up to 5 keys. Each key is read-only or trading, may carry an IP allow-list and an expiry, and can be revoked by the client, the broker or the system (revoking also closes its WebSocket and FIX sessions).

Check a key: GET /account
curl "https://api.your-brand.com/api/open/v1/account" \
  -H "X-API-Key: $OCTOLIT_API_KEY"

When the Trading API is not available the answer is 403 open_api_disabled with details.reason: brand_off (the broker has not enabled it), pro_locked (the client is not in Pro mode), server_off or not_ready.

#Trading scopes

readAccount, symbols, quotes, bars, trending, positions, orders, history, stream tickets. Every key has it.
tradePlace, change, close and cancel orders. Chosen when the key is created; the broker can stop API trading at any time.
fixLog on over FIX 4.4 with the same key (QUOTE and TRADE sessions).

A read-only key that tries to place an order answers 403 trade_scope_required. The broker can stop API trading for everyone at once (403 api_trading_stopped); reads keep working.

#SSO tokens, webhook secrets, FIX

SurfaceCredentialWhere
Inbound SSOA JWT you sign (RS256 public key / JWKS URL, or an HS256 shared secret)Settings › API & Webhooks › Broker login (SSO), per brand
Outbound SSOA one-time login link issued with a Partner key (sso:issue)POST /users/{external_id}/sso
WebhooksPer-endpoint secret whsec_… used to sign every delivery (HMAC-SHA256)Settings › API & Webhooks › Webhooks; rotate with 24 h overlap
FIX 4.4The Trading API key in tag 554 at logon; SenderCompID K<key id>Key needs the fix scope

#Key hygiene

  • Store keys in a secrets manager or environment variable; the examples read OCTOLIT_PARTNER_KEY / OCTOLIT_API_KEY.
  • Give each system its own key with the smallest scope set. A key that posts money (balance:write) should always have an IP allow-list.
  • Set an expiry and rotate: create the new key, switch your service, revoke the old one. Both work during the overlap.
  • On 401 stop retrying - the key is gone. On 403 read the code: it is a switch or a scope, not a transient fault.
  • Watch the client.login event with method: "sso" or "link" to see sign-ins your keys caused.
Rotate a key
# Rotation without downtime
export OCTOLIT_PARTNER_KEY="<new key>"     # 1. deploy the new key
curl -s https://api.your-brand.com/api/external/v1/me -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"   # 2. confirm
# 3. revoke the old key in Settings > API & Webhooks