# Docs - Guides: Use the XreplyAI REST API - [Overview](/docs/guides): What the XreplyAI API does and how it is organized. - [Quickstart](/docs/guides/quickstart): Five steps from a fresh API key to a scheduled post. - [Authentication](/docs/guides/authentication): Personal API keys, scopes, and the rules they follow. - [Scheduling](/docs/guides/scheduling): Drafts, exact times, queue slots, dry runs, recurrence, and the post lifecycle. - [Platforms](/docs/guides/platforms): Platform keys, character limits, and supported content types across all 15 platforms. - [Media](/docs/guides/media): Uploading images, video, and documents, and attaching them to posts. - [Webhooks](/docs/guides/webhooks): Signed event deliveries when a scheduled post reaches a terminal state. - [Errors & Rate Limits](/docs/guides/errors-and-rate-limits): The error envelope, the full error catalog, and rate-limit behavior. - API Reference: REST API endpoints, generated from the OpenAPI spec - [API Reference](/docs/api-reference): Every XreplyAI REST API endpoint, generated from the OpenAPI spec. - Account: The authenticated identity behind the key. - [Get the authenticated account](/docs/api-reference/account/getCurrentUser): Returns the account profile, subscription tier, and workspace context. Requires any valid key (no specific scope). - Posts: Create, read, update, schedule, and review posts. - [List posts](/docs/api-reference/posts/listPosts): Requires scope: `posts:read`. Returns the post queue with status counts and a pagination envelope. Defaults to queue statuses (draft, scheduled, etc.) unless `status` is supplied. - [Create a post](/docs/api-reference/posts/createPost): Requires scope: `posts:write`. Supply `post_contents` (one entry per platform) and `social_account_ids`. Omit `scheduled_at` to create a draft. Recurrence fields require a paid plan. - [Create up to 50 posts in one call](/docs/api-reference/posts/bulkCreatePosts): Requires scope: `posts:write`. Each item is created in its own transaction, so a single invalid item does not roll back the others. Returns `201` if any item succeeded, `422` if all failed or if more than 50 items were supplied. - [Approve multiple posts at once](/docs/api-reference/posts/batchApprovePosts): Requires scope: `posts:write`, a Pro/Team plan, and a write role. Approves the supplied post IDs. - [Get a post](/docs/api-reference/posts/getPost): Requires scope: `posts:read`. - [Update a post](/docs/api-reference/posts/updatePost): Requires scope: `posts:write`. A post that is processing or already posted cannot be edited. - [Delete a post](/docs/api-reference/posts/deletePost): Requires scope: `posts:write`. - [Submit a post for review](/docs/api-reference/posts/submitPost): Requires scope: `posts:write` and a write role. Moves a draft into the review queue. - [Approve a post](/docs/api-reference/posts/approvePost): Requires scope: `posts:write` and a Pro/Team plan. Approves a post awaiting review. - [Reject a post](/docs/api-reference/posts/rejectPost): Requires scope: `posts:write` and a Pro/Team plan. Rejects a post awaiting review, optionally with a reason. - [Mint branded short links](/docs/api-reference/posts/createShortLinks): Requires scope `links:write`. Mints a branded short link for each supplied URL and returns a mapping of original URL to short link. Links are keyed per user, so the same URL shortened twice returns the same link and does not consume additional quota. UTM handling: any utm_* params already on the URL are preserved and win; defaults (`utm_source=social`, `utm_medium=social`, a month-bucketed `utm_campaign`) only fill the ones the caller did not set. A URL that is already a short link, or that resolves to a private network address, is skipped. A URL that fails to mint is omitted from `links` rather than failing the whole request. Note posts created via `POST /posts` already shorten their links automatically — this endpoint is for shortening without posting. - A I Generation: Generate post content in your trained voice. - [Generate post content in your voice](/docs/api-reference/ai-generation/generatePost): Requires scope: `ai:generate` and a paid plan. Subject to your plan's daily generation quota. - [Generate a batch of post ideas](/docs/api-reference/ai-generation/generatePostBatch): Requires scope: `ai:generate` and a paid plan. Generates several standalone posts for a category. Shares a 6/min rate-limit bucket with the thread and carousel generators. - [Generate a thread](/docs/api-reference/ai-generation/generateThread): Requires scope: `ai:generate` and a paid plan. Generates a connected thread of posts. Shares a 6/min rate-limit bucket with the batch and carousel generators. - [Generate a LinkedIn carousel](/docs/api-reference/ai-generation/generateCarousel): Requires scope: `ai:generate` and a paid plan. Generates a slide-based carousel document for LinkedIn. A connected LinkedIn account is required. Shares a 6/min rate-limit bucket with the batch and thread generators. - [Generate a reply to a post in your voice](/docs/api-reference/ai-generation/generateReply): Requires scope: `replies:generate` and a paid plan. Subject to your plan's daily generation quota. - [Generate post content from a content idea](/docs/api-reference/ai-generation/generatePostFromIdea): Requires scope: `ai:generate` and a paid plan. Subject to your plan's daily generation quota. `idea` is typically the `seed_prompt` returned by `POST /content_ideas/{id}/use`, but any topic string is accepted. - Publishing: Publish posts now or into the next open schedule slot. - [Publish a post](/docs/api-reference/publishing/publishPost): Requires scope: `publish:write`. Publishes an existing post. Without `scheduled_at` or `use_next_slot` the post is sent immediately. Pass `scheduled_at` to schedule it, or `use_next_slot: true` to queue it into the next open posting-schedule slot. Target accounts default to those already attached to the post; override with `social_account_id(s)`. - [Get the next open posting slot](/docs/api-reference/publishing/getNextSlot): Requires scope: `posts:read`. Returns the earliest open schedule slot for the post's (or supplied) accounts. - Media Uploads: Upload images and video for use in posts. - [Upload media (Facebook, Instagram, Pinterest, TikTok, Threads, Discord, Slack, Telegram, Tumblr, X, Mastodon, Bluesky)](/docs/api-reference/media-uploads/uploadMedia): Requires scope: `publish:write`. Uploads base64-encoded media to storage and returns an `r2_key` to reference from a post's `post_contents` metadata. `platform` selects the size/type limits. For X, Mastodon, and Bluesky the image is minted into the platform's native handle at publish time under each targeted account, so the same `r2_key` works correctly even when a post targets more than one account on that platform. - [Delete an uploaded media file](/docs/api-reference/media-uploads/deleteMedia): Requires scope: `publish:write`. Deletes a previously uploaded file by its `r2_key`. - [Upload an X (Twitter) image](/docs/api-reference/media-uploads/uploadTwitterMedia): Requires scope: `publish:write`. Uploads a base64 image to X and returns a `media_id` for use in a post's metadata. X media IDs are scoped to the uploading account — pass `social_account_id` when the user has more than one X account connected, or the media is minted under the oldest connected account and is invalid for the others. - [Upload a Bluesky image](/docs/api-reference/media-uploads/uploadBlueskyMedia): Requires scope: `publish:write`. Uploads a base64 image and returns a blob reference for use in a post's metadata. - [Upload a Mastodon image](/docs/api-reference/media-uploads/uploadMastodonMedia): Requires scope: `publish:write`. Uploads a base64 image and returns a media reference for use in a post's metadata. - [Upload a LinkedIn image](/docs/api-reference/media-uploads/uploadLinkedinImage): Requires scope: `publish:write`. Uploads a base64 image and returns an `asset_urn` for use in a post's metadata. Asset URNs are scoped to the uploading account — pass `social_account_id` when the user has more than one LinkedIn account connected. - [Upload a LinkedIn document](/docs/api-reference/media-uploads/uploadLinkedinDocument): Requires scope: `publish:write`. Uploads a base64 document and returns a `document_urn` for use in a carousel post's metadata. - [Upload a LinkedIn video](/docs/api-reference/media-uploads/uploadLinkedinVideo): Requires scope: `publish:write`. Uploads a video as `multipart/form-data` (field `video`, max 100 MB, `video/mp4`) and returns an `asset_urn`. Rate-limited to 10 per hour. - [Presign a LinkedIn video upload](/docs/api-reference/media-uploads/presignLinkedinUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT a video (max 100 MB, `video/mp4`) directly to storage, plus the `r2_key` to reference afterward. - [Presign a Pinterest media upload](/docs/api-reference/media-uploads/presignPinterestUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT media directly to storage, plus the `r2_key`. - [Presign a TikTok media upload](/docs/api-reference/media-uploads/presignTiktokUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT media directly to storage, plus the `r2_key`. - [Presign an X (Twitter) video upload](/docs/api-reference/media-uploads/presignTwitterUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT a video (max 500 MB, `video/mp4`) directly to storage, plus the `r2_key` to reference afterward. At publish time the video is uploaded to X via the v2 chunked flow (`media_category=tweet_video`); X enforces a 140-second duration cap. - [Presign a YouTube video upload](/docs/api-reference/media-uploads/presignYoutubeUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT a video (max 4 GB) directly to storage, plus the `r2_key`. - [Presign a Tumblr media upload](/docs/api-reference/media-uploads/presignTumblrUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT media directly to storage, plus the `r2_key`. - [Presign an Instagram media upload](/docs/api-reference/media-uploads/presignInstagramUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT media directly to storage, plus the `r2_key`. - [Presign a Facebook video upload](/docs/api-reference/media-uploads/presignFacebookUpload): Requires scope: `publish:write`. Returns a presigned URL to PUT a video (up to 1 GB) directly to storage, plus the `r2_key`. Facebook presign accepts video content types only; images go through POST /facebook/media_uploads. - [Upload Facebook media](/docs/api-reference/media-uploads/uploadFacebookMedia): Requires scope: `publish:write`. Uploads a base64 image (JPEG/PNG) and returns an `r2_key` to reference from a post's metadata. - [Upload Instagram media](/docs/api-reference/media-uploads/uploadInstagramMedia): Requires scope: `publish:write`. Uploads base64 media (image or video) and returns an `r2_key` to reference from a post's metadata. - [Delete an uploaded Instagram media file](/docs/api-reference/media-uploads/deleteInstagramMedia): Requires scope: `publish:write`. - [Upload Pinterest media](/docs/api-reference/media-uploads/uploadPinterestMedia): Requires scope: `publish:write`. Uploads a base64 image and returns an `r2_key` to reference from a post's metadata. - [Delete an uploaded Pinterest media file](/docs/api-reference/media-uploads/deletePinterestMedia): Requires scope: `publish:write`. - [Upload TikTok media](/docs/api-reference/media-uploads/uploadTiktokMedia): Requires scope: `publish:write`. Uploads a base64 image and returns an `r2_key` to reference from a post's metadata. - [Delete an uploaded TikTok media file](/docs/api-reference/media-uploads/deleteTiktokMedia): Requires scope: `publish:write`. - [Upload Threads media](/docs/api-reference/media-uploads/uploadThreadsMedia): Requires scope: `publish:write`. Uploads a base64 image and returns an `r2_key` to reference from a post's metadata. - [Upload Discord media](/docs/api-reference/media-uploads/uploadDiscordMedia): Requires scope: `publish:write`. Uploads base64 media and returns an `r2_key`. A connected Discord account is required. - [Delete an uploaded Discord media file](/docs/api-reference/media-uploads/deleteDiscordMedia): Requires scope: `publish:write`. Returns `403` if the file is not owned by the caller. - [Upload Slack media](/docs/api-reference/media-uploads/uploadSlackMedia): Requires scope: `publish:write`. Uploads base64 media and returns an `r2_key`. A connected Slack account is required. - [Delete an uploaded Slack media file](/docs/api-reference/media-uploads/deleteSlackMedia): Requires scope: `publish:write`. Returns `403` if the file is not owned by the caller. - [Upload Telegram media](/docs/api-reference/media-uploads/uploadTelegramMedia): Requires scope: `publish:write`. Uploads base64 media and returns an `r2_key`. A connected Telegram account is required. - [Delete an uploaded Telegram media file](/docs/api-reference/media-uploads/deleteTelegramMedia): Requires scope: `publish:write`. Returns `403` if the file is not owned by the caller. - [Upload Tumblr media](/docs/api-reference/media-uploads/uploadTumblrMedia): Requires scope: `publish:write`. Uploads base64 media and returns an `r2_key`. A connected Tumblr account is required. - [Delete an uploaded Tumblr media file](/docs/api-reference/media-uploads/deleteTumblrMedia): Requires scope: `publish:write`. Returns `403` if the file is not owned by the caller. - Social Accounts: Read connected accounts and platform lookups. - [Fetch TikTok creator info for a connected account](/docs/api-reference/social-accounts/getTiktokCreatorInfo): Requires scope: `accounts:read`. Returns the creator's display details and posting capabilities from TikTok, used to populate the composer before a Direct Post. TikTok's Content Sharing Guidelines require the upload UI to name the creator being posted to and to disable any interaction the creator has turned off, so `comment_disabled`, `duet_disabled`, and `stitch_disabled` are creator-level settings that override any per-post choice. - [List per-platform capabilities](/docs/api-reference/social-accounts/listPlatforms): Requires scope: `posts:read`. Returns machine-readable per-platform capabilities (character limits, supported content types, image counts, and media content-type + size limits) so clients don't hardcode them. `content_types` is per-platform truth — only the types the platform can actually publish (e.g. `document` appears only for linkedin, `poll` only for twitter and linkedin, and media-required platforms omit `text`). Fields that don't apply to a platform (`max_images`, `media`) are omitted. - [List connected social accounts](/docs/api-reference/social-accounts/listSocialAccounts): Requires scope: `accounts:read`. Connecting and disconnecting accounts is dashboard-only. - [List saved X communities](/docs/api-reference/social-accounts/listTwitterCommunities): Requires scope: `communities:read`. Returns the X communities you have posted to or saved. - [Search Instagram audio](/docs/api-reference/social-accounts/searchInstagramAudio): Requires scope: `accounts:read`. Searches Instagram audio for reels. A connected Instagram account is required. - [List Pinterest boards](/docs/api-reference/social-accounts/listPinterestBoards): Requires scope: `accounts:read`. Returns the boards on your connected Pinterest account. - Analytics: Post-performance rollups, timeseries, and best-time data. - [Get analytics rollups](/docs/api-reference/analytics/getAnalytics): Requires scope: `analytics:read`. Returns per-account rollups with period-over-period comparison. The date window selects posts by publish time (falling back to scheduled time, then last-modified, when a post has never been published). - [Get analytics timeseries](/docs/api-reference/analytics/getAnalyticsTimeseries): Requires scope: `analytics:read`. Returns a current series and a prior-period comparison series. - [Get best posting times](/docs/api-reference/analytics/getBestTimes): Requires scope: `analytics:read`. Returns day-of-week × hour cells ranked by engagement, plus the single best cell. - Preferences & Styles: Generation preferences and per-platform style profiles. - [Get generation preferences](/docs/api-reference/preferences-and-styles/getPreferences): Requires scope: `preferences:read`. - [Update generation preferences](/docs/api-reference/preferences-and-styles/updatePreferences): Requires scope: `preferences:write`. Merges the supplied fields into existing preferences. - [List per-platform style profiles](/docs/api-reference/preferences-and-styles/listPlatformStyles): Requires scope: `platform_styles:read`. Returns the effective style profile for each platform (defaults merged with your overrides). - [Update a platform style profile](/docs/api-reference/preferences-and-styles/updatePlatformStyle): Requires scope: `platform_styles:write`. Merges the supplied overrides for one platform. - [Reset a platform style profile](/docs/api-reference/preferences-and-styles/resetPlatformStyle): Requires scope: `platform_styles:write`. Clears your overrides for one platform, reverting to defaults. - Rules: Custom rules applied to generated content. - [List custom rules](/docs/api-reference/rules/listCustomRules): Requires scope: `rules:read`. Reads are available on every plan so users can always see rules that steer their generation; writes require a paid plan. - [Create a custom rule](/docs/api-reference/rules/createCustomRule): Requires scope: `rules:write` and a paid plan. - [Get a custom rule](/docs/api-reference/rules/getCustomRule): Requires scope: `rules:read`. Available on every plan. - [Update a custom rule](/docs/api-reference/rules/updateCustomRule): Requires scope: `rules:write` and a paid plan. - [Delete a custom rule](/docs/api-reference/rules/deleteCustomRule): Requires scope: `rules:write` and a paid plan. - [Toggle a custom rule on or off](/docs/api-reference/rules/toggleCustomRule): Requires scope: `rules:write` and a paid plan. Flips the rule's `active` flag. - Schedules & Plans: Posting schedules and content plans. - [List posting schedules](/docs/api-reference/schedules-and-plans/listPostingSchedules): Requires scope: `schedules:read`. Returns each connected account's posting schedule and its slots. - [Update a posting schedule](/docs/api-reference/schedules-and-plans/updatePostingSchedule): Requires scope: `schedules:write` and a write role. Updates schedule settings and/or its slots. - [List content plans](/docs/api-reference/schedules-and-plans/listContentPlans): Requires scope: `plans:read`. Returns your recurring content plans. - [Create a content plan](/docs/api-reference/schedules-and-plans/createContentPlan): Requires scope: `plans:write`. Creates a recurring content plan. - [Run a content plan now](/docs/api-reference/schedules-and-plans/runContentPlan): Requires scope: `plans:write`. Triggers an immediate run of the plan's generation. - [List upcoming open posting slots](/docs/api-reference/schedules-and-plans/listOpenSlots): Requires scope: `schedules:read`. Returns upcoming schedule slots not yet filled by a post, across your connected accounts. - [List content ideas](/docs/api-reference/schedules-and-plans/listContentIdeas): Requires scope: `content_ideas:read`. Returns current content ideas from the planner. - [Refresh content ideas](/docs/api-reference/schedules-and-plans/refreshContentIdeas): Requires scope: `content_ideas:write`. Queues a background refresh of the idea list. Returns 202 with an empty body. - [Dismiss a content idea](/docs/api-reference/schedules-and-plans/dismissContentIdea): Requires scope: `content_ideas:write`. Marks the idea dismissed. Returns 200 with an empty body. - [Use a content idea](/docs/api-reference/schedules-and-plans/useContentIdea): Requires scope: `content_ideas:write`. Marks the idea used and returns a seed prompt for generation. - Voice: The trained voice profile. - [Get the voice profile](/docs/api-reference/voice/getVoiceProfile): Requires scope: `voice:read`. Returns the trained voice profile and per-platform summaries. Raw archive and embeddings are never exposed. - Billing: Read-only subscription and quota. - [Get the current subscription and quota](/docs/api-reference/billing/getCurrentSubscription): Requires scope: `billing:read`. Read-only. Billing mutations (subscribe, cancel, change plan) are dashboard-only. - Quote Week: AI-generated quote-card image runs (Instagram/Pinterest). - [List Quote Week runs](/docs/api-reference/quote-week/listImageWeekRuns): Requires scope: `image_week:read`. Returns the 20 most recent Quote Week runs for the authenticated user, ordered by `created_at` descending. - [Start a Quote Week run](/docs/api-reference/quote-week/createImageWeekRun): Requires scope: `image_week:write` and a paid plan. Creates an `ImageWeekRun` and enqueues `ImageWeekRunJob`, which plans a week of AI quote-card images (Instagram/Pinterest) and generates them with a vision-verify retry loop. Subject to the plan's monthly quota (4 runs/month on Starter, 12 on Pro/Team) — `dry_run: true` requests are exempt. - [Get a Quote Week run](/docs/api-reference/quote-week/getImageWeekRun): Requires scope: `image_week:read`. Poll for run progress. Returns the run plus its full item list. - [Cancel a Quote Week run](/docs/api-reference/quote-week/cancelImageWeekRun): Requires scope: `image_week:write`. Cancels a run that hasn't reached a terminal status yet. No-op if the run is already `completed`, `failed`, or `canceled`. - [Regenerate a failed Quote Week item](/docs/api-reference/quote-week/regenerateImageWeekItem): Requires scope: `image_week:write`. Reprocesses a single `failed` item — resets its attempt count and re-enqueues generation → verify → post-build → slot-fill for that item alone. Only `failed` items can be regenerated (422 `INVALID_STATE` otherwise). - Site Pushes: Push articles from a connected CMS site (e.g. the WordPress plugin). Authenticated by a Site Connection token, not a personal API key. - [Push an article from a connected site](/docs/api-reference/site-pushes/createSitePush): Called by a CMS plugin (e.g. WordPress) when a post is published or updated. Stores the article for the connection's automation rules; enabled rules then create drafts or scheduled posts. Re-pushing the same URL updates the stored article instead of duplicating it. Rate limit: 30 requests per minute per token. - [Get the connection's status and recent pushes](/docs/api-reference/site-pushes/getSitePushStatus): Read-only status for the authenticated Site Connection: connection details, its automation rules, and the 10 most recent pushed articles. Powers the plugin's Test Connection button and status displays. - MCP: XreplyAI MCP server for AI agents - [MCP Server](/docs/mcp): Drive XreplyAI from Claude and any other MCP client. - [Setup](/docs/mcp/setup): Connect the hosted MCP server with OAuth, or run the npm package locally. - [Tools](/docs/mcp/tools): The full catalog of MCP tools, grouped by workflow. - [Security](/docs/mcp/security): The trust boundaries the MCP server is built around.