Authentication
Most API endpoints are public and don't require authentication. When bearer token auth is enabled on the server, write endpoints (order submission, cancellation) require an API key.
Public Endpoints
All GET endpoints are public and do not require authentication, including:
/api/v1/markets/api/v1/orderbook/{marketId}/api/v1/trades/{marketId}/api/v1/stats/{marketId}/api/v1/platform/stats/api/v1/quick-markets/{asset}/api/v1/resolution/{marketId}/api/v1/stream(WebSocket)
Bearer Token Authentication
When enabled, write endpoints require an Authorization header with a signed bearer token.
Token Format
Tokens use Ed25519 signatures and have the form:
base64url(payload).base64url(signature)The payload is a JSON object:
{
"kid": "your-key-id",
"ts": 1735689000,
"n": "random-32-char-hex-nonce"
}| Field | Type | Description |
|---|---|---|
kid | string | API key ID (matches your registered key) |
ts | int64 | Unix timestamp when token was created |
n | string | Random 32-character hex nonce (replay prevention) |
Tokens are valid for 5 minutes from the ts timestamp.
**Note:** Ensure your system clock is accurate when generating tokens. Tokens older than 5 minutes will be rejected.
Making Authenticated Requests
Include the token in the Authorization header:
curl -X POST https://api.turbinefi.com/api/v1/orders \
-H "Authorization: Bearer <payload>.<signature>" \
-H "Content-Type: application/json" \
-d '{ ... }'Registering an API Key
Register for API credentials by proving wallet ownership with an Ethereum signature.
POST to: /api/v1/api-keys
This endpoint does not require bearer authentication — it uses wallet signature verification instead.
Request: Register API Key
Request body (JSON):
{
"address": "0xYourWalletAddress",
"signature": "0x...",
"name": "my-trading-bot"
}| Field | Type | Required | Description |
|---|---|---|---|
address | address | Yes | Your Ethereum wallet address |
signature | string | Yes | Signature of the message below |
name | string | No | Friendly name for the key |
The message to sign:
Register API key for Turbine: 0xYourWalletAddressSign this message using a standard Ethereum personal sign (eth_sign or personal_sign).
Response: API Key Created
{
"success": true,
"api_key_id": "abc123def456...",
"api_private_key": "deadbeef...",
"message": "API key created successfully. Save your private key - it cannot be retrieved later!"
}| Field | Type | Description |
|---|---|---|
success | bool | Whether registration succeeded |
api_key_id | string | Your key ID (used in kid field of tokens) |
api_private_key | string | Ed25519 private key hex (save this — shown only once) |
message | string | Status message |
Generating Tokens (Client-side)
Use your api_key_id and api_private_key to generate bearer tokens.
Python example:
import json
import time
import base64
import secrets
from nacl.signing import SigningKey
# Your credentials from registration
key_id = "abc123def456..."
private_key_hex = "deadbeef..."
# Create payload
payload = {
"kid": key_id,
"ts": int(time.time()),
"n": secrets.token_hex(16)
}
# Sign with Ed25519
payload_bytes = json.dumps(payload).encode()
signing_key = SigningKey(bytes.fromhex(private_key_hex))
signature = signing_key.sign(payload_bytes).signature
# Encode token
token = (
base64.urlsafe_b64encode(payload_bytes).rstrip(b"=").decode()
+ "."
+ base64.urlsafe_b64encode(signature).rstrip(b"=").decode()
)
# Use in requests
headers = {"Authorization": f"Bearer {token}"}Use the generated token in the Authorization header when calling write endpoints.
Error Responses
| Status | Error | Description |
|---|---|---|
| 401 | missing authorization header | No Authorization header provided |
| 401 | invalid authorization format | Must be Bearer <token> |
| 401 | invalid token format | Token is malformed |
| 401 | token expired | Token ts is older than 5 minutes |
| 401 | API key not found | The kid doesn't match any registered key |
| 401 | API key is inactive | Key has been revoked |
| 401 | API key has expired | Key's expiration time has passed |
| 401 | invalid signature | Ed25519 signature verification failed |