Skip to content

API keys & programmatic access

API keys let you drive Buzzator from outside the app — from your own scripts and integrations over a REST API, and from AI assistants over the MCP server (Model Context Protocol). One key, scoped to exactly the permissions you choose, authenticates both.

  • REST APIhttps://app.buzzator.com/api/pub/v1 — for scripts, automations, and integrations.
  • MCP serverhttps://app.buzzator.com/api/mcp — connect an AI assistant or any MCP-compatible client so it can operate your account.

Everything a key can do is bounded by the scopes, brands, and platforms you give it when you create it.


Creating a key

Settings → API keys → Create key. Choose:

Setting What it controls
Name A label so you can recognise the key later (e.g. "Zapier", "Reporting bot").
Permissions (scopes) Which actions the key may perform — see the table below.
Brands All brands (current and future) or a specific set. A brand-restricted key can only ever touch those brands.
Platforms All platforms or a specific set (Instagram, LinkedIn, X, …).
Expiration Optional — the key stops working after this date.

The full secret (bztr_live_… in production, bztr_test_… outside it) is shown once, at creation. Copy it then — it is stored only as a hash and can never be retrieved again. Lost it? Regenerate the key (rotates the secret, keeps the same scopes) or delete it (permanent — the secret stops working immediately).

A key acts as the teammate who created it, intersected with the key's own scopes. If that teammate loses access to a brand, the key does too. This is the least‑privilege model — give each integration its own key with the narrowest scopes it needs.


What's possible — capabilities by scope

Scope Lets the key…
brands:read List the brands the key can access (id, name, handle, logo).
accounts:read List a brand's connected social accounts (which platforms are live).
posts:read List and read posts (drafts, scheduled, published), with filters and pagination.
posts:write Create posts — as a draft or scheduled (auto‑publish at a set time).
posts:generate Start AI generation — on‑brand captions + images across platforms (async job).
publish Publish an existing post to its connected account now.
media:write Upload an image or video and get a media URL to attach to a post.
analytics:read Read aggregated engagement analytics for a brand.
inbox:read List inbox conversations (DMs, comments, mentions).
inbox:write Send a reply on a conversation (posts a real outbound message).

A key only exposes the scopes you granted it — everything else returns 403 insufficient_scope.

Common things you can build

  • Cross‑post from your own tools — create drafts or schedule posts on any connected platform.
  • Schedule at a specific time — create a post with status: "scheduled" and a future scheduled_at.
  • AI content at scale — kick off brand‑aware generation for one prompt across several platforms, then collect the drafts.
  • Reporting — pull a brand's analytics into a dashboard or a weekly digest.
  • Community management — read the inbox and (with inbox:write) send replies.
  • Give an AI assistant hands — connect the MCP server so an assistant can do all of the above conversationally.

The REST API

Base URL: https://app.buzzator.com/api/pub/v1 Auth: send Authorization: Bearer <your-api-key> on every request.

Method & path Scope What it does
GET /me Introspect the key: its org, scopes, and brand/platform restrictions.
GET /brands brands:read List accessible brands.
GET /accounts?brand_id=… accounts:read List a brand's connected accounts.
GET /posts posts:read List posts (brand_id, status, platform, page, per_page).
GET /posts/{id} posts:read Fetch a single post.
POST /posts posts:write Create a draft or scheduled post.
POST /posts/{id}/publish publish Publish a post now.
POST /generations posts:generate Start an AI generation job → 202 { job_id }.
GET /generations/{job_id} posts:generate Poll a generation job's status + drafts.
POST /media media:write Upload media (multipart) → a bare media URL.
GET /analytics?brand_id=…&days=… analytics:read Aggregated brand analytics.
GET /inbox?brand_id=… inbox:read List conversations (cursor‑paginated).
POST /inbox/{conversation_id}/reply inbox:write Send an outbound reply.

brand_id is a query parameter on brand‑scoped endpoints. A brand‑restricted key must supply it (or gets 400 brand_required).

Creating and scheduling a post

# A draft
curl -X POST "https://app.buzzator.com/api/pub/v1/posts?brand_id=<brand-uuid>" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"platform":"instagram","caption":"Hello world","status":"draft"}'

# Scheduled — same call, add status=scheduled + an absolute ISO 8601 time
curl -X POST "https://app.buzzator.com/api/pub/v1/posts?brand_id=<brand-uuid>" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"platform":"instagram","caption":"Launch!","status":"scheduled","scheduled_at":"2026-08-01T09:00:00-07:00"}'

There is no separate "schedule" endpoint — scheduling is just creating a post with status: "scheduled" and a future scheduled_at. At that time Buzzator's normal publish workflow fires it to the connected account.

AI generation is asynchronous

POST /generations returns 202 { "job_id": …, "status": "queued" } immediately. Poll GET /generations/{job_id} every 5–10 s (a run takes ~1–3 min) as it moves queued → running → done | failed. On done, the response includes the draft posts it created.

Errors & rate limits

Errors are JSON: { "detail": { "code": "…", "message": "…" } }.

Status Meaning
401 invalid_api_key Missing / malformed / revoked / expired key.
403 insufficient_scope The key lacks the scope for that action.
403 brand_out_of_scope / platform_out_of_scope The key isn't scoped to that brand/platform.
404 Not found The resource doesn't exist — or the API‑keys feature is disabled on this deployment.
422 Request validation failed.
429 Rate limit exceeded Slow down — see below.

Rate limits: ~600 requests/minute per key and ~1000/minute per IP. Keep a gentle pace with small pauses.


The MCP server (for AI assistants)

The MCP server lets an AI assistant (or any MCP‑compatible client) operate your account with the same API key — read brands and posts, create, schedule, generate and publish content, upload media, and work the inbox — all bounded by the key's scopes.

Endpoint: https://app.buzzator.com/api/mcp · Transport: streamable HTTP · Auth: Authorization: Bearer <your-api-key>

Add it to any MCP client with a standard configuration:

{
  "mcpServers": {
    "buzzator": {
      "type": "http",
      "url": "https://app.buzzator.com/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY" }
    }
  }
}

Tools exposed

whoami · list_brands · list_accounts · list_posts · get_post · create_post · publish_post · generate_post · get_generation_job · upload_media_from_url · get_analytics · list_inbox · reply_to_conversation.

Each tool requires the matching scope (e.g. create_post needs posts:write), so a key with only posts:read + analytics:read gives the assistant a read‑only, reporting‑only surface. Scheduling works the same way as the REST API — create_post with status: "scheduled" and a scheduled_at.

Least privilege for assistants: mint a dedicated key per assistant with only the scopes (and brands/platforms) it needs. A support bot might get inbox:read + inbox:write on one brand; a reporting bot only analytics:read.


Security model at a glance

  • Keys are hashed at rest (HMAC‑SHA256) — the plaintext is shown once and never stored.
  • Scoped three ways — permissions (scopes) × brands × platforms. Every request is checked against all three.
  • Acts as its creator — a key can never exceed what the teammate who made it can do; losing brand access revokes it for the key too.
  • Rotate or revoke instantlyRegenerate invalidates the old secret and issues a new one; Delete is permanent and immediate.
  • Availability — programmatic access is gated per deployment; on production it must be enabled by an admin before keys work.