Developers

Build on Posted Once

Automate Posted Once with a simple REST API, or connect AI agents over MCP. Both use the same API keys, both are on the Pro plan, and both are created in Settings.

The API is in beta while platform integrations roll out.

Authentication

Every request is authenticated with a Posted Once API key sent as a Bearer token. Keys start with pok_live_. Create one in Settings, API keys, New key, and copy it right away because it is shown only once. API access is part of the Pro plan.

request header
Authorization: Bearer pok_live_YOUR_KEY
Base URL: https://postedonce.com/api/v1. All responses are JSON. Success responses are wrapped in { "data": ... } and errors in { "error": { "message", "code" } }.

REST API

Four endpoints. The same capabilities as the MCP tools.

GET/v1/channels

List the connected social accounts you can publish to. Use each returned id as an accountId when creating a post.

request
curl https://postedonce.com/api/v1/channels \
  -H "Authorization: Bearer pok_live_YOUR_KEY"
200 response
{
  "data": [
    {
      "id": "acc_9f3a2b",
      "platform": "TWITTER",
      "username": "yourhandle",
      "displayName": "Your Brand",
      "active": true
    }
  ]
}
POST/v1/posts

Create and publish, or schedule, a post to one or more channels. Omit scheduledAt to publish now. Provide platformSchedules to give each platform its own time.

request
curl -X POST https://postedonce.com/api/v1/posts \
  -H "Authorization: Bearer pok_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Big news coming Friday.",
    "accountIds": ["acc_9f3a2b"],
    "scheduledAt": "2026-07-10T14:00:00Z"
  }'
201 response
{
  "data": {
    "id": "post_1a2b3c",
    "status": "SCHEDULED"
  }
}
GET/v1/posts

List your recent posts with per-channel status. Paginate with limit (default 20, max 100) and offset.

request
curl "https://postedonce.com/api/v1/posts?limit=20&offset=0" \
  -H "Authorization: Bearer pok_live_YOUR_KEY"
200 response
{
  "data": [
    {
      "id": "post_1a2b3c",
      "status": "SCHEDULED",
      "content": "Big news coming Friday.",
      "scheduledAt": "2026-07-10T14:00:00Z",
      "publishedAt": null,
      "channels": [
        { "platform": "TWITTER", "status": "PENDING", "platformPostUrl": null }
      ]
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "count": 1,
    "hasMore": false,
    "nextOffset": null
  }
}
GET/v1/posts/{id}

Get one post by id, including every channel's live status, post URL, and any error. Returns 404 if the post is not yours.

request
curl https://postedonce.com/api/v1/posts/post_1a2b3c \
  -H "Authorization: Bearer pok_live_YOUR_KEY"
200 response
{
  "data": {
    "id": "post_1a2b3c",
    "status": "PUBLISHED",
    "content": "Big news coming Friday.",
    "scheduledAt": "2026-07-10T14:00:00Z",
    "publishedAt": "2026-07-10T14:00:04Z",
    "channels": [
      {
        "platform": "TWITTER",
        "status": "PUBLISHED",
        "platformPostUrl": "https://x.com/yourhandle/status/1810000000000000000",
        "errorMessage": null,
        "scheduledAt": "2026-07-10T14:00:00Z",
        "publishedAt": "2026-07-10T14:00:04Z"
      }
    ]
  }
}

MCP for AI agents

MCP lets Claude, Cursor, and other AI agents call the same four actions in plain language, no code required. Add the server to your agent with one command:

terminal
claude mcp add --transport http postedonce \
  https://postedonce.com/api/mcp \
  --header "Authorization: Bearer pok_live_YOUR_KEY"
list_channels

See which social accounts are connected.

create_post

Publish or schedule a post, with a different time per platform if you want.

list_posts

View recent posts and their per-channel status.

get_post

Get the full status of one post, with live links.

Full MCP setup guide

Rate limits

Limits are per API key. All endpoints share a budget of 60 requests per minute. Post creation has a second cap of 60 posts per hour, so a looping agent cannot burn your plan quota or spam your channels. When you are over a limit you get a 429 with a Retry-After header (in seconds).

Errors

Every error uses the same envelope. message is safe to show a user; code is stable for branching in code.

error envelope
{
  "error": {
    "message": "Invalid or unauthorized API key",
    "code": "unauthorized"
  }
}
StatuscodeWhen
401unauthorizedMissing, invalid, or non-Pro API key.
429rate_limitedToo many requests for this key. See the Retry-After header.
400invalid_bodyBody was not valid JSON, or failed validation.
400 / 403create_post_errorA plan limit was hit (monthly, scheduling, or daily platform caps).
404not_foundThe post does not exist, or does not belong to your key.
500internal_errorUnexpected server error. Safe to retry.

Start building

Start free, connect your channels, upgrade to Pro, and create an API key in Settings.

Get your API key