REST API

Schedule and manage Postline posts from your own code with the REST API: authentication, rate limits, every endpoint, post fields and curl examples.

On this pageBase URLAuthenticationRate limitEndpointsPost fieldsExamplesRelated

Base URL

All paths start with:

https://your-postline-address/api/public/v1

Responses are JSON with the result in data:

{ "data": { ... } }

Errors come back as { "error": "message" } with an HTTP error status.

Authentication

  1. Go to Settings → API. Only owners and admins can manage API keys.
  2. Under API keys, enter a Key name and choose Create key.
  3. Copy the key. It starts with pl_. You won't be able to see it again.

Send the key in the Authorization header:

Authorization: Bearer pl_...

A key belongs to one workspace and has admin access to it. Posts you create with a key are scheduled right away, even if the workspace requires approval. Choose Revoke to turn a key off.

Rate limit

120 requests per minute. Over the limit, you get HTTP 429.

Endpoints

Workspace and channels

MethodPathPurpose
GET/meThe workspace this key belongs to (id, name, plan, time zone)
GET/channelsList channels with ids, networks, posting times and status
GET/channels/:id/settingsPer-post settings a channel accepts, such as a title or board
GET/networksSupported networks with character and media limits
GET/groupsClient groups and their channel ids
GET/setsSaved channel sets

Posts

MethodPathPurpose
GET/posts?from=&to=&status=&limit=List posts, oldest first
GET/posts/:idOne post with per-channel status, links and metrics
POST/postsCreate a post
PUT/posts/:idChange a post. Only the fields you send change
PATCH/posts/:id/statusMove a post between draft and scheduled
DELETE/posts/:idDelete a post. Copies already published stay on the networks
POST/posts/next-slotNext free posting time for channelIds

GET /posts query parameters:

ParameterMeaning
from, toDate range (ISO 8601)
statusOne or more statuses, comma-separated, for example scheduled,draft
limit1 to 500, default 100

Post statuses: draft, pending_approval, scheduled, published, partial (sent on some channels), failed.

Media and templates

MethodPathPurpose
GET/media?limit=Recent media (default 30, up to 100)
POST/mediaUpload files (multipart, field files)
POST/media/urlImport an image or video from a public url
GET/templatesSaved templates

Analytics, feeds and notifications

MethodPathPurpose
GET/analytics?days=30Totals, per-channel numbers, follower change and best posts (1 to 90 days)
GET/posts/:id/analyticsOne post's engagement per channel, plugs that ran, and link clicks
GET/channels/:id/analytics?days=30A channel's follower history and engagement totals
GET/feedsRSS feeds that create posts
GET/notifications?limit=50Recent workspace events such as failures, approvals and reconnects (up to 100)

Post fields

Use these fields with POST /posts and PUT /posts/:id.

FieldTypeRequiredMeaning
contentstringThe main text
channelIdsarray of stringsYesChannel ids from GET /channels
datestringYes for POSTISO 8601 time with a time zone, for example 2026-11-03T09:30:00Z
actionstringschedule (default for POST /posts), draft or now
threadarray of stringsExtra parts, posted as a thread or as comments depending on the network. Up to 25
overridesobjectDifferent text per channel: { "<channelId>": "text" }
settingsobjectPer-channel settings: { "<channelId>": { "title": "..." } }. See GET /channels/:id/settings
mediaIdsarray of stringsMedia ids from /media or /media/url. Up to 20
tagstringnone, launch, evergreen, event or promo
repeatobject{ "every": 1, "unit": "week", "until": "2027-01-01" }. unit is day, week or month. Send null to stop repeating
shortLinksbooleanTrack link clicks in this post, when the workspace is set to ask per post

A post needs text or at least one file. Postline checks each channel's rules (character limits, media, required settings) when you schedule, and returns HTTP 422 with the problems if something doesn't fit. Drafts aren't checked.

Examples

Set up a helper:

export POSTLINE_URL=https://your-postline-address
export POSTLINE_API_KEY=pl_...
API="$POSTLINE_URL/api/public/v1"

List channels:

curl "$API/channels" \
  -H "Authorization: Bearer $POSTLINE_API_KEY"

Schedule a post:

curl -X POST "$API/posts" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"Hello from the API","channelIds":["CHANNEL_ID"],"date":"2026-11-03T09:30:00Z"}'

Save a draft with different text on one channel:

curl -X POST "$API/posts" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"Our new guide is live.","channelIds":["X_ID","LINKEDIN_ID"],"overrides":{"LINKEDIN_ID":"Our new guide is live. Here is what is inside."},"date":"2026-11-03T09:30:00Z","action":"draft"}'

Find the next free posting time:

curl -X POST "$API/posts/next-slot" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channelIds":["CHANNEL_ID"]}'

Schedule a draft:

curl -X PATCH "$API/posts/POST_ID/status" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"scheduled"}'

Change only the time:

curl -X PUT "$API/posts/POST_ID" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-11-04T15:00:00Z"}'

Import an image, then use its data.id in mediaIds:

curl -X POST "$API/media/url" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/photo.jpg"}'

Upload a local file:

curl -X POST "$API/media" \
  -H "Authorization: Bearer $POSTLINE_API_KEY" \
  -F "files=@./photo.jpg"