Authentication
VoxBurst uses API key authentication. All requests require a Bearer token in the Authorization header.
API Keys
Authorization: Bearer vb_live_xxxxxxxxxxxxxAPI keys are prefixed with vb_live_. Keys created in the VoxBurst dashboard always use this prefix.
Create and manage your API keys in the VoxBurst dashboard .
Keep your API keys secret. Never commit them to version control or expose them in client-side code.
Scopes
API keys can be scoped to specific permissions. Use the minimum scopes required for your use case.
| Scope | Description |
|---|---|
posts:read | Read posts and their status |
posts:write | Create, update, delete, and publish posts |
accounts:read | List connected social accounts |
accounts:write | Connect and disconnect social accounts |
media:read | View uploaded media files |
media:write | Upload and delete media files |
webhooks:read | View webhook configurations |
webhooks:write | Create, update, and delete webhooks |
personas:write | Create, update, and manage personas |
billing:write | Preview plan changes, change plans, manage add-ons, and purchase credits |
hashtag-sets:write | Create, update, and delete hashtag sets |
Rate Limiting
Rate limits are applied per API key based on your plan:
| Plan | Requests/Minute |
|---|---|
| Free | 120 |
| Starter | 200 |
| Pro | 500 |
| Agency | 1,000 |
Rate limit information is returned in response headers:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1707753600When rate limited, the API returns 429 Too Many Requests with a Retry-After header indicating when to retry.
Rate Limit Headers
Every API response includes headers to help you manage request pacing:
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute | 120 |
X-RateLimit-Remaining | Requests remaining in current window | 118 |
X-RateLimit-Reset | Unix timestamp when the limit resets | 1707753600 |
Example Response with Rate Limit Headers
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1707753600
{
"id": "post_abc123",
"content": "Hello from VoxBurst!",
"status": "scheduled"
}Use different API keys for development and production environments to limit the blast radius of a leaked key.
Environment Variables
Store your API key as an environment variable:
# .env
VOXBURST_API_KEY=vb_live_xxxxxxxxxxxxxcurl https://api.voxburst.io/v1/accounts \
-H "Authorization: Bearer $VOXBURST_API_KEY"Or with the TypeScript SDK:
import { VoxBurstClient } from '@voxburst/sdk'
const client = new VoxBurstClient({ apiKey: process.env.VOXBURST_API_KEY! })Health Check
The API exposes two health endpoints under the /v1 prefix:
| Endpoint | Description |
|---|---|
GET /v1/health | Returns 200 when the API is up |
GET /v1/ready | Returns 200 when the API is up and dependencies are healthy |
curl https://api.voxburst.io/v1/healthThe health endpoints are at /v1/health — not /health. Requests to https://api.voxburst.io/health (without /v1) return 403 from the CloudFront distribution layer and do not reach the API. Always use the /v1/ prefix.
Both endpoints are unauthenticated and do not require an API key.
Resource ID Format
All VoxBurst resource IDs (post IDs, account IDs, etc.) follow the cuid2 format:
- Exactly 25 characters total
- Starts with the letter
c - Followed by 24 lowercase alphanumeric characters (
a–z,0–9) - Example:
cmp6v6bhf000369v60htcu3vc
Passing a malformed ID returns 400 Bad Request — not 404. The API validates the ID format before attempting a database lookup. Handle both 400 and 404 when an ID might be user-supplied:
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid path parameter 'id': Invalid ID format"
}
}Idempotency
VoxBurst supports idempotency for all write operations (POST, PUT, PATCH, DELETE). This lets you safely retry requests on network failures without creating duplicate resources.
How to use
Add an Idempotency-Key header to any write request:
POST /v1/posts
Authorization: Bearer vb_live_xxxxxxxxxxxxx
Idempotency-Key: create-post-2026-06-01-campaign-a
Content-Type: application/jsonKey format
| Rule | Value |
|---|---|
| Header name | Idempotency-Key (case-insensitive) |
| Allowed characters | Alphanumeric, hyphens (-), underscores (_) |
| Min length | 1 character |
| Max length | 255 characters |
| TTL | 24 hours — keys are purged after expiry |
Behavior
| Scenario | Behavior |
|---|---|
| First request | Executes normally, caches response against the key |
| Repeat request (same key, same body) | Returns the cached response with Idempotency-Key-Used: true header — no duplicate action |
| Repeat request (same key, different body) | Returns 409 Conflict — key is already locked to the original payload |
| Concurrent requests with same key | Returns 409 Conflict with code IN_PROGRESS — only one request proceeds |
| Key expired (>24h) | Treated as a new request — processed normally |
Response headers
| Header | Description |
|---|---|
Idempotency-Key-Used | true when the response is a replay of a cached result |
X-VoxBurst-Supports-Idempotency | true on every response — confirms the endpoint supports idempotency |
Recommended key strategies
# Use a UUID per attempt
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
# Use a stable identifier for your operation
Idempotency-Key: schedule-post-campaign-123-slot-4
# Use a hash of the request intent for agent workflows
Idempotency-Key: post-${workspaceId}-${contentHash}-${scheduledFor}Error codes
| Code | HTTP | Cause |
|---|---|---|
IDEMPOTENCY_CONFLICT | 409 | Key already used with a different request body |
IDEMPOTENCY_IN_PROGRESS | 409 | A request with this key is currently being processed |
IDEMPOTENCY_INVALID_KEY | 400 | Key format invalid (invalid characters or out of length range) |
Idempotency keys are scoped to your workspace. A key from one workspace cannot conflict with the same key in another workspace.
Contract precedence
When prose descriptions, inline examples, SDK documentation, and the OpenAPI spec ever appear to conflict, this ordering determines which source is authoritative:
- API source code — the implementation is the ground truth. All other sources describe it.
- This documentation — pages under
/api-reference/*reflect the current implementation, validated against the codebase before publishing. - OpenAPI spec (
GET /api/openapi.yaml) — machine-readable contract. Kept in sync with implementation; the source code takes precedence on conflict. - SDK docs (TypeScript, Go) — SDK method signatures and types are derived from the REST contract. Where SDK behavior diverges from REST, the REST contract wins.
- Examples — illustrative, not normative. Examples may omit optional fields or use placeholder values.
In practice: if you encounter a mismatch between a docs example and a field table, trust the field table. If a field table conflicts with an actual API response, file a bug — the implementation may have changed without a docs update.
Backwards compatibility: non-breaking changes (new optional fields, new endpoints, new enum values) are deployed without notice. Your client should ignore unknown fields. Breaking changes (field removal, type changes, endpoint removal) are announced at least 30 days in advance in the changelog.
Error Responses
Authentication failures return:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}| Status | Code | Cause |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid API key |
403 | FORBIDDEN | Valid key but insufficient scope |
429 | RATE_LIMITED | Rate limit exceeded |