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.
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
- Go to Settings → API. Only owners and admins can manage API keys.
- Under API keys, enter a Key name and choose Create key.
- 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
| Method | Path | Purpose |
|---|---|---|
| GET | /me | The workspace this key belongs to (id, name, plan, time zone) |
| GET | /channels | List channels with ids, networks, posting times and status |
| GET | /channels/:id/settings | Per-post settings a channel accepts, such as a title or board |
| GET | /networks | Supported networks with character and media limits |
| GET | /groups | Client groups and their channel ids |
| GET | /sets | Saved channel sets |
Posts
| Method | Path | Purpose |
|---|---|---|
| GET | /posts?from=&to=&status=&limit= | List posts, oldest first |
| GET | /posts/:id | One post with per-channel status, links and metrics |
| POST | /posts | Create a post |
| PUT | /posts/:id | Change a post. Only the fields you send change |
| PATCH | /posts/:id/status | Move a post between draft and scheduled |
| DELETE | /posts/:id | Delete a post. Copies already published stay on the networks |
| POST | /posts/next-slot | Next free posting time for channelIds |
GET /posts query parameters:
| Parameter | Meaning |
|---|---|
from, to | Date range (ISO 8601) |
status | One or more statuses, comma-separated, for example scheduled,draft |
limit | 1 to 500, default 100 |
Post statuses: draft, pending_approval, scheduled, published, partial (sent on some channels), failed.
Media and templates
| Method | Path | Purpose |
|---|---|---|
| GET | /media?limit= | Recent media (default 30, up to 100) |
| POST | /media | Upload files (multipart, field files) |
| POST | /media/url | Import an image or video from a public url |
| GET | /templates | Saved templates |
Analytics, feeds and notifications
| Method | Path | Purpose |
|---|---|---|
| GET | /analytics?days=30 | Totals, per-channel numbers, follower change and best posts (1 to 90 days) |
| GET | /posts/:id/analytics | One post's engagement per channel, plugs that ran, and link clicks |
| GET | /channels/:id/analytics?days=30 | A channel's follower history and engagement totals |
| GET | /feeds | RSS feeds that create posts |
| GET | /notifications?limit=50 | Recent workspace events such as failures, approvals and reconnects (up to 100) |
Post fields
Use these fields with POST /posts and PUT /posts/:id.
| Field | Type | Required | Meaning |
|---|---|---|---|
content | string | The main text | |
channelIds | array of strings | Yes | Channel ids from GET /channels |
date | string | Yes for POST | ISO 8601 time with a time zone, for example 2026-11-03T09:30:00Z |
action | string | schedule (default for POST /posts), draft or now | |
thread | array of strings | Extra parts, posted as a thread or as comments depending on the network. Up to 25 | |
overrides | object | Different text per channel: { "<channelId>": "text" } | |
settings | object | Per-channel settings: { "<channelId>": { "title": "..." } }. See GET /channels/:id/settings | |
mediaIds | array of strings | Media ids from /media or /media/url. Up to 20 | |
tag | string | none, launch, evergreen, event or promo | |
repeat | object | { "every": 1, "unit": "week", "until": "2027-01-01" }. unit is day, week or month. Send null to stop repeating | |
shortLinks | boolean | Track 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"
Related
- Webhooks: get notified when posts publish or fail.
- MCP and AI agents: connect AI agents to the same tools.