# Post Social > Post Social connects an AI to a person's social accounts (Instagram, Facebook Pages, Threads, YouTube Shorts, TikTok, LinkedIn, Bluesky, X) so the AI can publish, schedule and track posts as the person directs. ## Connect - MCP server (streamable HTTP): https://www.postsocial.xyz/mcp. Sign-in is OAuth 2.1 with dynamic client registration and PKCE (discovery at https://www.postsocial.xyz/.well-known/oauth-protected-resource/mcp), or send an API key: Authorization: Bearer ps_live_... - REST API: https://www.postsocial.xyz/api/v1; OpenAPI 3.1 at https://www.postsocial.xyz/api/v1/openapi.json. Errors are {"error":{"code","message"}}; writes accept an Idempotency-Key header. - CLI: npx postsocial login, then npx postsocial (JSON in, JSON out). npx postsocial upload --file ./clip.mp4 uploads local media. - Docs for people: https://www.postsocial.xyz/docs ## How to post 1. list_social_accounts for account ids and limits. 2. Media must be in Post Social and ready: import_media from a public link (poll get_media), or upload with the CLI. 3. validate_post, then create_post with scheduled_at (ISO 8601; one call per post for a series), or publish: "now" to send right away. Without either, create_post only saves a draft and posts nothing. 4. TikTok posts go direct by default (set privacy_level to the audience the person asked for), or to the creator's TikTok inbox: per post with delivery_mode, or per account with set_tiktok_delivery. 5. A post is live only when list_post_results shows published with a live_url. ## Pricing - Connected accounts 1 and 2 are free (no card). Then per account per month: $5 for accounts 3–10, $2.50 for 11–100, $1 for 101 and up; usage based, prorated for the days an account is connected. X posts 2¢ each, 25¢ with a link, first $1 a month free, under a monthly cap the person sets. Details: https://www.postsocial.xyz/docs/billing ## Tools (MCP name = REST operationId; CLI command uses hyphens) - get_workspace (GET /api/v1/me): Shows which Post Social workspace this key acts for, the key's name, and whether it is a live or test key (test keys cannot publish). - list_social_accounts (GET /api/v1/accounts): Lists the social accounts connected to Post Social, with their ids, health, profile and what each can post (capabilities and limits). - request_connect_link (POST /api/v1/accounts/connect-link): Returns a link the person opens to connect a social account in Post Social. Accounts can only be connected by the person, never by an AI. - list_profiles (GET /api/v1/profiles): Lists the profiles accounts are grouped under (a business, organisation or client), with how many connected accounts each has. Filter list_social_accounts by profile_id to see a profile's accounts. - create_profile (POST /api/v1/profiles): Creates a profile to group accounts under, such as a business, organisation or client. - update_profile (PATCH /api/v1/profiles/{profile_id}): Changes a profile's name, description, colour or time zone. Leave out what stays the same. - delete_profile (DELETE /api/v1/profiles/{profile_id}): Deletes a profile. Its accounts stay connected and move to no profile. - move_account_to_profile (POST /api/v1/accounts/{account_id}/profile): Puts a connected account in a profile, or in no profile when profile_id is none. - set_tiktok_delivery (POST /api/v1/accounts/{account_id}/tiktok-delivery): Sets how this TikTok account receives AI posts: direct (the default) posts straight away; inbox sends each post to the creator's TikTok inbox to finish and post in TikTok. Posts that leave delivery_mode out follow this; an account set to inbox refuses direct posts. Change it only when the person asks. - list_media (GET /api/v1/media): Lists uploaded and imported media, newest first. Only media with status ready can be posted. - get_media (GET /api/v1/media/{media_id}): Gets a media item's details and status. Ready items include a temporary view link (valid 1 hour). - import_media (POST /api/v1/media/import): Copies an image or video from a public https link into Post Social. It is checked in the background; poll get_media until status is ready (or failed, with a reason). - start_media_upload (POST /api/v1/media/uploads): For tools that can send files (CLI, scripts). Returns upload links: PUT each part's bytes to its url, keep each response's ETag, then call finish_media_upload. Links last 1 hour. single_part: true returns one link for the whole file (for tools that send a file in one request, like Apple Shortcuts). - finish_media_upload (POST /api/v1/media/{media_id}/complete): Completes an upload started with start_media_upload. The file is then checked in the background; poll get_media until status is ready. parts can be left out when the tool can't read ETags; Post Social then reads them from storage. - delete_media (DELETE /api/v1/media/{media_id}): Removes a media item from the library. Files used by a post are kept until that post no longer needs them; unused files are deleted automatically later. - validate_post (POST /api/v1/posts/validate): Checks a proposed post against every chosen platform's rules (caption length, media shape and length, post types) without saving anything. Returns plain-language problems per account. Each account is named by its profile name (account), its platform and its handle (account_handle, without the @; null for LinkedIn, Facebook Pages and YouTube, which share no handle with Post Social), so two accounts with the same name can be told apart. - create_post (POST /api/v1/posts): Creates a post for one or more accounts. It is sent only when you say when: scheduled_at publishes at that time, publish: "now" publishes right away. Without either (or with draft: true) it is only saved as a draft and nothing is posted; tell the person, and call publish_post when they want it sent. To schedule a series, call it once per post with each time. Unknown fields are refused. The result's next_step says what happens. If the post has problems it is saved as a draft and the problems are returned. - list_posts (GET /api/v1/posts): Lists posts, newest first. Each post has published_at (when it first went out on any account; null until then), its destinations (one per account: status, live_url, published_at, error) and media (in order: id, media_type, mime_type, name, status, width, height, duration_seconds, url and thumbnail_url; url and thumbnail_url are temporary view links valid 1 hour, null until the item is ready; thumbnail_url is the image itself or a video's poster frame). Each account is named by its profile name (account), its platform and its handle (account_handle, without the @; null for LinkedIn, Facebook Pages and YouTube, which share no handle with Post Social), so two accounts with the same name can be told apart. - get_post (GET /api/v1/posts/{post_id}): Gets one post with its caption, published_at (when it first went out on any account; null until then), each account's status, live_url, published_at and errors, its approval state, media_ids and media (in order: id, media_type, mime_type, name, status, width, height, duration_seconds, url and thumbnail_url; url and thumbnail_url are temporary view links valid 1 hour, null until the item is ready; thumbnail_url is the image itself or a video's poster frame). Each account is named by its profile name (account), its platform and its handle (account_handle, without the @; null for LinkedIn, Facebook Pages and YouTube, which share no handle with Post Social), so two accounts with the same name can be told apart. If the post is publishing right now, waits up to about 25 seconds for the accounts still sending, so the live links are usually all there. - update_post (PATCH /api/v1/posts/{post_id}): Edits a draft, a post waiting for approval, or a scheduled post: its caption, time, media or accounts. Only the fields you pass change; media_ids and destinations each replace the whole list (to swap an image, upload the new one and pass its id in media_ids). To change a scheduled post, edit it here instead of creating a new post, which would publish twice. Editing an approved or scheduled post may send it back for approval. - publish_post (POST /api/v1/posts/{post_id}/publish): Publishes a draft now, or schedules it with scheduled_at. - reschedule_post (POST /api/v1/posts/{post_id}/reschedule): Changes the time of a scheduled post that has not started sending. - cancel_post (POST /api/v1/posts/{post_id}/cancel): Cancels a draft, a post waiting for approval, or a scheduled post before it starts sending. Posts already sent cannot be cancelled. - delete_post (DELETE /api/v1/posts/{post_id}): Permanently deletes a draft or a cancelled post. Sent posts are kept for the record. - get_usage (GET /api/v1/usage): Shows usage for a period: posts published (by account and by who made them), posts created by AI, failed publishes, API calls per connection, a day-by-day series, and how close the workspace is to each plan limit. - list_analytics (GET /api/v1/analytics): Lists published posts with their stats (views, likes, comments, shares, and saves, reposts or quotes where the platform reports them), plus totals per platform. Sort by any stat to find what performed best. - get_post_analytics (GET /api/v1/posts/{post_id}/analytics): Shows one post's stats on each platform it went to, with a day-by-day history. - refresh_analytics (POST /api/v1/analytics/refresh): Fetches fresh stats from the platforms for one post (or all recent posts) instead of waiting for the next automatic update. At most every 30 minutes per post. - list_post_results (GET /api/v1/results): Shows each account's outcome: published (with the live link), failed (with the platform's reason in plain language), or still in progress. One post's results (waiting up to about 25 seconds for accounts still sending), or the most recent overall. Each account is named by its profile name (account), its platform and its handle (account_handle, without the @; null for LinkedIn, Facebook Pages and YouTube, which share no handle with Post Social), so two accounts with the same name can be told apart.