Skip to main content
The Postbreeze REST API exposes everything you need to drive the scheduling pipeline from outside the dashboard.
  • Base URL: https://api.postbreeze.ai/api/v1
  • Auth: Authorization: Bearer pb_live_…
  • Content type: application/json request and response bodies
  • Errors: standard HTTP status codes; bodies are { "statusCode", "code", "message", "requestId" } (see Errors)
  • Rate limits: 60 req/min burst, 1000 req/15min sustained per key (see Rate limits)

Workspace resolution

API keys are issued in one of two modes:
  • Full access (default) — the key can act on every workspace its owner is a member of.
  • Scoped — the key is restricted to an explicit allow-list of workspaces.
How endpoints find the workspace for each request:
Endpoint shapeSource of workspaceId
GET /posts/{id}, PATCH /posts/{id}, DELETE /posts/{id}Derived from Post.workspaceId
`POST /posts//schedulerescheduleretrycancel`Derived from Post.workspaceId
POST /postsDerived from the first account in platforms[] / targets[]
GET /social-accounts/{id}, DELETE /social-accounts/{id}Derived from SocialAccount.workspaceId
POST /comments/{id}/reply, POST /comments/{id}/readDerived from Comment.workspaceId
GET /media/{id}, PATCH /media/{id}, DELETE /media/{id}Derived from the media’s owner workspace
GET /posts, GET /social-accounts, GET /commentsOptional ?workspaceId= — omit to fan out across every workspace the key can act on
GET /mediaRequired ?workspaceId= (media is account-global)
POST /media/presign, POST /media/from-url, POST /comments/refreshRequired ?workspaceId=
Derivation is enforced at the resolver layer; the server never widens a scoped key’s reach. A request to a resource that belongs to a workspace outside the key’s allow-list returns 403.

Endpoints in v1

ResourceMethods
WorkspacesGET /workspaces, GET /workspaces/{id}, POST /workspaces (create)
PostsGET /posts, POST /posts, GET /posts/{id}, PATCH /posts/{id}, DELETE /posts/{id}, POST /posts/{id}/schedule, POST /posts/{id}/cancel, POST /posts/{id}/retry, POST /posts/{id}/targets/{tid}/retry-first-comment
Social accountsGET /social-accounts, GET /social-accounts/{id}, DELETE /social-accounts/{id}
MediaGET /media, POST /media/presign, POST /media/from-url, POST /media/{id}/complete, GET /media/{id}, PATCH /media/{id}, DELETE /media/{id}
CommentsGET /comments, POST /comments/refresh, POST /comments/{id}/reply, POST /comments/{id}/read

Two body shapes for POST /posts

The post-create + post-update endpoints accept a discriminated body — send exactly one of platforms (flat) or targets (nested). Sending both returns 400 MUST_SPECIFY_EXACTLY_ONE.
  • Flat ({ content, platforms: [{ accountId }] }) — Zernio-style, recommended for most calls. Same caption for every platform.
  • Nested ({ caption, targets: [{ socialAccountId, platformOptions }] }) — full control over per-platform options, per-target media overrides, and platform-specific kind discriminators.
See Platforms → Overview for the full schema of each shape.

URL ingest for media

POST /media/from-url accepts a public HTTPS URL and fetches the bytes server-side. The fetch is SSRF-guarded — private IPs, link-local addresses, metadata-IMDS hostnames, and DNS-rebinding tricks are rejected. Redirects are not followed (redirect: manual). By the time the call returns, the bytes live in R2; the source URL is never re-fetched at publish time.

Dashboard-internal routes

A second set of routes under /api/v1/me/media/* powers the dashboard UI — they take an x-workspace-id header instead of inferring from a key. SDK and MCP callers should ignore these; they’re not part of the public surface.

OpenAPI spec

The full machine-readable spec lives at /openapi.json on this site and is regenerated on every Postbreeze deploy. The TypeScript SDK @postbreeze/node is generated from this spec.