curl --request POST \
--url https://api.example.com/v1/posts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"profileId": "<string>",
"title": "<string>",
"content": "<string>",
"accountIds": [
"<string>"
],
"platforms": [
{
"accountId": "<string>",
"customContent": "<string>",
"customMedia": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
]
}
],
"mediaItems": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
],
"mediaUrls": [
"<string>"
],
"scheduledFor": "2027-01-01T12:00:00",
"timezone": "Europe/Paris",
"publishNow": false,
"asDraft": false,
"trialReel": false,
"asStory": false,
"trialGraduation": "MANUAL",
"shareToFeed": true,
"allowComment": true,
"allowDuet": true,
"allowStitch": true,
"privacy": "public",
"promotionalContent": false,
"paidPartnership": false
}
'import requests
url = "https://api.example.com/v1/posts"
payload = {
"profileId": "<string>",
"title": "<string>",
"content": "<string>",
"accountIds": ["<string>"],
"platforms": [
{
"accountId": "<string>",
"customContent": "<string>",
"customMedia": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
]
}
],
"mediaItems": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
],
"mediaUrls": ["<string>"],
"scheduledFor": "2027-01-01T12:00:00",
"timezone": "Europe/Paris",
"publishNow": False,
"asDraft": False,
"trialReel": False,
"asStory": False,
"trialGraduation": "MANUAL",
"shareToFeed": True,
"allowComment": True,
"allowDuet": True,
"allowStitch": True,
"privacy": "public",
"promotionalContent": False,
"paidPartnership": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
profileId: '<string>',
title: '<string>',
content: '<string>',
accountIds: ['<string>'],
platforms: [
{
accountId: '<string>',
customContent: '<string>',
customMedia: [
{
url: 'https://cdn.example.com/photo.jpg',
altText: '<string>',
thumbnail: '<string>'
}
]
}
],
mediaItems: [
{
url: 'https://cdn.example.com/photo.jpg',
altText: '<string>',
thumbnail: '<string>'
}
],
mediaUrls: ['<string>'],
scheduledFor: '2027-01-01T12:00:00',
timezone: 'Europe/Paris',
publishNow: false,
asDraft: false,
trialReel: false,
asStory: false,
trialGraduation: 'MANUAL',
shareToFeed: true,
allowComment: true,
allowDuet: true,
allowStitch: true,
privacy: 'public',
promotionalContent: false,
paidPartnership: false
})
};
fetch('https://api.example.com/v1/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'profileId' => '<string>',
'title' => '<string>',
'content' => '<string>',
'accountIds' => [
'<string>'
],
'platforms' => [
[
'accountId' => '<string>',
'customContent' => '<string>',
'customMedia' => [
[
'url' => 'https://cdn.example.com/photo.jpg',
'altText' => '<string>',
'thumbnail' => '<string>'
]
]
]
],
'mediaItems' => [
[
'url' => 'https://cdn.example.com/photo.jpg',
'altText' => '<string>',
'thumbnail' => '<string>'
]
],
'mediaUrls' => [
'<string>'
],
'scheduledFor' => '2027-01-01T12:00:00',
'timezone' => 'Europe/Paris',
'publishNow' => false,
'asDraft' => false,
'trialReel' => false,
'asStory' => false,
'trialGraduation' => 'MANUAL',
'shareToFeed' => true,
'allowComment' => true,
'allowDuet' => true,
'allowStitch' => true,
'privacy' => 'public',
'promotionalContent' => false,
'paidPartnership' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/posts"
payload := strings.NewReader("{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/posts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}"
response = http.request(request)
puts response.read_bodyCreate a post (draft, scheduled, or published)
With publishNow, the response returns immediately with status: "publishing" and publishing runs in the background. Poll GET /posts/:id to follow it.
curl --request POST \
--url https://api.example.com/v1/posts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"profileId": "<string>",
"title": "<string>",
"content": "<string>",
"accountIds": [
"<string>"
],
"platforms": [
{
"accountId": "<string>",
"customContent": "<string>",
"customMedia": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
]
}
],
"mediaItems": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
],
"mediaUrls": [
"<string>"
],
"scheduledFor": "2027-01-01T12:00:00",
"timezone": "Europe/Paris",
"publishNow": false,
"asDraft": false,
"trialReel": false,
"asStory": false,
"trialGraduation": "MANUAL",
"shareToFeed": true,
"allowComment": true,
"allowDuet": true,
"allowStitch": true,
"privacy": "public",
"promotionalContent": false,
"paidPartnership": false
}
'import requests
url = "https://api.example.com/v1/posts"
payload = {
"profileId": "<string>",
"title": "<string>",
"content": "<string>",
"accountIds": ["<string>"],
"platforms": [
{
"accountId": "<string>",
"customContent": "<string>",
"customMedia": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
]
}
],
"mediaItems": [
{
"url": "https://cdn.example.com/photo.jpg",
"altText": "<string>",
"thumbnail": "<string>"
}
],
"mediaUrls": ["<string>"],
"scheduledFor": "2027-01-01T12:00:00",
"timezone": "Europe/Paris",
"publishNow": False,
"asDraft": False,
"trialReel": False,
"asStory": False,
"trialGraduation": "MANUAL",
"shareToFeed": True,
"allowComment": True,
"allowDuet": True,
"allowStitch": True,
"privacy": "public",
"promotionalContent": False,
"paidPartnership": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
profileId: '<string>',
title: '<string>',
content: '<string>',
accountIds: ['<string>'],
platforms: [
{
accountId: '<string>',
customContent: '<string>',
customMedia: [
{
url: 'https://cdn.example.com/photo.jpg',
altText: '<string>',
thumbnail: '<string>'
}
]
}
],
mediaItems: [
{
url: 'https://cdn.example.com/photo.jpg',
altText: '<string>',
thumbnail: '<string>'
}
],
mediaUrls: ['<string>'],
scheduledFor: '2027-01-01T12:00:00',
timezone: 'Europe/Paris',
publishNow: false,
asDraft: false,
trialReel: false,
asStory: false,
trialGraduation: 'MANUAL',
shareToFeed: true,
allowComment: true,
allowDuet: true,
allowStitch: true,
privacy: 'public',
promotionalContent: false,
paidPartnership: false
})
};
fetch('https://api.example.com/v1/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'profileId' => '<string>',
'title' => '<string>',
'content' => '<string>',
'accountIds' => [
'<string>'
],
'platforms' => [
[
'accountId' => '<string>',
'customContent' => '<string>',
'customMedia' => [
[
'url' => 'https://cdn.example.com/photo.jpg',
'altText' => '<string>',
'thumbnail' => '<string>'
]
]
]
],
'mediaItems' => [
[
'url' => 'https://cdn.example.com/photo.jpg',
'altText' => '<string>',
'thumbnail' => '<string>'
]
],
'mediaUrls' => [
'<string>'
],
'scheduledFor' => '2027-01-01T12:00:00',
'timezone' => 'Europe/Paris',
'publishNow' => false,
'asDraft' => false,
'trialReel' => false,
'asStory' => false,
'trialGraduation' => 'MANUAL',
'shareToFeed' => true,
'allowComment' => true,
'allowDuet' => true,
'allowStitch' => true,
'privacy' => 'public',
'promotionalContent' => false,
'paidPartnership' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/posts"
payload := strings.NewReader("{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/posts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"profileId\": \"<string>\",\n \"title\": \"<string>\",\n \"content\": \"<string>\",\n \"accountIds\": [\n \"<string>\"\n ],\n \"platforms\": [\n {\n \"accountId\": \"<string>\",\n \"customContent\": \"<string>\",\n \"customMedia\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ]\n }\n ],\n \"mediaItems\": [\n {\n \"url\": \"https://cdn.example.com/photo.jpg\",\n \"altText\": \"<string>\",\n \"thumbnail\": \"<string>\"\n }\n ],\n \"mediaUrls\": [\n \"<string>\"\n ],\n \"scheduledFor\": \"2027-01-01T12:00:00\",\n \"timezone\": \"Europe/Paris\",\n \"publishNow\": false,\n \"asDraft\": false,\n \"trialReel\": false,\n \"asStory\": false,\n \"trialGraduation\": \"MANUAL\",\n \"shareToFeed\": true,\n \"allowComment\": true,\n \"allowDuet\": true,\n \"allowStitch\": true,\n \"privacy\": \"public\",\n \"promotionalContent\": false,\n \"paidPartnership\": false\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Profile that owns the post
Title of the post. Required by YouTube (100 characters max) and ignored by platforms that have no title.
100Text / caption of the post. REQUIRED, except when asStory is set and every target is an Instagram or Facebook account: a story has no caption.
Target account ids — the short form. Use platforms instead to tailor the content per platform. Exactly one of the two is required.
Targets with per-platform overrides. Exactly one of platforms and accountIds is required.
Show child attributes
Show child attributes
Media of the post. This is the canonical shape: it carries the type, alt text and thumbnail, which mediaUrls cannot.
Show child attributes
Show child attributes
Legacy shorthand: a list of URLs, converted to mediaItems (type inferred from the extension). Ignored when mediaItems is provided.
Scheduled date (ISO 8601). Without an offset ("2027-01-01T12:00:00") the time is read in timezone; with an offset or a Z it is an absolute instant. The post moves to scheduled and is published automatically at that time.
"2027-01-01T12:00:00"
IANA timezone scheduledFor is expressed in (e.g. "Europe/Paris"). Ignored when the date already carries an offset.
"Europe/Paris"
Publish immediately
TikTok only: send the video to the creator's inbox as a draft (Content Posting API, video.upload scope) instead of publishing it directly. The creator finishes the post in the TikTok app.
Instagram only: publish the video as a trial reel — shown to NON-followers only, never to your own followers, until you choose to release it from the Instagram app. Requires a video and an account with at least 1,000 followers. Ignored by the other platforms.
Instagram and Facebook Pages: publish to the STORY instead of the feed. A story lasts 24 hours, carries no caption (content is ignored, and may be omitted when every target is an Instagram or Facebook account) and takes exactly one media — on Instagram a JPEG image (8 MB max) or an MP4/MOV video of 3 to 60 seconds (100 MB max), on a Facebook Page an image (10 MB max) or an MP4 video of 3 to 90 seconds. Cannot be combined with trialReel. Ignored by the other platforms, which have no story API: TikTok does not expose one, LinkedIn and YouTube retired theirs.
Instagram only, with trialReel: how the trial ends. MANUAL — you decide in the Instagram app whether to release the reel to your followers. SS_PERFORMANCE — Instagram releases it on its own if the trial performs well.
MANUAL, SS_PERFORMANCE Instagram only, reels: also show the reel in the account feed, not just in the Reels tab.
TikTok only: let other users comment on the video. Forced off when the creator's own TikTok settings already disable comments.
TikTok only: let other users Duet the video. Forced off when the creator's own TikTok settings already disable duets.
TikTok only: let other users Stitch the video. Forced off when the creator's own TikTok settings already disable stitches.
Visibility of the published video. YouTube maps it directly (unlisted = reachable by link but not listed). TikTok has no unlisted, so both unlisted and private publish as SELF_ONLY — visible to the account owner only. The other platforms ignore it.
public, unlisted, private TikTok only: the exact privacy level the creator picked, among those returned by GET /accounts/{id}/publish-options. Takes precedence over privacy, which only knows three values where TikTok has four. Rejected if the creator is not allowed to use it.
PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY TikTok only: the video promotes the creator's own brand, product or business. TikTok labels it « Promotional content ».
TikTok only: the video promotes a third party as a paid partnership. TikTok labels it « Paid partnership », which wins over « Promotional content » when both are declared. Cannot be combined with a private (SELF_ONLY) visibility.