Developer docs

Connect your AI agent or build a publishing integration. Create drafts, customize posts for each account, and track publishing results through the API or MCP.

Quickstart

Authenticate with a workspace product key, create a draft, validate every destination, then publish or schedule. The same services power the UI, REST and MCP.

BASE=http://localhost:3000/api/v1   # your app host in production
KEY=pk_v1_…                          # create in /app/developers — shown once

# 1. Pick a real destination ID from your key's allowlist
curl -s -H "Authorization: Bearer $KEY" $BASE/accounts

# 2. Create a draft (permissive; account IDs are UUIDs from step 1).
#    Capture the postId from the response: POST_ID=<postId>
curl -s -X POST $BASE/posts \
  -H "Authorization: Bearer $KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"caption":"A new update from our team.","mediaIds":[],"brandFolderId":null,
       "destinations":[{"accountId":"<uuid-from-accounts>","format":"text"}]}'

# 3. Validate → 4. Publish (202 + delivery IDs) → 5. Observe per destination
curl -s -X POST -H "Authorization: Bearer $KEY" $BASE/posts/$POST_ID/validate
curl -s -X POST -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" $BASE/posts/$POST_ID/publish
curl -s -H "Authorization: Bearer $KEY" $BASE/posts/$POST_ID

Endpoints

Every mutation requires an Idempotency-Key; edits require expectedVersion.

GET /capabilities · GET /accounts
Eligible formats and options for permitted destinations
POST /media/upload-intents
Reserve bytes, return direct upload instructions
POST /media/{id}/finalize
Verify the uploaded asset and make it usable
POST /posts · PATCH /posts/{id}
Create or edit a draft with revision checks
POST /posts/{id}/validate
Structured per-destination issues
POST /posts/{id}/publish
Submit now — returns 202 and job IDs
POST /posts/{id}/schedule
Save an immutable revision + timestamp
POST /deliveries/{id}/cancel · /retry
Cancel when safely possible; retry eligible failures only
GET /usage
Plan, slots, storage and rate info — no post counter

Errors

Normalized errors carry code, message, fieldErrors, destinationErrors, retryable and requestId.

401 unauthenticated
Missing or invalid credentials
403 forbidden_scope / account_not_allowed
Key lacks the scope or account allowlist
409 revision_conflict / idempotency_conflict
Stale version, or key reused with a different body
409 media_expired / media_deleting
Source passed retention or is being removed — re-upload to publish
422 validation_failed
Fix the listed destinations — the audience is never reduced silently
429 rate_limited
Technical rate limit; responses include Retry-After
too_late_to_cancel / submission_unknown
Honest cancellation and unknown-outcome states

MCP

Point your agent at the local stdio adapter with a product key (Node 22+). Tools map one-to-one onto the services above; binary media never flows through tool JSON — uploads return direct instructions.

{
  "mcpServers": {
    "publisher": {
      "command": "node",
      "args": ["/absolute/path/to/packages/mcp/bin/publisher-mcp.mjs"],
      "env": {
        "PUBLISHER_API_URL": "https://app.example.com",
        "PUBLISHER_API_KEY": "pk_v1_…"
      }
    }
  }
}

Managing keys and webhooks from the UI? Open the developer page.