Skip to content

API keys

Your account’s routes and the /ws/trade socket need an API key. Market data does not.

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.

Market data needs no key. You can list markets, watch order books and trades, and read history. See Market data.

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/balance

The 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 base64
import time
import httpx
from cryptography.hazmat.primitives.serialization import load_pem_private_key
KEY_ID = "your-key-id"
ACCOUNT = 7
private_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 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}

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.