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"
}
FieldTypeDescription
kidstringAPI key ID (matches your registered key)
tsint64Unix timestamp when token was created
nstringRandom 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"
}
FieldTypeRequiredDescription
addressaddressYesYour Ethereum wallet address
signaturestringYesSignature of the message below
namestringNoFriendly name for the key

The message to sign:

Register API key for Turbine: 0xYourWalletAddress

Sign 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!"
}
FieldTypeDescription
successboolWhether registration succeeded
api_key_idstringYour key ID (used in kid field of tokens)
api_private_keystringEd25519 private key hex (save this — shown only once)
messagestringStatus 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

StatusErrorDescription
401missing authorization headerNo Authorization header provided
401invalid authorization formatMust be Bearer <token>
401invalid token formatToken is malformed
401token expiredToken ts is older than 5 minutes
401API key not foundThe kid doesn't match any registered key
401API key is inactiveKey has been revoked
401API key has expiredKey's expiration time has passed
401invalid signatureEd25519 signature verification failed