# Authentication All OneHazel API calls require authentication. This page covers how API keys work, how to manage them, and security best practices. ## API key format OneHazel API keys follow the format: ``` oh_live_<64 hex characters> ``` For example: `oh_live_a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456` The `oh_live_` prefix makes keys easy to identify in code and logs. Keys are 32 random bytes (256 bits of entropy) encoded as hexadecimal. ## Using your API key Include your API key in the `Authorization` header as a Bearer token: ```bash curl https://api.onehazel.com/operator-data-api/settings \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` All API endpoints use this same header format. ## Creating API keys ### Via the dashboard 1. Navigate to **Settings > API Keys** in the OneHazel dashboard 2. Click **Create API Key** 3. Give it a descriptive label (e.g. "Production backend", "Staging ETL") 4. Copy the key immediately — it is only shown once ### Via the API ```bash curl -X POST https://api.onehazel.com/api-keys \ -H "Content-Type: application/json" \ -d '{ "operatorId": "your-operator-id", "label": "Production backend" }' ``` **Response:** ```json { "success": true, "data": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "key": "oh_live_a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", "label": "Production backend", "createdAt": "2026-04-06T12:00:00.000Z" } } ``` ## Listing API keys ```bash curl https://api.onehazel.com/api-keys \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` Keys are returned with masked hashes — the plaintext key is never stored or retrievable after creation. ## Renaming a key ```bash curl -X PATCH https://api.onehazel.com/api-keys \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "label": "New label" }' ``` ## Revoking a key ```bash curl -X DELETE "https://api.onehazel.com/api-keys?id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` ::: warning Last-key guard You cannot revoke your last active API key. Create a new key before revoking the old one. This prevents accidental lockout. ::: ## Hard deleting a key Already-revoked keys can be permanently deleted: ```bash curl -X DELETE "https://api.onehazel.com/api-keys?id=a1b2c3d4-e5f6-7890-abcd-ef1234567890&hard=true" \ -H "Authorization: Bearer oh_live_YOUR_API_KEY" ``` Active keys must be revoked before they can be hard-deleted. ## Security ### Key storage API keys are **never stored in plaintext**. OneHazel stores only the SHA-256 hash of each key. When you authenticate, the provided key is hashed and compared against stored hashes. ### Key rotation Best practice is to rotate keys periodically: 1. Create a new key 2. Update your application to use the new key 3. Verify the new key works 4. Revoke the old key ### JWT sessions (dashboard only) The OneHazel dashboard uses Supabase JWT sessions for browser authentication. JWTs are resolved to operators via `user_profiles.actor_id`. JWT auth is for the dashboard only — all programmatic API integrations should use API keys. ## Rate limits Rate limits are applied per operator, per endpoint category: | Endpoint Category | Limit | |---|---| | Data ingestion (realtime) | Standard rate limit | | Data ingestion (batch) | Standard rate limit | | Gateway execution | Standard rate limit | | Analytics read | 200 requests / minute | | Analytics export | 5 requests / minute | | Analytics refresh | 1 request / minute | When rate-limited, the API returns HTTP `429` with a `Retry-After` header and a `resetAt` timestamp in the response body. ## Error responses | HTTP Status | Error Code | Description | |---|---|---| | `401` | `AUTH_MISSING` | No `Authorization` header provided | | `401` | `AUTH_INVALID` | API key not recognised | | `401` | `AUTH_REVOKED` | API key has been revoked | | `429` | `RATE_LIMITED` | Too many requests — check `Retry-After` header |