API keys
Your account’s routes and the /ws/trade socket need an API key. Market data
does not.
Keys are not open yet
Section titled “Keys are not open yet”API keys are not open to outside developers on testnet yet. The app does not make them.
Sign-in with a wallet for bots is planned for after launch. This page says how a key signs a request, for when keys are open.
What you can do without a key
Section titled “What you can do without a key”Market data needs no key. You can list markets, watch order books and trades, and read history. See Market data.
Sign a request
Section titled “Sign a request”Send three headers with every account request:
| Header | Value |
|---|---|
INF-ACCESS-KEY |
The key ID. |
INF-ACCESS-TIMESTAMP |
The time now, in epoch milliseconds. |
INF-ACCESS-SIGNATURE |
The Ed25519 signature of timestamp + method + path + body, in base64. |
To read your balance at 1700000000000, you sign this text:
1700000000000GET/api/trading/accounts/7/balanceThe path is exactly what you request, without the query string. A GET has
no body. If a request has a body, add its exact bytes after the path. Each
request gets a new timestamp and a new signature. We refuse a timestamp more
than 30 seconds from our clock, so keep yours in sync.
import base64import time
import httpxfrom cryptography.hazmat.primitives.serialization import load_pem_private_key
KEY_ID = "your-key-id"ACCOUNT = 7private_key = load_pem_private_key(open("inflection-bot.pem", "rb").read(), None)
def signed(method: str, path: str, body: bytes = b"") -> dict[str, str]: timestamp = str(int(time.time() * 1000)) signature = private_key.sign(f"{timestamp}{method}{path}".encode() + body) return { "INF-ACCESS-KEY": KEY_ID, "INF-ACCESS-TIMESTAMP": timestamp, "INF-ACCESS-SIGNATURE": base64.b64encode(signature).decode(), }
path = f"/api/trading/accounts/{ACCOUNT}/balance"print(httpx.get("https://inflection.exchange" + path, headers=signed("GET", path)).json())Sign the trading socket
Section titled “Sign the trading socket”Sign the handshake that opens /ws/trade, as a GET of /ws/trade.
Reconnecting means signing a new handshake. The API key only opens the socket.
Each place, modify and cancel on it needs a signature from a session key.
See Signing orders.
import websockets
async with websockets.connect( "wss://inflection.exchange/ws/trade", additional_headers=signed("GET", "/ws/trade")) as socket: print(await socket.recv()) # {"type": "auth_success", "account_id": 7, "time_ms": 1700000000000}When it fails
Section titled “When it fails”A 401 on a request, or on the socket handshake, means one of:
- the key ID is wrong or the key was revoked,
- the signature was made with a different key,
- the signature covers a different method, path or body, or
- the timestamp is more than 30 seconds off.