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.comRoutes 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.
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
409Duplicate 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.
Rate Limits
To ensure fair usage and maintain service quality, the Crosspostify API implements rate limiting:
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
Per social account, minute
Per social account, day
Errors
Crosspostify uses conventional HTTP response codes to indicate the success or failure of an API request.
Everything worked as expected.
Media uploaded (POST /media).
Posts created and queued or scheduled (POST /post/*). Publishing happens afterwards; check GET /posts.
The request was invalid, for example a missing or invalid field. The body says what is wrong.
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.
Only posts with status SCHEDULED can be deleted.
The requested resource does not exist or does not belong to your account.
A request with the same X-Request-ID is still being processed, or the media is used by a scheduled post.
Request body larger than 110 MB.
Posting endpoints need Content-Type: application/json.
A rate limit was hit. See Rate Limits.
Something went wrong on Crosspostify's end.
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.
| Status | error | When |
|---|---|---|
| 400 | No JSON data provided | The body is empty. |
| 400 | No posts provided | posts is missing or empty. |
| 400 | Invalid post format - missing accountId | An entry in posts has no accountId. |
| 400 | No media ID provided / No media IDs provided or invalid format | mediaId (or mediaIds) is missing. |
| 400 | Invalid media / Invalid media ID | The media does not exist, is not yours or has the wrong type. message says why (for Pinterest also: images with different aspect ratios). |
| 400 | Invalid date format | scheduledDate is not an ISO 8601 date-time. |
| 400 | Scheduled date must be in the future | scheduledDate is now or in the past. |
| 404 | One or more social accounts not found or unauthorized | An accountId does not exist or is not yours. |
| 400 | Unsupported platforms | An account platform is not supported by this endpoint. invalid_accounts lists them as accountId:platform. |
| 400 | Missing boardId | A Pinterest post has no boardId. accountId names the post. |
| 400 | Too many images | More mediaIds than a platform allows. Includes platform, max_images and affected_accounts. |
| 400 | Missing caption | /post/text with an empty caption. |
| 400 | Invalid textFormatPresetId | /post/text: textFormatPresetId is not an integer or numeric string. |
| 400 | Invalid <field> | An on/off option is not true or false, e.g. Invalid is_aigc or Invalid tiktok.disable_duet. |
| 400 | Invalid tiktok.privacy_level | Not one of PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY. |
| 400 | Invalid tiktok.photo_cover_index | Not a whole number of 0 or more. |
| 400 | Invalid tiktok settings | tiktok is not an object, or branded content is set to private (SELF_ONLY). |
| 400 | Invalid instagram.trial_reel | Not MANUAL or SS_PERFORMANCE. |
| 400 | Invalid instagram settings / Invalid facebook settings | The value is not an object, or as_story is set with more than one image. |
| 400 | Invalid youtube.privacyStatus / Invalid youtube settings | privacyStatus is not public, unlisted or private, or youtube is not an object. |
| 409 | Duplicate request | A request with the same X-Request-ID is still being processed. |
| 415 | 415 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/imageCreate 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)
titleis 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.linkis used by Pinterest (pin destination) and Tumblr (source link). Other platforms ignore it.boardIdis 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.
scheduledDateis an ISO 8601 date-time, e.g.2030-01-15T10:00:00Zor2030-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
mediaIdstringrequiredThe ID of the uploaded image (type IMAGE) from POST /media
scheduledDatestringoptionalISO 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.
postsarrayrequiredArray of post objects containing account and content information
posts[].accountIdstringrequiredThe ID of the social media account to post to (see GET /social-accounts)
posts[].captionstringoptionalPost text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).
posts[].titlestringoptionalTitle for TikTok (photo title), Pinterest, Tumblr and LinkedIn. Ignored elsewhere. Longer than 90 characters is cut.
posts[].linkstringoptionalLink URL: Pinterest (pin destination) and Tumblr (source link). Ignored elsewhere.
posts[].boardIdstringoptionalPinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)
posts[].facebookFirstCommentstringoptionalFirst comment posted under the Facebook post (not for Stories). Ignored for other platforms.
posts[].is_aigcbooleanoptionalLabel 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[].tiktokobjectoptionalTikTok settings: privacy_level, disable_comment, brand_content, self_brand, isDraft, auto_add_music. See the TikTok guide.
posts[].instagramobjectoptionalInstagram settings: as_story. See the Instagram guide.
posts[].facebookobjectoptionalFacebook settings: as_story. See the Facebook guide.
Response
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/imagesCreate 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_storyorfacebook.as_storywith more than onemediaIdsentry returns 400 titleis 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.linkis used by Pinterest (pin destination) and Tumblr (source link). Other platforms ignore it.boardIdis 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).
scheduledDateis an ISO 8601 date-time, e.g.2030-01-15T10:00:00Zor2030-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
mediaIdsarrayrequiredArray of uploaded image IDs (type IMAGE) from POST /media. The maximum depends on the platform (see above).
scheduledDatestringoptionalISO 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.
postsarrayrequiredArray of post objects containing account and content information
posts[].accountIdstringrequiredThe ID of the social media account to post to (see GET /social-accounts)
posts[].captionstringoptionalPost text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).
posts[].titlestringoptionalTitle for TikTok (photo title), Pinterest, Tumblr and LinkedIn. Ignored elsewhere. Longer than 90 characters is cut.
posts[].linkstringoptionalLink URL: Pinterest (pin destination) and Tumblr (source link). Ignored elsewhere.
posts[].boardIdstringoptionalPinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)
posts[].facebookFirstCommentstringoptionalFirst comment posted under the Facebook post. Ignored for other platforms.
posts[].is_aigcbooleanoptionalLabel 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[].tiktokobjectoptionalTikTok settings, including the cover image (photo_cover_index) and recommended music (auto_add_music). See the TikTok guide.
posts[].instagramobjectoptionalInstagram settings: as_story (only with exactly one mediaIds entry). See the Instagram guide.
posts[].facebookobjectoptionalFacebook settings: as_story (only with exactly one mediaIds entry). See the Facebook guide.
Response
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/videoCreate 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. titleis used by YouTube (video title,Untitled Videoif 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.linkis used by Pinterest (pin destination, max 2048 characters) and Tumblr (source link)boardIdis 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.privacyStatustopublic(default),unlistedorprivate. 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. thumbnailTimestamppicks the TikTok cover frame, in milliseconds from the startscheduledDateis an ISO 8601 date-time, e.g.2030-01-15T10:00:00Zor2030-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
mediaIdstringrequiredThe ID of the uploaded video (type VIDEO) from POST /media
scheduledDatestringoptionalISO 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.
postsarrayrequiredArray of post objects containing account and content information
posts[].accountIdstringrequiredThe ID of the social media account to post to (see GET /social-accounts)
posts[].captionstringoptionalPost text. Optional. Longer than 2,200 characters is cut (Threads: 500, Bluesky: 300).
posts[].titlestringoptionalTitle for YouTube, Pinterest, Tumblr and LinkedIn. Ignored elsewhere (including TikTok videos). Longer than 90 characters is cut.
posts[].linkstringoptionalLink URL: Pinterest (pin destination, max 2048 characters) and Tumblr (source link). Ignored elsewhere.
posts[].boardIdstringoptionalPinterest board ID (mandatory for Pinterest accounts, see GET /pinterest-boards)
posts[].thumbnailTimestampintegeroptionalTikTok only: video frame for the cover, in milliseconds from the start. Default 0. Not used for drafts.
posts[].facebookFirstCommentstringoptionalFirst comment posted under the Facebook post (not for Stories). Ignored for other platforms.
posts[].is_aigcbooleanoptionalLabel 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[].tiktokobjectoptionalTikTok settings: privacy_level, disable_comment, disable_duet, disable_stitch, self_brand, brand_content, isDraft. See the TikTok guide.
posts[].instagramobjectoptionalInstagram settings: as_story, trial_reel, share_to_feed. See the Instagram guide.
posts[].facebookobjectoptionalFacebook settings: as_story. See the Facebook guide.
posts[].youtubeobjectoptionalYouTube settings: privacyStatus = public (default), unlisted or private (not case-sensitive). See the YouTube guide.
Notes on is_aigc and platform settings
is_aigcis 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,facebookandyoutubeobjects 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_storyand so on) accepttrue/false, the strings"true"/"false"and1/0. Any other value returns 400, e.g.Invalid tiktok.disable_duet. tiktok.privacy_levelmust be one ofPUBLIC_TO_EVERYONE(default),MUTUAL_FOLLOW_FRIENDS,FOLLOWER_OF_CREATORorSELF_ONLY.- Details and validation rules: TikTok, Instagram, Facebook, YouTube.
Response
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/textCreate 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
scheduledDateis an ISO 8601 date-time, e.g.2030-01-15T10:00:00Zor2030-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
scheduledDatestringoptionalISO 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.
postsarrayrequiredArray of post objects containing account and text content
posts[].accountIdstringrequiredThe ID of a Facebook Page or Threads account
posts[].captionstringrequiredThe text of the post. Must not be empty. Longer than 2,200 characters is cut (Threads: 500).
posts[].textFormatPresetIdstring | integeroptionalFacebook text background preset ID (numeric, see the list below). Omit it or send an empty string for no background. Ignored for Threads.
posts[].facebookFirstCommentstringoptionalFirst comment posted under the Facebook post. Ignored for Threads.
Validation
- If provided,
textFormatPresetIdmust be an integer or a numeric string. Otherwise the request is rejected with HTTP 400 (Invalid textFormatPresetId). An empty string means no background. textFormatPresetIdis ignored for Threads.- An empty or whitespace-only
captionis rejected with HTTP 400 (Missing caption).
Response
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.
| ID | Label |
|---|---|
106018623298955 | Solid purple |
365653833956649 | Pink tropical plants |
618093735238824 | Brown illustration |
191761991491375 | 3D hearts |
2193627793985415 | 3D heart eyes emojis |
200521337465306 | 3D flame emojis |
1821844087883360 | Walking yellow illustration |
177465482945164 | Light purple 3D cube pattern |
160419724814650 | Orange with pink illustration |
248623902401250 | 3D smiling emoji |
240401816771706 | 3D rose emojis |
1868855943417360 | 3D crying laughter emoji |
255989551804163 | Eye pink illustration |
1654916007940525 | Light grey illustration |
1679248482160767 | Light blue illustration |
518948401838663 | Pink heart pattern |
423339708139719 | Illustration |
204187940028597 | Solid red |
621731364695726 | Solid red |
518596398537417 | Red illustration |
134273813910336 | Tree red illustration |
217321755510854 | Pink/purple hearts on pink |
323371698179784 | Sunset red illustration |
901751159967576 | Gradient dark orange/red |
552118025129095 | Brown illustration |
263789377694911 | Apple red illustration |
606643333067842 | Tulip light orange illustration |
458988134561491 | Cat dark orange illustration |
548109108916650 | Unicorn red illustration |
175493843120364 | Pink/yellow gradient |
338976169966519 | Stairs beige illustration |
206513879997925 | Spiral beige illustration |
168373304017982 | Cube beige illustration |
1271157196337260 | Solid red |
174496469882866 | Lemon yellow illustration |
862667370603267 | Egg light yellow illustration |
127541261450947 | Ball green illustration |
218067308976029 | Light grey illustration |
688479024672716 | Gradient teal/light green |
238863426886624 | Cat light blue illustration |
301029513638534 | Solid teal |
154977255088164 | Solid teal |
1941912679424590 | Gradient grey/dark grey |
396343990807392 | Flower teal illustration |
143093446467972 | Blue clouds on dark blue |
161409924510923 | Rocket heart in the sky |
145893972683590 | Solid dark purple |
217761075370932 | Solid blue |
931584293685988 | Wave blue illustration |
148862695775447 | Pink/purple hearts on purple |
100114277230063 | Deep sea blue illustration |
558836317844129 | Spiral purple illustration |
172497526576609 | Watermelon light purple |
433967226963128 | Solid purple |
197865920864520 | Donut light purple |
643122496026756 | Pink illustration |
762009070855346 | Balloon light grey illustration |
228164237768720 | Grey hearts on black |
146487026137131 | Rain black illustration |
221828835275596 | Glasses light grey illustration |
1903718606535395 | Solid red |
1881421442117417 | Solid black |
249307305544279 | Gradient red/blue |
1777259169190672 | Gradient purple/magenta |
303063890126415 | Yellow/orange/pink gradient |
122708641613922 | Gradient dark grey/black |
319468561816672 | Dark blue illustration |
121945541697934 | Pink illustration |
288211338285858 | Blue illustration |
446330032368780 | Gradient red |
219266485227663 | Solid magenta |
1289741387813798 | Solid dark red |
1365883126823705 | Solid 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 (checkGET /posts). - Omit
textFormatPresetId(or send an empty string) to post with no background.
/pinterest-boards/{accountId}Get Pinterest boards for a specific account. Use a board id as boardId when posting to Pinterest.
Path Parameters
accountIdstringrequiredThe ID of the Pinterest account
Response
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"/social-accountsGet user's connected social media accounts.
Query Parameters
platformstringoptionalFilter by platform (facebook, instagram, tiktok, youtube, linkedin, pinterest, tumblr, bluesky, threads)
Response
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"/postsGet user posts with filtering and pagination options.
Query Parameters
idstringoptionalFetch 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"}.
statusstringoptionalFilter by status: SCHEDULED, QUEUED, PROCESSING, PUBLISHED, FAILED (exact match)
platformstringoptionalFilter by platform (facebook, instagram, tiktok, etc.)
fromstringoptionalFilter by createdAt greater or equal this timestamp (ISO 8601 date or date-time)
tostringoptionalFilter by createdAt less than or equal to this timestamp (ISO 8601 date or date-time)
limitintegeroptionalNumber of posts to return (default 50; values above 100 are treated as 100)
offsetintegeroptionalPagination offset (default 0)
Response
Notes
- Newest first (by
createdAt). The list also contains posts created in the web app (originAPP). - Status flow:
QUEUEDorSCHEDULED→PROCESSING→PUBLISHEDorFAILED. On a temporary platform error the post stays inPROCESSINGwhile it is retried;errorthen starts withTransient error (will retry). - All dates are UTC without a timezone suffix.
mediaIdsis null for text posts.mediaTypeisVIDEO,IMAGE,MULTIIMAGEorTEXT.postUrlis null until the post is published. On TikTok it can stay null for up to about 10 minutes afterPUBLISHED, and for drafts and Facebook Stories it stays null.- An invalid
limit,offset,fromortoreturns 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"/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
postIdstringrequiredThe ID of the post to delete
Response
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"/mediaGet user's uploaded media files.
Query Parameters
typestringoptionalFilter by media type (IMAGE, VIDEO; not case-sensitive)
fromstringoptionalFilter by createdAt greater or equal this timestamp (ISO 8601)
tostringoptionalFilter by createdAt smaller or equal this timestamp (ISO 8601)
limitintegeroptionalNumber of media files to return (default 50; values above 100 are treated as 100)
offsetintegeroptionalPagination offset (default 0)
Response
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"/mediaUpload a media file (image or video) for later use in posts.
Request Body (multipart/form-data)
mediafilerequiredThe media file to upload (images: .jpg, .jpeg, .png, .webp up to 20 MB; videos: .mp4, .mov up to 100 MB)
typestringrequiredMedia type: IMAGE or VIDEO (not case-sensitive)
Response
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 400Invalid file format for IMAGE(orVIDEO) withallowed_formats. - Images are converted to JPEG and rotated according to EXIF. They are not resized. Videos are stored unchanged.
- Video
width,heightandaspectRatioare null. - No URL is returned and there is no upload by URL. Use the
id. - Each upload gets a
scheduledDeletionDate30 days ahead (seeGET /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"/media/{mediaId}Delete a media file from your account.
Path Parameters
mediaIdstringrequiredThe ID of the media file to delete
Response
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"