# PostPlain API > PostPlain Agent-Native Social Media Scheduling API. Schedule posts to X, LinkedIn, Threads, and Facebook. Authenticate with a Bearer token using your mp_ prefixed API key. Version: 1.0.0 Base URL: https://postplain.com/api/v1 ## Authentication All API requests require a Bearer token. Use your PostPlain API key (prefixed with `mp_`). ``` Authorization: Bearer mp_your_api_key ``` ## Machine-readable formats - OpenAPI spec: https://postplain.com/openapi.json - Interactive docs: https://postplain.com/docs - Agent manifest: https://postplain.com/.well-known/agent.json --- ## Account ### GET /accounts List connected accounts Returns all social media accounts connected to your team, including platform, username, character limits, and connection timestamps. **Responses:** 200 () ### POST /accounts/connect/{platform} Connect an account Initiate an OAuth connection for a social platform. Returns a URL that a human must visit to complete the OAuth flow. Supported platforms: x, linkedin, threads, facebook. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | platform | path | string | yes | | **Responses:** 200 () ### DELETE /accounts/{account} Disconnect an account Remove a connected social media account from your team. This is a soft delete; previously published posts are not affected. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | account | path | integer | yes | The account ID | **Responses:** 200 (), 404 () --- ## Health ### GET /health Health check Returns the current health status of the API. This endpoint is unauthenticated and can be used to verify connectivity before making authenticated requests. Authentication: none required **Responses:** 200 () --- ## Limits ### GET /limits Get plan limits Returns your team's current plan details, post usage, rate limits, connected account count, and per-platform character constraints. Use this before scheduling to check remaining quota. **Responses:** 200 () --- ## Post ### POST /posts/schedule Schedule a post Schedule a post to one or more connected social accounts. If `scheduled_at` is omitted, the post begins publishing in the background immediately after creation. Supports idempotency keys to prevent duplicate posts. **Request body** (application/json): | Field | Type | Required | Description | |-------|------|----------|-------------| | text | string | yes | | | scheduled_at | string|null | no | | | idempotency_key | string|null | no | | | account_ids | array<integer> | yes | | | media_urls | array|null<string> | no | | | platform_overrides | object | no | | **Responses:** 200 (), 422 () ### POST /posts/bulk-schedule Bulk schedule posts Schedule up to 50 posts in a single request. Each post is processed independently; failures for individual posts do not affect others. Returns separate arrays of scheduled and failed posts. **Request body** (application/json): | Field | Type | Required | Description | |-------|------|----------|-------------| | posts | array<object> | yes | | **Responses:** 200 (), 422 () ### GET /posts/{post} Get a post Retrieve full details of a specific post, including per-platform publishing status, platform post IDs, and timestamps. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | post | path | integer | yes | The post ID | **Responses:** 200 (), 404 () ### DELETE /posts/{post} Cancel a scheduled post Cancel a post that has not yet been published. Only posts with status `scheduled` can be cancelled. Already published or failed posts cannot be cancelled. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | post | path | integer | yes | The post ID | **Responses:** 200 (), 404 () ### GET /posts/{post}/analytics Get post analytics Retrieve engagement analytics for a published post, broken down by platform. Includes impressions, likes, comments, shares, and clicks. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | post | path | integer | yes | The post ID | **Responses:** 200 (), 404 () ### GET /posts List posts Returns a paginated list of posts. Filter by status (scheduled, publishing, published, failed, cancelled), platform (x, linkedin, threads, facebook, bluesky), or date range (from/to as ISO 8601). **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | status | query | string | no | | | platform | query | string | no | | | from | query | string | no | | | to | query | string | no | | | per_page | query | string | no | | **Responses:** 200 () --- ## Webhook ### POST /webhooks Create a webhook Register a URL to receive POST notifications for specified events. Returns a signing secret (whsec_ prefixed) for verifying webhook payloads. Available events: post.published, post.failed, account.connected, account.disconnected. All webhook payloads follow a standard envelope: `{"event": "post.published", "timestamp": "2026-04-01T09:00:05Z", "data": {...}}`. See the WebhookPayload_PostPublished, WebhookPayload_PostFailed, WebhookPayload_AccountConnected, and WebhookPayload_AccountDisconnected component schemas for full payload details. **Request body** (application/json): | Field | Type | Required | Description | |-------|------|----------|-------------| | url | string | yes | | | events | array<string> | yes | | **Responses:** 200 (), 422 () ### GET /webhooks List webhooks Returns all webhook subscriptions for your team. **Responses:** 200 () ### PUT /webhooks/{webhook} Update a webhook Modify a webhook's URL, events, or active status. Only provided fields are updated. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | webhook | path | integer | yes | The webhook ID | **Request body** (application/json): | Field | Type | Required | Description | |-------|------|----------|-------------| | url | string | no | | | is_active | boolean | no | | | events | array<string> | no | | **Responses:** 200 (), 422 (), 404 () ### DELETE /webhooks/{webhook} Delete a webhook Permanently remove a webhook subscription. No further events will be delivered to this URL. **Parameters:** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | webhook | path | integer | yes | The webhook ID | **Responses:** 200 (), 404 ()