Static Ads Lab

Authentication

API keys, the X-API-Key header, scopes, and the server-side-only rule.

Every Static Ads Lab API request requires an X-API-Key header.

The header

X-API-Key: sal_live_your_key_here

That's it. There's no Authorization: Bearer flow, no OAuth. Just one header.

Verify your key

const response = await fetch("https://api.staticadslab.com/v1/account", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { data } = await response.json();
console.log(data.organization.name);
console.log(data.api_key.scopes);

If the key is valid, this returns the organization name and the scopes the key carries. If not, you get 401 UNAUTHORIZED.

Key format

API keys are issued by the dashboard at Settings → API Keys. They have these properties:

  • Always start with sal_live_.
  • Shown only once — store them in a secrets manager immediately.
  • Tied to one organization.
  • Carry one or more scopes (see below).
  • Can be rotated or revoked at any time from the dashboard.

Scopes

Each key carries a set of scopes. The default scopes cover read/write across the public resources:

ScopeWhat it permits
brands:read / brands:writeList/get brands; create/update/delete brands
products:read / products:writeList/get products and variants; create/update/delete
audiences:read / audiences:writeList/get audiences; create/update/delete
images:read / images:writeList/get images; upload/delete
design_templates:read / design_templates:writeList/get templates; create/update/delete
image_ads:read / image_ads:writeList/get ads; generate, patch, delete, sync

Create one broad key for trusted backend code. Create scoped keys (e.g., read-only) for services that don't need to mutate data.

Server-side only

Never call the Static Ads Lab API from a browser. API keys carry full org permissions and would be exfiltrated. Always:

  • Store the key in a secrets manager (Vercel/Railway env vars, AWS Secrets Manager, etc.).
  • Call the API from your backend.
  • If you need real-time progress in the browser, push updates to the client via your own WebSocket or SSE connection (see Async jobs).

The API does not currently support short-lived client-side tokens. Issue scoped keys per backend service instead.

Rate limiting

The API enforces a rate limit per key (default 100 req / 60 s). If you exceed it, you'll get 429 RATE_LIMIT_EXCEEDED with a Retry-After header. See Rate limits.

Errors

StatusCodeWhen
401UNAUTHORIZEDMissing or invalid API key
403VariousValid key, missing scope for the requested action
429RATE_LIMIT_EXCEEDEDToo many requests on this key

See Errors for the full table.

What's next