# PostAgent > Social media scheduling API built for AI agents. One POST schedules a post > to any combination of X (Twitter), LinkedIn, Facebook, Instagram, YouTube, > TikTok and Bluesky. Base URL: https://postagent.pro/api/v1 Authentication: HTTP header `Authorization: Bearer sk_live_...` API keys are created by a human at https://postagent.pro/developers (session-only page). Full OpenAPI spec: https://postagent.pro/api/v1/openapi.json Human docs: https://postagent.pro/docs MCP server (Streamable HTTP): https://postagent.pro/api/mcp — tools: schedule_post, list_accounts, list_posts, cancel_post. Same Bearer key. ## The one call that matters POST /api/v1/posts ``` curl https://postagent.pro/api/v1/posts \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: any-unique-string" \ -d '{ "content": "We just shipped something new", "media": [{"url": "https://example.com/launch.png", "type": "image"}], "targets": ["x", "linkedin"], "schedule_at": "2026-07-08T09:00:00Z" }' ``` Rules: - targets: array of platform names ("x", "linkedin", "facebook", "instagram", "youtube", "tiktok", "bluesky") or objects {"platform", "account_id"?, "content"?, "options"?}. A bare platform name works when the user has exactly one connected account on that platform; otherwise the error tells you the valid account_ids. - schedule_at: ISO 8601. Omit it to publish immediately. - "status": "draft" holds the post without scheduling. - media: optional [{url, type: "image"|"video"}]. YouTube and TikTok require a video. X and LinkedIn are text-only for now. - content: per-platform limits apply (X 280, Instagram/TikTok 2200, LinkedIn 3000, YouTube 5000). Override per platform with targets[].content. - Idempotency-Key header (or idempotency_key body field): retries with the same key return the original post (200 + Idempotency-Replayed: true) instead of double-posting. ## Discovering valid targets GET /api/v1/accounts -> the user's connected social accounts (use their "id" as account_id; "simulated": true means test mode) GET /api/v1/platforms -> per-platform capabilities and char limits (public) ## Managing posts GET /api/v1/posts list (filters: ?status=, ?scheduled_after=, ?scheduled_before=, pagination: ?limit=, ?starting_after=) GET /api/v1/posts/{id} retrieve with per-target publish status PATCH /api/v1/posts/{id} edit content/media/targets/schedule_at while draft or scheduled POST /api/v1/posts/{id}/publish publish a draft or scheduled post now DELETE /api/v1/posts/{id} cancel a scheduled post / delete a draft Post lifecycle: draft -> scheduled -> publishing -> published | partial | failed (canceled via DELETE). Each target carries its own status, platform_post_id, platform_post_url and error. Failed targets retry up to 3 times with exponential backoff. ## Errors Every non-2xx response is: {"error": {"type", "code", "message", "param"?}} Types: invalid_request_error (400), authentication_error (401), permission_error (403), not_found_error (404), idempotency_error (409), api_error (500). Messages are written to be actionable — read them. ## Simulated mode Platforms without configured credentials run simulated: connecting creates a fake account instantly and publishing succeeds with a fake sim_* post id and "simulated": true on the target. Everything else behaves identically, so you can build and test against the full API without any platform credentials.