Authentication
The BreakGround API supports two authentication methods: API keys for SDK and server-to-server requests, and JWT tokens for dashboard users.
SDK Authentication (API Keys)
API keys authenticate requests from the BreakGround Runtime SDK and any server-to-server integrations. Generate keys from the dashboard under Settings > API Keys.
Key format: wfx_ followed by 64 hexadecimal characters.
Passing the API Key
The API key can be provided in three ways, checked in this order:
1. X-API-Key header (recommended)
curl -X POST https://api.breakground.io/api/sdk/events \
-H "Content-Type: application/json" \
-H "X-API-Key: wfx_your_api_key_here" \
-d '{"events": [{"type": "PAGE_VIEW", "url": "https://app.example.com"}]}'
2. _apiKey body field
Use this when custom headers are not available, such as with navigator.sendBeacon():
navigator.sendBeacon(
"/api/sdk/events",
JSON.stringify({
_apiKey: "wfx_your_api_key_here",
events: [{ type: "PAGE_VIEW", url: "https://app.example.com" }],
}),
);
The _apiKey field is stripped from the body before it reaches route handlers.
3. apiKey query parameter
Use this for GET requests where a body is not available:
curl https://api.breakground.io/api/sdk/config?apiKey=wfx_your_api_key_here
TypeScript Example
const API_KEY = "wfx_your_api_key_here";
const BASE_URL = "https://api.breakground.io";
const response = await fetch(`${BASE_URL}/api/sdk/events`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
body: JSON.stringify({
events: [
{
type: "PAGE_VIEW",
userId: "user-42",
url: "https://app.example.com/dashboard",
timestamp: new Date().toISOString(),
},
],
}),
});
const result = await response.json();
// { data: { accepted: 1, correlationId: "req-abc123" } }
Dashboard Authentication (JWT)
Dashboard users authenticate via email/password or Google SSO. The API returns an HttpOnly session_token cookie.
curl -X POST https://api.breakground.io/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "your_password"}'
The session_token cookie is automatically included in subsequent dashboard requests. Tokens can also be passed via the Authorization: Bearer <token> header.
Rate Limits
| Scope | Limit | Key |
|---|---|---|
| Global (all routes) | 100 requests/min | Per IP address |
| Auth routes | 10 requests/min | Per IP address |
| Token refresh | 20 requests/min | Per IP address |
| SDK routes | 600 requests/min | Per API key |
| Admin read | 60 requests/min | Per platform JWT |
| Admin write | 20 requests/min | Per platform JWT |
| Admin critical | 5 requests/min | Per platform JWT |
When rate limited, the API returns a 429 status with a Retry-After header indicating when to retry.
Error Responses
Authentication failures return a structured error:
{
"error": {
"message": "Unauthorized: Invalid API key",
"statusCode": 401,
"code": "AUTH_FAILED",
"category": "AUTH"
}
}
| Code | Status | When |
|---|---|---|
AUTH_FAILED | 401 | Missing or invalid API key |
AUTH_NO_TOKEN | 401 | Missing JWT token (dashboard routes) |
AUTH_INVALID_TOKEN | 401 | Expired or malformed JWT |
AUTH_TOKEN_REVOKED | 401 | Token has been revoked |
FORBIDDEN | 403 | Valid auth but insufficient permissions |
RATE_LIMITED | 429 | Too many requests |
Security Best Practices
- Use the
X-API-Keyheader over query parameters when possible to avoid key exposure in logs. - Store API keys in environment variables, not in client-side source code.
- Rotate keys periodically from the dashboard API Keys settings page.
- Each company can have multiple active API keys for safe rotation.