REST API Quickstart
The Agent API lives at /api/v1/agent/* and exposes endpoints for publishing posts, scheduling content, managing media, running preflight validation, and calling AI generation tools. All routes require a signed-in workspace and an API key with the appropriate scopes. MCP and REST use your plan — posts and AI credits are metered the same as in the dashboard.
Base URLs
The key prefix selects the environment automatically.
| Environment | Base URL | Key prefix |
|---|---|---|
| Production | https://api.luftsocial.com/api/v1/agent | ls_live_… |
| Staging | https://test-api.luftsocial.com/api/v1/agent | ls_test_… |
Authentication
Every request needs a single Authorization header. Your API key resolves workspace and brand context internally — no extra headers required.
Step 1 — Create a key in Developer settings
Go to Dashboard → Settings → Developer and click New API Key. Name it, pick a scope preset, and copy the value immediately — it's shown only once.
Step 2 — Store it as an environment variable
.env.local to your .gitignore.Step 3 — Send it in every request
X-Tenant-ID or X-Brand-ID for standard integrations. Those headers exist for advanced multi-brand setups only.API Key Scopes
Scopes are fine-grained permissions assigned when you create a key. They control exactly which endpoints and MCP tools that key can call. Request only the scopes your integration actually needs — following the principle of least privilege.
| Scope | Label | Description | Type |
|---|---|---|---|
| accounts:read | View brands & accounts | List brands and connected social accounts. | read |
| rules:read | Validation rules | Post types, media rules, and platform constraints. | read |
| media:read | Browse media | List library assets and read signed download URLs. | read |
| posts:read | View posts & schedules | Fetch publish status and list scheduled posts. | read |
| posts:preflight | Preflight checks | Validate captions, platforms, and readiness before publishing. | read |
| media:write | Upload & transform media | Presigned upload URLs and platform codec transforms. | write |
| posts:write | Publish & schedule | Publish immediately, schedule, or save drafts. | write |
| ai:write | AI generation | Captions, hashtags, content ideas. Debits AI credits per call. | write |
ai:write scope calls generation endpoints that debit AI credits from your plan per request. Check your usage in Dashboard → Settings → Billing.Your first request
The preflight endpoint validates a post before publishing — checking caption length, platform constraints, and media compatibility. It's the safest first call because it only reads and validates; it never writes or publishes anything.
Expected response
Thread post type example
Thread posts for Twitter or Threads require at least two typed parts in threadParts.
Explore all endpoints in theinteractive API reference or download the spec:openapi.json
Error handling
All error responses return a consistent JSON object. Parse the error field for human-readable details and code for machine-readable classification.
| Status | Meaning | When it occurs |
|---|---|---|
200 | OK | Request succeeded. |
201 | Created | Resource created (POST that creates a draft or scheduled post). |
204 | No Content | Request succeeded with no body (e.g. DELETE media). |
400 | Bad Request | Invalid parameters or missing required fields. Check the error object for details. |
401 | Unauthorized | Missing or invalid API key, or expired OAuth access token. |
402 | Payment Required | Insufficient AI credits for an AI generation call. Publish and schedule still use the posts meter. |
403 | Forbidden | Valid key but insufficient scope, or a locked plan feature. |
404 | Not Found | Resource doesn't exist or isn't accessible to this key/brand. |
422 | Unprocessable | Semantic validation error — e.g. media exceeds platform file size limit. |
429 | Too Many Requests | Rate limit exceeded. Check Retry-After header for how long to wait. |
500 | Server Error | LuftSocial-side error. Safe to retry with exponential backoff. |
429, wait the number of seconds in the Retry-After header before retrying. On 5xx errors, use exponential backoff with jitter.4xx errors (except 429) indicate a client bug — don't retry without fixing the request.