Integrate agents and external tools with Postger via the REST API or the built-in MCP server.
pg_live_... token — it is shown only once.Create your first draft:
curl -X POST https://app.postger.com/api/v1/posts \
-H "Authorization: Bearer pg_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-first-post-1" \
-d '{
"content": "Hello from the Postger API!",
"channel_id": "<channel id from GET /api/v1/accounts>",
"scheduled_at": "2026-07-10T09:00:00Z",
"status": "draft"
}'Not sure what your channel IDs are? Call GET /api/v1/accounts first, or GET /api/v1/me to see everything the key can do.
Postger ships an MCP server, so assistants like Claude can list your accounts, draft and schedule posts, search your media library, and read analytics — with the permissions you chose, nothing more.
https://app.postger.com/api/v1/mcp as the URL — no API key needed.claude mcp add --transport http postger \ https://app.postger.com/api/v1/mcp \ --header "Authorization: Bearer pg_live_..."
Add this to your client's MCP config (e.g. .cursor/mcp.json):
{
"mcpServers": {
"postger": {
"url": "https://app.postger.com/api/v1/mcp",
"headers": {
"Authorization": "Bearer pg_live_..."
}
}
}
}Tip: create a dedicated key per assistant with only the permissions it needs — e.g. drafting without posts.publish — and watch what it does in Settings → API Keys → Recent activity.
Create an API key in Settings → API Keysand send it as a bearer token. Keys are scoped to one workspace, an account allowlist, and a set of permissions. Effective permissions are the intersection of the key's grants and the issuer's current workspace role — demoting the issuer shrinks their keys.
curl https://app.postger.com/api/v1/me \ -H "Authorization: Bearer pg_live_..."
| Endpoint | Permission | Description |
|---|---|---|
GET /api/v1/me | — | Key context: workspace, permissions, allowed channels |
GET /api/v1/accounts | channels.read | List connected social accounts |
GET /api/v1/posts | posts.read | List posts (filter by status) |
POST /api/v1/posts | posts.write | Create a post (supports Idempotency-Key) |
GET /api/v1/posts/{id} | posts.read | Get a single post |
PATCH /api/v1/posts/{id} | posts.write | Update content, schedule, or images |
DELETE /api/v1/posts/{id} | posts.delete | Delete a post |
POST /api/v1/posts/{id}/schedule | posts.publish | Queue a post for publishing |
POST /api/v1/posts/{id}/cancel | posts.write | Cancel a scheduled post (back to draft) |
GET /api/v1/media | media.read | Search the media library (q, media_type, cursor, limit) |
GET /api/v1/media/{id} | media.read | Get a single media asset |
POST /api/v1/media | media.write | Upload a file, multipart/form-data (supports Idempotency-Key) |
GET /api/v1/analytics/accounts/{id} | analytics.read | Account analytics over a date range |
GET /api/v1/analytics/posts/{id} | analytics.read | Post metrics |
Responses are wrapped in { "data": ... }; errors in { "error": { "code", "message" } }.
Throttled responses return 429 with Retry-After, X-RateLimit-Limit and X-RateLimit-Remaining headers.
POST /api/v1/posts and POST /api/v1/media accept an Idempotency-Key header. Retries with the same key within 24 hours replay the original response (marked with X-Idempotent-Replayed: true). Reusing a key with a different body returns 422; a concurrent duplicate returns 409.
The MCP endpoint lives at POST /api/v1/mcp (JSON-RPC 2.0). Connect with an API key, or via OAuth — Claude Desktop discovers the flow automatically through /.well-known/oauth-protected-resource, registers itself, and asks you to approve access to a workspace.
| Tool | Permission | Description |
|---|---|---|
list_accounts | channels.read | List connected social accounts |
create_post | posts.write | Create a draft or queued post |
list_posts | posts.read | List posts, optionally by status |
get_post | posts.read | Get a post by ID |
update_post | posts.write | Update content, schedule, or images |
schedule_post | posts.publish | Queue a post for publishing |
cancel_post | posts.write | Cancel a scheduled post |
upload_media | media.write | Upload base64-encoded media |
search_media | media.read | Search the media library |
get_media | media.read | Get a media asset by ID |
get_account_analytics | analytics.read | Account analytics |
get_post_analytics | analytics.read | Post metrics |
Errors use a consistent envelope: { "error": { "code", "message" } }.
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, malformed, revoked, or expired token |
| 403 | FORBIDDEN | The key lacks the required permission or channel access |
| 404 | NOT_FOUND | Resource missing or outside the key's scope |
| 409 | IDEMPOTENCY_CONFLICT | The same Idempotency-Key is still being processed |
| 422 | IDEMPOTENCY_KEY_REUSED | Idempotency-Key reused with a different body |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit hit — respect the Retry-After header |