API reference
REST API v1, webhooks and MCP — scoped keys, JSON in, JSON out.
Authentication
Create an API key in Settings → API Keys and send it as a bearer token. Keys are scoped per capability, rate-limited per minute, hashed at rest and bound to your organization.
curl https://adneticai.com/api/v1/brands \ -H "Authorization: Bearer adk_live_..." \ -H "Content-Type: application/json"
Endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | /api/v1/brands | brands:read | List brands |
| POST | /api/v1/brands | brands:write | Create a brand |
| GET | /api/v1/brands/:id | brands:read | Fetch a brand with its products |
| GET | /api/v1/actors | creatives:read | List actors available to the workspace |
| POST | /api/v1/generations/video | generations:create | Queue a video generation (idempotent) |
| GET | /api/v1/jobs/:id | creatives:read | Poll a generation job |
| GET | /api/v1/webhooks | webhooks:manage | List webhook endpoints |
| POST | /api/v1/webhooks | webhooks:manage | Register an endpoint (secret returned once) |
| GET | /api/v1/webhooks/:id | webhooks:manage | Fetch an endpoint with recent deliveries |
| DELETE | /api/v1/webhooks/:id | webhooks:manage | Delete an endpoint |
Idempotency
POST /api/v1/generations/video accepts an Idempotency-Key header. Replaying the same key returns the original job (with replayed: true) instead of creating — and charging — a new one. Keys are namespaced per organization.
Webhooks
Register endpoints on the Developers page or via the API. Endpoints must be public HTTPS URLs. The signing secret is returned exactly once at registration. Deliveries are retried up to 5 times with exponential backoff.
Every delivery carries these headers:
X-Adnetic-Event: generation.completed X-Adnetic-Delivery: <delivery id> X-Adnetic-Timestamp: <unix seconds> X-Adnetic-Signature: v1=<hex HMAC-SHA256>
The signature is HMAC_SHA256(secret, `${timestamp}.${rawBody}`). Verify by recomputing it over the exact raw request body and comparing with a constant-time equality check, and reject timestamps older than 5 minutes to prevent replays:
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, timestamp, rawBody, signature) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = "v1=" + createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}Events emitted today:
| creative.created | A creative record was created for a queued generation |
| creative.approved | A creative was approved (internal review or client link) |
| generation.queued | A generation was accepted and credits were reserved |
| generation.completed | The render finished; payload includes credits charged |
| generation.failed | The render failed; credits were released |
| localization.completed | A localization re-render finished |
| workflow.completed | An Autopilot run finished rendering its plan |
| workflow.failed | An Autopilot run failed during planning |
| campaign.approved | Every active creative of an in-review campaign was approved |
| credits.low | A reservation took the balance below 100 credits |
| test.ping | Sent by the endpoint test button / test action |
MCP server
The Model Context Protocol server is live at /api/mcp (Streamable HTTP). Authenticate with the same adk_… API keys as bearer tokens; each tool enforces the matching REST scope and calls the same application services.
| Tool | Required scope |
|---|---|
| list_brands | brands:read |
| list_actors | creatives:read |
| list_creatives | creatives:read |
| generate_hooks | campaigns:write |
| generate_script | campaigns:write |
| estimate_video_credits | generations:create |
| create_ugc_video | generations:create |
| get_generation | creatives:read |
Errors
Errors are JSON: { "error": { "code", "message" } }. Notable codes: 402 insufficient_credits, 422 compliance_blocked (the content failed the server-side compliance review; the message names the finding and a suggested fix), 429 rate_limited, and 503 when no provider or queue is configured for the workspace.