Docs/API Reference

API Reference

The Crosspostify API is organized around REST. It accepts JSON request bodies (Content-Type: application/json), and multipart/form-data for media uploads. It returns JSON responses and uses standard HTTP status codes.

A typical flow: upload a file with POST /media, use the returned id in a /post/image, /post/images or /post/video request (or send text only with /post/text), then check the result with GET /posts?id=<id>. The posting endpoints answer 202 Accepted: publishing happens afterwards, and a platform can still reject a post at that point (its status then becomes FAILED with an error).

Not a developer?

Use Crosspostify's dashboard to get started with social media posting.

Base URL

https://v1.api.crosspostify.com

Routes sit directly at the root, without a version prefix (for example https://v1.api.crosspostify.com/post/video). GET /health needs no API key and returns {"status": "ok"}, which is handy for uptime checks.

Platform Guides

While our API endpoints remain consistent across platforms, each social network has specific capabilities, limitations, and best practices. Select a platform below to view detailed requirements for posting to that network.

Authentication

All API requests require authentication using an API key. Include your API key in the X-API-Key header with every request.
The API key can be retrieved on the API page of the Crosspostify App.

API access requires a Pro or Business plan. Requests with a key from another plan are rejected with 401 Invalid API key. A request without a key gets 401 API key is required.

Keep your API key secure

Your API key carries many privileges, so be sure to keep it secure! Do not share your secret API key in publicly accessible areas such as GitHub, client-side code, and so forth.

Safe retries with X-Request-ID

The four posting endpoints (/post/image, /post/images, /post/video, /post/text) accept an optional X-Request-ID header (up to 200 characters) that protects you from posting twice:

  • If a request times out, send it again with the same X-Request-ID.
  • If the first request succeeded within the last 10 minutes, you get its original answer again, with the response header Idempotent-Replay: true. No new posts are created.
  • If the first request is still being processed, you get 409 Duplicate request. Retry a little later with the same ID.
  • If the first request failed (4xx or 5xx), the retry runs normally.
  • Use a new ID for every new post: the ID is not tied to the endpoint or the request body.
X-Request-ID: 9b2e4c1a-5f7d-4e8b-a3c6-0d1f2e3a4b5c

Rate Limits

To ensure fair usage and maintain service quality, the Crosspostify API implements rate limiting:

Per API key
250 requests per hour
Per API key (burst)
50 requests per minute
Per social account (posting)
30 posts per minute
Per social account (posting)
150 posts per day (UTC)

The per-key limits are shared by all endpoints, and every request counts, including failed ones. The per-account limits apply only to the four /post/* endpoints. Each entry in posts counts once, and a scheduled post counts toward the UTC day of its scheduledDate.

When you exceed a rate limit, you receive a 429 status code. The body tells you which limit was hit. The per-account minute limit includes retry_after (seconds until the next minute starts). No Retry-After header is sent. We recommend implementing exponential backoff in your applications.

Per API key

{ "error": "Rate limit exceeded", "limits": { "hourly": "250 requests per hour", "minute": "50 requests per minute" }, "message": "Too many requests" }

Per social account, minute

{ "error": "Rate limit exceeded", "message": "Maximum 30 requests per minute reached for account acc_789", "remaining": 0, "retry_after": 42 }

Per social account, day

{ "error": "Daily posting limit exceeded", "message": "Maximum 150 posts per day reached for account acc_789", "remaining": 0 }

Errors

Crosspostify uses conventional HTTP response codes to indicate the success or failure of an API request.

200
OK

Everything worked as expected.

201
Created

Media uploaded (POST /media).

202
Accepted

Posts created and queued or scheduled (POST /post/*). Publishing happens afterwards; check GET /posts.

400
Bad Request

The request was invalid, for example a missing or invalid field. The body says what is wrong.

401
Unauthorized

Missing API key (API key is required), unknown key, or a plan without API access (Invalid API key). API access requires a Pro or Business plan.

403
Forbidden

Only posts with status SCHEDULED can be deleted.

404
Not Found

The requested resource does not exist or does not belong to your account.

409
Conflict

A request with the same X-Request-ID is still being processed, or the media is used by a scheduled post.

413
Payload Too Large

Request body larger than 110 MB.

415
Unsupported Media Type

Posting endpoints need Content-Type: application/json.

429
Too Many Requests

A rate limit was hit. See Rate Limits.

500
Server Error

Something went wrong on Crosspostify's end.

503
Service Unavailable

Temporary problem; retry with backoff.

Error bodies are JSON with an error string and usually a message. Some add fields such as invalid_accounts, accountId, max_images, remaining or retry_after.

Common posting errors

These come from the four /post/* endpoints. The error value is shown.

StatuserrorWhen
400No JSON data providedThe body is empty.
400No posts providedposts is missing or empty.
400Invalid post format - missing accountIdAn entry in posts has no accountId.
400No media ID provided / No media IDs provided or invalid formatmediaId (or mediaIds) is missing.
400Invalid media / Invalid media IDThe media does not exist, is not yours or has the wrong type. message says why (for Pinterest also: images with different aspect ratios).
400Invalid date formatscheduledDate is not an ISO 8601 date-time.
400Scheduled date must be in the futurescheduledDate is now or in the past.
404One or more social accounts not found or unauthorizedAn accountId does not exist or is not yours.
400Unsupported platformsAn account platform is not supported by this endpoint. invalid_accounts lists them as accountId:platform.
400Missing boardIdA Pinterest post has no boardId. accountId names the post.
400Too many imagesMore mediaIds than a platform allows. Includes platform, max_images and affected_accounts.
400Missing caption/post/text with an empty caption.
400Invalid textFormatPresetId/post/text: textFormatPresetId is not an integer or numeric string.
400Invalid <field>An on/off option is not true or false, e.g. Invalid is_aigc or Invalid tiktok.disable_duet.
400Invalid tiktok.privacy_levelNot one of PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY.
400Invalid tiktok.photo_cover_indexNot a whole number of 0 or more.
400Invalid tiktok settingstiktok is not an object, or branded content is set to private (SELF_ONLY).
400Invalid instagram.trial_reelNot MANUAL or SS_PERFORMANCE.
400Invalid instagram settings / Invalid facebook settingsThe value is not an object, or as_story is set with more than one image.
400Invalid youtube.privacyStatus / Invalid youtube settingsprivacyStatus is not public, unlisted or private, or youtube is not an object.
409Duplicate requestA request with the same X-Request-ID is still being processed.
415415 Unsupported Media Type: ...Content-Type is not application/json.

A 202 means the posts were accepted, not published. A platform can still reject a post later; its status in GET /posts then becomes FAILED with an error text.

Endpoints

Below are all the available API endpoints organized by functionality.

POST/post/image

Create a new single image post across multiple social media platforms.

Platform Support & Notes

  • Supported for TikTok, Instagram, Facebook, LinkedIn, Pinterest, Tumblr, Bluesky and Threads (not YouTube)
  • title is used by TikTok (photo title), Pinterest (pin title), Tumblr (heading) and LinkedIn (media title). Other platforms ignore it. Maximum 90 characters; longer titles are cut.
  • link is used by Pinterest (pin destination) and Tumblr (source link). Other platforms ignore it.
  • boardId is mandatory for every Pinterest Account
  • Instagram and Facebook can post the image as a Story (instagram.as_story / facebook.as_story)
  • For TikTok, Instagram and Facebook, images are converted to JPEG. Instagram feed images outside 4:5 to 1.91:1 get white borders (they are never cropped). Instagram Story images are scaled to fit 1080×1920 and keep their aspect ratio.
  • scheduledDate is an ISO 8601 date-time, e.g. 2030-01-15T10:00:00Z or 2030-01-15T12:00:00+02:00. A value without an offset is read as UTC. It must be in the future. Omit it to post immediately. Scheduled posts go out within about a minute of that time.

Request Body

mediaIdstringrequired

The ID of the uploaded image (type IMAGE) from POST /media

scheduledDatestringoptional

ISO 8601 date-time in the future, e.g. 2030-01-15T10:00:00Z. Without an offset it is read as UTC. Omit to post immediately.

postsarrayrequired

Array of post objects containing account and content information

posts[].accountIdstringrequired

The ID of the social media account to post to (see GET /social-accounts)

posts[].captionstringoptional

Post text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).

posts[].titlestringoptional

Title for TikTok (photo title), Pinterest, Tumblr and LinkedIn. Ignored elsewhere. Longer than 90 characters is cut.

posts[].linkstringoptional

Link URL: Pinterest (pin destination) and Tumblr (source link). Ignored elsewhere.

posts[].boardIdstringoptional

Pinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)

posts[].facebookFirstCommentstringoptional

First comment posted under the Facebook post (not for Stories). Ignored for other platforms.

posts[].is_aigcbooleanoptional

Label the post as AI-generated on TikTok and Instagram (Facebook only labels Reels and video Stories). true or false; "true"/"false" and 1/0 also work. Default: false.

posts[].tiktokobjectoptional

TikTok settings: privacy_level, disable_comment, brand_content, self_brand, isDraft, auto_add_music. See the TikTok guide.

posts[].instagramobjectoptional

Instagram settings: as_story. See the Instagram guide.

posts[].facebookobjectoptional

Facebook settings: as_story. See the Facebook guide.

Response

{ "mediaId": "img_12345", "message": "Image post created successfully", "posts": [ { "id": "7f3c9a2e-1b4d-4c8e-9f60-2a5b7d1e3c48", "platform": "instagram", "socialAccountId": "acc_789", "status": "SCHEDULED" } ] }

HTTP 202. status is SCHEDULED when scheduledDate is set, otherwise QUEUED. One entry per item in posts. Follow progress with GET /posts?id=<id>.

Code Example

curl -X POST "https://v1.api.crosspostify.com/post/image" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "mediaId": "img_12345",
    "scheduledDate": "2030-01-15T10:00:00Z",
    "posts": [
      {
        "accountId": "acc_789",
        "caption": "Check out our new product!",
        "title": "New Product Announcement",
        "boardId": "board_123",
        "facebookFirstComment": "This is my first comment on Facebook"
      }
    ]
  }'
POST/post/images

Create a new multiple images post across multiple social media platforms.

Platform Image Limits

  • TikTok: Maximum 35 images per post
  • Instagram: Maximum 10 images per post
  • Facebook: Maximum 10 images per post
  • LinkedIn: Maximum 10 images per post
  • Threads: Maximum 10 images per post
  • Tumblr: Maximum 10 images per post
  • Pinterest: Maximum 5 images per post
  • Bluesky: Maximum 4 images per post

Notes

  • Supported for TikTok, Instagram, Facebook, LinkedIn, Pinterest, Tumblr, Bluesky and Threads (not YouTube)
  • A single image works too: it is posted as a normal single-image post on every platform
  • A Story takes exactly one image: instagram.as_story or facebook.as_story with more than one mediaIds entry returns 400
  • title is used by TikTok (photo title), Pinterest (pin title), Tumblr (heading) and LinkedIn (media title). Other platforms ignore it. Maximum 90 characters; longer titles are cut.
  • link is used by Pinterest (pin destination) and Tumblr (source link). Other platforms ignore it.
  • boardId is mandatory for every Pinterest Account
  • For Pinterest all images in a multiple image post must have the same aspect ratio
  • For TikTok, Instagram and Facebook, images are converted to JPEG. Instagram images outside 4:5 to 1.91:1 get white borders (they are never cropped).
  • scheduledDate is an ISO 8601 date-time, e.g. 2030-01-15T10:00:00Z or 2030-01-15T12:00:00+02:00. A value without an offset is read as UTC. It must be in the future. Omit it to post immediately. Scheduled posts go out within about a minute of that time.

Request Body

mediaIdsarrayrequired

Array of uploaded image IDs (type IMAGE) from POST /media. The maximum depends on the platform (see above).

scheduledDatestringoptional

ISO 8601 date-time in the future, e.g. 2030-01-15T10:00:00Z. Without an offset it is read as UTC. Omit to post immediately.

postsarrayrequired

Array of post objects containing account and content information

posts[].accountIdstringrequired

The ID of the social media account to post to (see GET /social-accounts)

posts[].captionstringoptional

Post text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).

posts[].titlestringoptional

Title for TikTok (photo title), Pinterest, Tumblr and LinkedIn. Ignored elsewhere. Longer than 90 characters is cut.

posts[].linkstringoptional

Link URL: Pinterest (pin destination) and Tumblr (source link). Ignored elsewhere.

posts[].boardIdstringoptional

Pinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)

posts[].facebookFirstCommentstringoptional

First comment posted under the Facebook post. Ignored for other platforms.

posts[].is_aigcbooleanoptional

Label the post as AI-generated on TikTok and Instagram (Facebook only labels Reels and video Stories). true or false; "true"/"false" and 1/0 also work. Default: false.

posts[].tiktokobjectoptional

TikTok settings, including the cover image (photo_cover_index) and recommended music (auto_add_music). See the TikTok guide.

posts[].instagramobjectoptional

Instagram settings: as_story (only with exactly one mediaIds entry). See the Instagram guide.

posts[].facebookobjectoptional

Facebook settings: as_story (only with exactly one mediaIds entry). See the Facebook guide.

Response

{ "mediaIds": ["img_12345", "img_67890"], "message": "Multiple images post created successfully", "posts": [ { "id": "4a8d2f61-7c3e-4b9a-8e15-6f0c2d9b7a34", "platform": "instagram", "socialAccountId": "acc_789", "status": "SCHEDULED" } ] }

HTTP 202. mediaIds is returned as sent. status is SCHEDULED when scheduledDate is set, otherwise QUEUED. One entry per item in posts. Follow progress with GET /posts?id=<id>.

Code Example

curl -X POST "https://v1.api.crosspostify.com/post/images" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "mediaIds": ["img_12345", "img_67890"],
    "scheduledDate": "2030-01-15T10:00:00Z",
    "posts": [
      {
        "accountId": "acc_789",
        "caption": "Check out our new products!",
        "title": "New Product Collection",
        "boardId": "board_123",
        "facebookFirstComment": "Drop your thoughts below 👇"
      }
    ]
  }'
POST/post/video

Create a new video post across multiple social media platforms.

Notes

  • Supported for Facebook, TikTok, Instagram, YouTube, LinkedIn, Pinterest, Tumblr, Bluesky and Threads
  • Formats: .mp4 and .mov (upload with POST /media, max 100 MB). The video is not changed or re-encoded.
  • title is used by YouTube (video title, Untitled Video if empty), Pinterest (pin title), Tumblr (in front of the caption) and LinkedIn (media title). TikTok videos, Instagram, Facebook, Threads and Bluesky ignore it. Longer than 90 characters is cut.
  • link is used by Pinterest (pin destination, max 2048 characters) and Tumblr (source link)
  • boardId is mandatory for every Pinterest Account
  • Instagram videos are posted as Reels; Facebook videos as Reels (a normal video if the Reel fails). Both can be posted as a Story instead (as_story).
  • YouTube: set youtube.privacyStatus to public (default), unlisted or private. The API has no category, tags or "made for kids" options; videos are uploaded in category 22 (People & Blogs) and as not made for kids.
  • thumbnailTimestamp picks the TikTok cover frame, in milliseconds from the start
  • scheduledDate is an ISO 8601 date-time, e.g. 2030-01-15T10:00:00Z or 2030-01-15T12:00:00+02:00. A value without an offset is read as UTC. It must be in the future. Omit it to post immediately. Scheduled posts go out within about a minute of that time.

Request Body

mediaIdstringrequired

The ID of the uploaded video (type VIDEO) from POST /media

scheduledDatestringoptional

ISO 8601 date-time in the future, e.g. 2030-01-15T10:00:00Z. Without an offset it is read as UTC. Omit to post immediately.

postsarrayrequired

Array of post objects containing account and content information

posts[].accountIdstringrequired

The ID of the social media account to post to (see GET /social-accounts)

posts[].captionstringoptional

Post text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).

posts[].titlestringoptional

Title for YouTube, Pinterest, Tumblr and LinkedIn. Ignored elsewhere (including TikTok videos). Longer than 90 characters is cut.

posts[].linkstringoptional

Link URL: Pinterest (pin destination, max 2048 characters) and Tumblr (source link). Ignored elsewhere.

posts[].boardIdstringoptional

Pinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)

posts[].thumbnailTimestampintegeroptional

TikTok only: video frame for the cover, in milliseconds from the start. Default 0. Not used for drafts.

posts[].facebookFirstCommentstringoptional

First comment posted under the Facebook post (not for Stories). Ignored for other platforms.

posts[].is_aigcbooleanoptional

Label the post as AI-generated on TikTok, Instagram and Facebook (Reels and video Stories). true or false; "true"/"false" and 1/0 also work. Default: false.

posts[].tiktokobjectoptional

TikTok settings: privacy_level, disable_comment, disable_duet, disable_stitch, self_brand, brand_content, isDraft. See the TikTok guide.

posts[].instagramobjectoptional

Instagram settings: as_story, trial_reel, share_to_feed. See the Instagram guide.

posts[].facebookobjectoptional

Facebook settings: as_story. See the Facebook guide.

posts[].youtubeobjectoptional

YouTube settings: privacyStatus = public (default), unlisted or private (not case-sensitive). See the YouTube guide.

Notes on is_aigc and platform settings

  • is_aigc is one flag for all platforms that support an AI label: TikTok (videos and photos), Instagram (images, carousels, Reels) and Facebook (Reels and video Stories). Other platforms ignore it.
  • The tiktok, instagram, facebook and youtube objects only apply to accounts of that platform and are ignored for all others, so one request can mix platforms.
  • On/off options (is_aigc, tiktok.disable_comment, tiktok.isDraft, instagram.as_story and so on) accept true/false, the strings "true"/"false" and 1/0. Any other value returns 400, e.g. Invalid tiktok.disable_duet.
  • tiktok.privacy_level must be one of PUBLIC_TO_EVERYONE (default), MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY.
  • Details and validation rules: TikTok, Instagram, Facebook, YouTube.

Response

{ "mediaId": "vid_12345", "message": "Video post created successfully", "posts": [ { "id": "c2e81b7f-9d4a-4f63-b05e-3a7d1c8e2f90", "platform": "tiktok", "socialAccountId": "acc_789", "status": "SCHEDULED" } ] }

HTTP 202. status is SCHEDULED when scheduledDate is set, otherwise QUEUED. One entry per item in posts. Follow progress with GET /posts?id=<id>.

Code Example

curl -X POST "https://v1.api.crosspostify.com/post/video" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "mediaId": "vid_12345",
    "scheduledDate": "2030-01-15T10:00:00Z",
    "posts": [
      {
        "accountId": "acc_789",
        "caption": "Watch our latest video!",
        "title": "New Video Release",
        "link": "https://example.com",
        "boardId": "board_123",
        "facebookFirstComment": "First comment with extra info and links",
        "is_aigc": true
      }
    ]
  }'
POST/post/text

Create a text-only post. Supported for Facebook Pages and Threads.

Platform Support & Notes

  • Supported platforms: Facebook, Threads. Other platforms return 400 Unsupported platforms.
  • No media is required or accepted for this endpoint
  • The caption must not be empty (400 Missing caption)
  • Threads: text longer than 500 characters is cut to 500
  • scheduledDate is an ISO 8601 date-time, e.g. 2030-01-15T10:00:00Z or 2030-01-15T12:00:00+02:00. A value without an offset is read as UTC. It must be in the future. Omit it to post immediately. Scheduled posts go out within about a minute of that time.

Request Body

scheduledDatestringoptional

ISO 8601 date-time in the future, e.g. 2030-01-15T10:00:00Z. Without an offset it is read as UTC. If omitted, the post is queued immediately.

postsarrayrequired

Array of post objects containing account and text content

posts[].accountIdstringrequired

The ID of a Facebook Page or Threads account

posts[].captionstringrequired

The text of the post. Must not be empty. Longer than 2,200 characters is cut (Threads: 500).

posts[].textFormatPresetIdstring | integeroptional

Facebook text background preset ID (numeric, see the list below). Omit it or send an empty string for no background. Ignored for Threads.

posts[].facebookFirstCommentstringoptional

First comment posted under the Facebook post. Ignored for Threads.

Validation

  • If provided, textFormatPresetId must be an integer or a numeric string. Otherwise the request is rejected with HTTP 400 (Invalid textFormatPresetId). An empty string means no background.
  • textFormatPresetId is ignored for Threads.
  • An empty or whitespace-only caption is rejected with HTTP 400 (Missing caption).

Response

{ "message": "Text-only post scheduled successfully", "posts": [ { "id": "e5b07c93-2f1d-4a6e-9c84-1d3f5a7b9e02", "platform": "facebook", "socialAccountId": "acc_facebook_page_123", "status": "SCHEDULED" } ] }

HTTP 202. Without scheduledDate the message is Text-only post created successfully and status is QUEUED. There is no media key. Follow progress with GET /posts?id=<id>.

Code Example

curl -X POST "https://v1.api.crosspostify.com/post/text" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "scheduledDate": "2030-01-15T10:00:00Z",
    "posts": [
      {
        "accountId": "acc_facebook_page_123",
        "caption": "Hello Facebook! This is a text-only post with a background.",
        "textFormatPresetId": "106018623298955",
        "facebookFirstComment": "P.S. Do not miss our live Q&A at 5 PM!"
      }
    ]
  }'

Facebook Text Background Presets

You can optionally provide textFormatPresetId for Facebook text-only posts. The value is forwarded to Facebook as text_format_preset_id. Use the numeric IDs below. Keep IDs as strings in requests to avoid numeric precision issues.

IDLabel
106018623298955Solid purple
365653833956649Pink tropical plants
618093735238824Brown illustration
1917619914913753D hearts
21936277939854153D heart eyes emojis
2005213374653063D flame emojis
1821844087883360Walking yellow illustration
177465482945164Light purple 3D cube pattern
160419724814650Orange with pink illustration
2486239024012503D smiling emoji
2404018167717063D rose emojis
18688559434173603D crying laughter emoji
255989551804163Eye pink illustration
1654916007940525Light grey illustration
1679248482160767Light blue illustration
518948401838663Pink heart pattern
423339708139719Illustration
204187940028597Solid red
621731364695726Solid red
518596398537417Red illustration
134273813910336Tree red illustration
217321755510854Pink/purple hearts on pink
323371698179784Sunset red illustration
901751159967576Gradient dark orange/red
552118025129095Brown illustration
263789377694911Apple red illustration
606643333067842Tulip light orange illustration
458988134561491Cat dark orange illustration
548109108916650Unicorn red illustration
175493843120364Pink/yellow gradient
338976169966519Stairs beige illustration
206513879997925Spiral beige illustration
168373304017982Cube beige illustration
1271157196337260Solid red
174496469882866Lemon yellow illustration
862667370603267Egg light yellow illustration
127541261450947Ball green illustration
218067308976029Light grey illustration
688479024672716Gradient teal/light green
238863426886624Cat light blue illustration
301029513638534Solid teal
154977255088164Solid teal
1941912679424590Gradient grey/dark grey
396343990807392Flower teal illustration
143093446467972Blue clouds on dark blue
161409924510923Rocket heart in the sky
145893972683590Solid dark purple
217761075370932Solid blue
931584293685988Wave blue illustration
148862695775447Pink/purple hearts on purple
100114277230063Deep sea blue illustration
558836317844129Spiral purple illustration
172497526576609Watermelon light purple
433967226963128Solid purple
197865920864520Donut light purple
643122496026756Pink illustration
762009070855346Balloon light grey illustration
228164237768720Grey hearts on black
146487026137131Rain black illustration
221828835275596Glasses light grey illustration
1903718606535395Solid red
1881421442117417Solid black
249307305544279Gradient red/blue
1777259169190672Gradient purple/magenta
303063890126415Yellow/orange/pink gradient
122708641613922Gradient dark grey/black
319468561816672Dark blue illustration
121945541697934Pink illustration
288211338285858Blue illustration
446330032368780Gradient red
219266485227663Solid magenta
1289741387813798Solid dark red
1365883126823705Solid blue

Notes

  • These IDs were collected from Facebook. Facebook may retire them without notice; a retired ID makes the post fail.
  • Non-numeric values are rejected with HTTP 400 (Invalid textFormatPresetId). Numeric IDs are not checked against this list; an ID that Facebook does not accept makes the post fail at publish time (check GET /posts).
  • Omit textFormatPresetId (or send an empty string) to post with no background.
GET/pinterest-boards/{accountId}

Get Pinterest boards for a specific account. Use a board id as boardId when posting to Pinterest.

Path Parameters

accountIdstringrequired

The ID of the Pinterest account

Response

{ "boards": [ { "description": "Delicious recipes to try", "id": "board_123", "name": "My Recipes", "privacy": "PUBLIC", "url": "" }, { "description": "Places I want to visit", "id": "board_456", "name": "Travel Ideas", "privacy": "SECRET", "url": "" } ], "success": true, "total": 2 }

Returns up to 200 boards. privacy is the value from Pinterest (e.g. PUBLIC, SECRET); url is usually empty. If the account is not one of your Pinterest accounts: 404 {"error": "Pinterest account not found"}.

Code Example

curl -X GET "https://v1.api.crosspostify.com/pinterest-boards/acc_123" \
  -H "X-API-Key: your_api_key_here"
GET/social-accounts

Get user's connected social media accounts.

Query Parameters

platformstringoptional

Filter by platform (facebook, instagram, tiktok, youtube, linkedin, pinterest, tumblr, bluesky, threads)

Response

{ "accounts": [ { "createdAt": "Fri, 16 Jan 2026 09:00:00 GMT", "id": "acc_123", "platform": "instagram", "username": "@myaccount" }, { "createdAt": "Thu, 15 Jan 2026 10:30:00 GMT", "id": "acc_456", "platform": "facebook", "username": "My Page" } ], "total": 2 }

Newest first. createdAt is an HTTP date (RFC 1123), not ISO 8601. username can be null. The list includes all connected accounts; X and Snapchat accounts are listed but cannot be used with the posting endpoints. Use id as accountId when posting.

Code Example

curl -X GET "https://v1.api.crosspostify.com/social-accounts" \
  -H "X-API-Key: your_api_key_here"
GET/posts

Get user posts with filtering and pagination options.

Query Parameters

idstringoptional

Fetch a single post by ID. The response is the post object itself (no posts / pagination wrapper); status, platform, from and to still filter. No match: 404 {"error": "Not found", "message": "Post not found"}.

statusstringoptional

Filter by status: SCHEDULED, QUEUED, PROCESSING, PUBLISHED, FAILED (exact match)

platformstringoptional

Filter by platform (facebook, instagram, tiktok, etc.)

fromstringoptional

Filter by createdAt greater or equal this timestamp (ISO 8601 date or date-time)

tostringoptional

Filter by createdAt less than or equal to this timestamp (ISO 8601 date or date-time)

limitintegeroptional

Number of posts to return (default 50; values above 100 are treated as 100)

offsetintegeroptional

Pagination offset (default 0)

Response

{ "pagination": { "limit": 50, "offset": 0, "total": 150 }, "posts": [ { "caption": "Check out our new product!", "createdAt": "2026-01-10T12:34:56.789012", "error": null, "id": "post_123", "mediaIds": ["img_1", "img_2"], "mediaType": "MULTIIMAGE", "origin": "API", "platform": "instagram", "postUrl": "https://www.instagram.com/p/ABC123xyz/", "scheduledDate": "2026-01-15T10:00:00", "socialAccountId": "acc_789", "status": "PUBLISHED", "title": "Title" } ] }

Notes

  • Newest first (by createdAt). The list also contains posts created in the web app (origin APP).
  • Status flow: QUEUED or SCHEDULED → PROCESSING → PUBLISHED or FAILED. On a temporary platform error the post stays in PROCESSING while it is retried; error then starts with Transient error (will retry).
  • All dates are UTC without a timezone suffix.
  • mediaIds is null for text posts. mediaType is VIDEO, IMAGE, MULTIIMAGE or TEXT.
  • postUrl is null until the post is published. On TikTok it can stay null for up to about 10 minutes after PUBLISHED, and for drafts and Facebook Stories it stays null.
  • An invalid limit, offset, from or to returns 400 {"error": "Invalid parameter", "message": "..."}.

Code Example

curl -X GET "https://v1.api.crosspostify.com/posts?limit=10" \
  -H "X-API-Key: your_api_key_here"
DELETE/posts/{postId}

Delete a post with status SCHEDULED. Any other status (also QUEUED and PROCESSING) returns 403. Deleting does not give back the post's place in the daily limit.

Path Parameters

postIdstringrequired

The ID of the post to delete

Response

{ "id": "post_123", "message": "Post deleted successfully" }

Errors: 403 {"error": "Only scheduled posts can be deleted", "status": "PUBLISHED"} (with the current status), 404 {"error": "Post not found"}. The uploaded media is not deleted.

Code Example

curl -X DELETE "https://v1.api.crosspostify.com/posts/post_123" \
  -H "X-API-Key: your_api_key_here"
GET/media

Get user's uploaded media files.

Query Parameters

typestringoptional

Filter by media type (IMAGE, VIDEO; not case-sensitive)

fromstringoptional

Filter by createdAt greater or equal this timestamp (ISO 8601)

tostringoptional

Filter by createdAt smaller or equal this timestamp (ISO 8601)

limitintegeroptional

Number of media files to return (default 50; values above 100 are treated as 100)

offsetintegeroptional

Pagination offset (default 0)

Response

{ "media": [ { "aspectRatio": 1.778, "createdAt": "2026-01-15T08:00:00", "filename": "product-photo.jpg", "height": 1080, "id": "img_123", "scheduledDeletionDate": "2026-02-14T08:00:00", "type": "IMAGE", "width": 1920 } ], "pagination": { "limit": 50, "offset": 0, "total": 25 } }

Newest first. No file URL is returned. For videos width, height and aspectRatio are null. Dates are UTC without a timezone suffix; scheduledDeletionDate can be null. The list also contains media uploaded in the web app.

Code Example

curl -X GET "https://v1.api.crosspostify.com/media" \
  -H "X-API-Key: your_api_key_here"
POST/media

Upload a media file (image or video) for later use in posts.

Request Body (multipart/form-data)

mediafilerequired

The media file to upload (images: .jpg, .jpeg, .png, .webp up to 20 MB; videos: .mp4, .mov up to 100 MB)

typestringrequired

Media type: IMAGE or VIDEO (not case-sensitive)

Response

{ "aspectRatio": 1.5, "filename": "new-product.jpg", "height": 800, "id": "img_456", "message": "Media uploaded successfully", "type": "IMAGE", "width": 1200 }

HTTP 201. Use id as mediaId / mediaIds in the posting endpoints.

Notes

  • Images: .jpg, .jpeg, .png, .webp (no GIF or HEIC), max 20 MB. Videos: .mp4, .mov (no AVI), max 100 MB.
  • Larger files return 400 File too large. Request bodies over 110 MB return 413. Other formats return 400 Invalid file format for IMAGE (or VIDEO) with allowed_formats.
  • Images are converted to JPEG and rotated according to EXIF. They are not resized. Videos are stored unchanged.
  • Video width, height and aspectRatio are null.
  • No URL is returned and there is no upload by URL. Use the id.
  • Each upload gets a scheduledDeletionDate 30 days ahead (see GET /media). Using the media in a post moves it to 30 days after that use.

Code Example

curl -X POST "https://v1.api.crosspostify.com/media" \
  -H "X-API-Key: your_api_key_here" \
  -F "[email protected]" \
  -F "type=IMAGE"
DELETE/media/{mediaId}

Delete a media file from your account.

Path Parameters

mediaIdstringrequired

The ID of the media file to delete

Response

{ "id": "img_123", "message": "Media deleted successfully" }

Errors: 404 {"error": "Media not found"}, 409 {"error": "Media is in use by one or more scheduled posts"}. The 409 check only covers single-media posts that have a scheduledDate. Do not delete media used by posts that are still queued or processing, or by multi-image posts; the check does not cover them and those posts would fail.

Code Example

curl -X DELETE "https://v1.api.crosspostify.com/media/img_123" \
  -H "X-API-Key: your_api_key_here"