PostQueueHD
Log in

API v1

API reference

Schedule and manage posts from your own code, a script or an AI agent.

https://postqueuehd.com/api/v1

Authentication

Every request needs a bearer token, created under Settings → API.

Authorization: Bearer pq_live_xxxxxxxx

The token is shown once, at creation, and stored only as a hash. If it is lost, revoke it and make another.

The API is included in paid plans. A valid token on the free plan answers 403, not 401 — the token is fine, the plan is not.

Errors

One shape for everything, so a client parses one thing:

{
  "message": "Pick at least one channel.",
  "errors": { "channels": ["Pick at least one channel."] }
}
Status Meaning
401 No token, or the token is unknown, revoked or expired
403 The token is valid but the plan does not include the API
404 No such post, or it belongs to another team
422 The payload or a plan limit rejected the request
429 Rate limited — wait for the seconds in Retry-After

Rate limits

Per token: 60 reads a minute and 20 writes a minute. Over the limit answers 429 with a Retry-After header.

GET /api/v1/me

What this token can do

The team the token belongs to, its plan, and how much of each allowance is left. Call this first: it answers what you are allowed to do without having to fail a write to find out.

curl https://postqueuehd.com/api/v1/me \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

GET /api/v1/channels

The channels you can publish to

Every connected channel with its provider and status. The `id` values here are what `POST /posts` expects in `channels`. A channel whose `needs_attention` is true will refuse to publish until it is reconnected.

curl https://postqueuehd.com/api/v1/channels \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

GET /api/v1/posts

The queue

Posts newest-cued first, cursor-paginated. Follow `links.next` to page.

Field Type Required Notes
status string no draft, scheduled, publishing, published, partially_failed, failed or cancelled
per_page integer no Up to 100. Defaults to 25.
curl "https://postqueuehd.com/api/v1/posts?status=scheduled" \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

GET /api/v1/posts/{id}

One post

A single post with one target per channel, each carrying its own status. An id belonging to another team answers 404, exactly like an id that does not exist.

curl https://postqueuehd.com/api/v1/posts/42 \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

POST /api/v1/posts

Schedule a post

Creates a post and one target per channel. Leave `scheduled_for` out to publish as soon as possible. Send the same `idempotency_key` twice and you get the same post back, which is what makes retrying after a timeout safe.

Field Type Required Notes
caption string no Up to 5000 characters. Each platform truncates to its own limit.
channels integer[] yes Channel ids from GET /channels.
scheduled_for ISO 8601 no Must be in the future. Omit to publish now.
media_ids integer[] no Media already uploaded to this team.
idempotency_key string no Up to 64 characters. Reuse it to make a retry safe.
channel_captions object no Per-channel caption override, keyed by channel id.
channel_options object no Per-channel platform options, keyed by channel id.
curl -X POST https://postqueuehd.com/api/v1/posts \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Summer drop is live",
    "channels": [1, 2],
    "scheduled_for": "2026-08-01T18:30:00Z",
    "idempotency_key": "summer-drop-1"
  }'

DELETE /api/v1/posts/{id}

Cancel a cued post

Cancels every channel that has not gone out yet. Anything already published is history and stays as it is; if every channel is already publishing, this answers 422.

curl -X DELETE https://postqueuehd.com/api/v1/posts/42 \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

GET /api/v1/media

The media you have uploaded

Everything this team has uploaded, newest first, cursor-paginated. Transcoded variants are left out: they are built per platform and are not something you refer to. Use this to reuse a file you already sent rather than uploading it twice.

Field Type Required Notes
per_page integer no Up to 100. Defaults to 25.
curl https://postqueuehd.com/api/v1/media \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

POST /api/v1/media

Start an upload

Reserves a media row and answers with somewhere to PUT the file. The bytes go to the URL that comes back, not to this endpoint, so a large video is never held in a JSON request. Your plan limits are checked here, before you send anything — a file over the limit is refused now rather than after the upload finishes. Send a sha256 `checksum` and a file already uploaded answers 200 with `already_uploaded: true` and no upload target, because there is nothing left to send.

Field Type Required Notes
filename string yes The original name. Its extension decides the stored one.
mime_type string yes Anything starting image/ is an image; everything else is treated as video.
size_bytes integer yes Checked against the plan's video size and storage allowance before you upload.
checksum string no sha256 of the file, 64 hex characters. A match reuses the existing media instead of uploading again.
# 1. reserve the row and read the upload target
curl -X POST https://postqueuehd.com/api/v1/media \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "summer.mp4",
    "mime_type": "video/mp4",
    "size_bytes": 8412345
  }'

# 2. send the bytes where it told you to
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/mp4" \
  --data-binary @summer.mp4

POST /api/v1/media/{id}/complete

Finish an upload

Confirms the bytes arrived and starts the probe that reads the dimensions, duration and codecs. Answers 422 if nothing was uploaded. The probe runs in the background, so this does not mean the file is usable yet — poll `GET /media/{id}` until the status is `ready`.

curl -X POST https://postqueuehd.com/api/v1/media/91/complete \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

GET /api/v1/media/{id}

One piece of media

The status, and what the probe found. Status walks `uploaded` → `probing` → `ready`, or `failed` with the reason in `error`. Only `ready` media is worth scheduling: a failed file will not publish, and the `error` says why in words you can pass on to whoever supplied it.

curl https://postqueuehd.com/api/v1/media/91 \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

DELETE /api/v1/media/{id}

Delete media

Deletes the file and everything transcoded from it, freeing the storage against your plan. Media still attached to a post that has not gone out answers 422 — cancel the post first. Media whose posts have all published can go; it would be deleted by the retention window anyway.

curl -X DELETE https://postqueuehd.com/api/v1/media/91 \
  -H "Authorization: Bearer $POSTQUEUE_TOKEN"

For AI agents

Point your agent at one of these instead of at this page — both are plain text and read in a single fetch.

This works with Claude, Gemini, ChatGPT or anything else that can fetch a URL — there is nothing to install.

Read https://postqueuehd.com/docs/api.md and schedule a post for tomorrow at 18:30 on every connected channel.