Turqoa Docs

Authentication

The Turqoa API supports two authentication methods: API key authentication for server-to-server integrations, and OAuth 2.0 for applications that act on behalf of users. All requests must be authenticated.

API Key Authentication

API keys are the simplest way to authenticate. Each key is scoped to specific permissions and tied to a service account.

Creating an API Key

API keys are created in the Turqoa admin panel under Settings > API Keys, or via the API:

curl -X POST https://api.turqoa.com/v1/auth/api-keys \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SIEM Integration",
    "scopes": ["events:read", "transactions:read"],
    "expires_in_days": 365,
    "ip_allowlist": ["10.0.0.0/8", "192.168.1.0/24"]
  }'

Response:

{
  "data": {
    "id": "key_abc123",
    "name": "SIEM Integration",
    "key": "tqa_live_a1b2c3d4e5f6g7h8i9j0...",
    "scopes": ["events:read", "transactions:read"],
    "expires_at": "2027-04-06T00:00:00Z",
    "created_at": "2026-04-06T10:00:00Z"
  }
}

The full key is only shown once at creation time. Store it securely.

Using an API Key

Include the key in the Authorization header with the Bearer prefix:

curl https://api.turqoa.com/v1/events \
  -H "Authorization: Bearer tqa_live_a1b2c3d4e5f6g7h8i9j0..."
import requests

headers = {
    "Authorization": "Bearer tqa_live_a1b2c3d4e5f6g7h8i9j0..."
}

response = requests.get(
    "https://api.turqoa.com/v1/events",
    headers=headers
)
events = response.json()
const response = await fetch("https://api.turqoa.com/v1/events", {
  headers: {
    Authorization: "Bearer tqa_live_a1b2c3d4e5f6g7h8i9j0...",
  },
});
const events = await response.json();

Key Prefixes

PrefixEnvironment
tqa_live_Production
tqa_test_Staging/test
tqa_dev_Development

Key Rotation

Rotate keys without downtime by creating a new key before revoking the old one:

# 1. Create new key with same scopes
curl -X POST https://api.turqoa.com/v1/auth/api-keys \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -d '{"name": "SIEM Integration v2", "scopes": ["events:read", "transactions:read"]}'

# 2. Update your integration to use the new key

# 3. Revoke the old key
curl -X DELETE https://api.turqoa.com/v1/auth/api-keys/key_abc123 \
  -H "Authorization: Bearer $ADMIN_TOKEN"

OAuth 2.0 Flow

For applications that need to act on behalf of Turqoa users (e.g., third-party dashboards), use the OAuth 2.0 Authorization Code flow.

Register an Application

Register your application in the admin panel under Settings > OAuth Applications:

{
  "name": "Security Dashboard",
  "redirect_uris": ["https://dashboard.example.com/callback"],
  "scopes": ["events:read", "transactions:read", "maritime:read"],
  "grant_types": ["authorization_code", "refresh_token"]
}

You will receive a client_id and client_secret.

Authorization Flow

Step 1: Redirect to Authorization

Redirect the user to the Turqoa authorization endpoint:

https://auth.turqoa.com/oauth/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://dashboard.example.com/callback&
  scope=events:read+transactions:read&
  state=random_csrf_token

Step 2: User Grants Access

The user logs in and approves the requested scopes. Turqoa redirects back to your redirect_uri with an authorization code:

https://dashboard.example.com/callback?code=AUTH_CODE&state=random_csrf_token

Step 3: Exchange Code for Tokens

curl -X POST https://auth.turqoa.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=https://dashboard.example.com/callback"

Response:

{
  "access_token": "tqa_oauth_eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tqa_refresh_dGhpcyBpcyBhIH...",
  "scope": "events:read transactions:read"
}

Step 4: Use the Access Token

curl https://api.turqoa.com/v1/events \
  -H "Authorization: Bearer tqa_oauth_eyJhbGciOiJSUzI1NiIs..."

Token Refresh

Access tokens expire after 1 hour. Use the refresh token to obtain a new access token without user interaction:

curl -X POST https://auth.turqoa.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=tqa_refresh_dGhpcyBpcyBhIH..." \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"
{
  "access_token": "tqa_oauth_bmV3IGFjY2VzcyB0b2tl...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tqa_refresh_bmV3IHJlZnJlc2gg..."
}

Refresh tokens expire after 30 days of inactivity. Each refresh returns a new refresh token (rotation).

Automatic Refresh in SDKs

from turqoa import TurqoaClient

# The SDK handles token refresh automatically
client = TurqoaClient(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
    refresh_token="tqa_refresh_dGhpcyBpcyBhIH..."
)

# This will auto-refresh if the token has expired
events = client.events.list(severity="high")
import { TurqoaClient } from "@turqoa/sdk";

const client = new TurqoaClient({
  clientId: "YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
  refreshToken: "tqa_refresh_dGhpcyBpcyBhIH...",
});

// Auto-refreshes transparently
const events = await client.events.list({ severity: "high" });

Scoped Permissions

Both API keys and OAuth tokens are scoped to specific permissions. A request to an endpoint outside the token's scope returns 403 Forbidden.

Available Scopes

ScopeDescription
events:readRead security events
events:writeCreate and update events
transactions:readRead gate transactions
transactions:writeOverride transaction decisions
maritime:readRead vessel data, zones, risk scores
maritime:writeCreate/modify threat zones
drones:readRead fleet status and mission data
drones:writeCreate missions, abort flights
webhooks:readList webhook configurations
webhooks:writeCreate, update, delete webhooks
system:readRead system health and config
system:writeModify system configuration
adminFull administrative access

Checking Token Scopes

curl https://api.turqoa.com/v1/auth/introspect \
  -H "Authorization: Bearer YOUR_TOKEN"
{
  "data": {
    "active": true,
    "scopes": ["events:read", "transactions:read"],
    "expires_at": "2026-04-06T11:00:00Z",
    "client_id": "YOUR_CLIENT_ID",
    "token_type": "oauth"
  }
}

Security Best Practices

  • Store API keys in environment variables or a secrets manager, never in source code
  • Use the narrowest scope necessary for each integration
  • Set IP allowlists on API keys when the calling service has a fixed IP
  • Rotate API keys at least every 90 days
  • Monitor the API Key Usage dashboard in the admin panel for anomalies
  • Use OAuth 2.0 for any user-facing application rather than embedding API keys in client-side code
  • Enable webhook signature verification (see Webhooks)