Update post
curl --request PUT \
--url https://app.getkavio.app/api/posts/{post} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"status": "<string>",
"content": "<string>",
"media": [
{}
],
"platforms": [
{
"id": "<string>",
"content_type": "<string>",
"meta": {}
}
],
"scheduled_at": "<string>",
"label_ids": [
{}
]
}
'import requests
url = "https://app.getkavio.app/api/posts/{post}"
payload = {
"status": "<string>",
"content": "<string>",
"media": [{}],
"platforms": [
{
"id": "<string>",
"content_type": "<string>",
"meta": {}
}
],
"scheduled_at": "<string>",
"label_ids": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
status: '<string>',
content: '<string>',
media: [{}],
platforms: [{id: '<string>', content_type: '<string>', meta: {}}],
scheduled_at: '<string>',
label_ids: [{}]
})
};
fetch('https://app.getkavio.app/api/posts/{post}', 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://app.getkavio.app/api/posts/{post}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'status' => '<string>',
'content' => '<string>',
'media' => [
[
]
],
'platforms' => [
[
'id' => '<string>',
'content_type' => '<string>',
'meta' => [
]
]
],
'scheduled_at' => '<string>',
'label_ids' => [
[
]
]
]),
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://app.getkavio.app/api/posts/{post}"
payload := strings.NewReader("{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://app.getkavio.app/api/posts/{post}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.getkavio.app/api/posts/{post}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_bodyPosts
Update post
Update a post’s content, schedule, enabled platforms, or labels — and trigger publishing.
PUT
/
posts
/
{post}
Update post
curl --request PUT \
--url https://app.getkavio.app/api/posts/{post} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"status": "<string>",
"content": "<string>",
"media": [
{}
],
"platforms": [
{
"id": "<string>",
"content_type": "<string>",
"meta": {}
}
],
"scheduled_at": "<string>",
"label_ids": [
{}
]
}
'import requests
url = "https://app.getkavio.app/api/posts/{post}"
payload = {
"status": "<string>",
"content": "<string>",
"media": [{}],
"platforms": [
{
"id": "<string>",
"content_type": "<string>",
"meta": {}
}
],
"scheduled_at": "<string>",
"label_ids": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
status: '<string>',
content: '<string>',
media: [{}],
platforms: [{id: '<string>', content_type: '<string>', meta: {}}],
scheduled_at: '<string>',
label_ids: [{}]
})
};
fetch('https://app.getkavio.app/api/posts/{post}', 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://app.getkavio.app/api/posts/{post}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'status' => '<string>',
'content' => '<string>',
'media' => [
[
]
],
'platforms' => [
[
'id' => '<string>',
'content_type' => '<string>',
'meta' => [
]
]
],
'scheduled_at' => '<string>',
'label_ids' => [
[
]
]
]),
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://app.getkavio.app/api/posts/{post}"
payload := strings.NewReader("{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://app.getkavio.app/api/posts/{post}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.getkavio.app/api/posts/{post}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"<string>\",\n \"content\": \"<string>\",\n \"media\": [\n {}\n ],\n \"platforms\": [\n {\n \"id\": \"<string>\",\n \"content_type\": \"<string>\",\n \"meta\": {}\n }\n ],\n \"scheduled_at\": \"<string>\",\n \"label_ids\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_bodyRequest
string
required
The post ID.
string
required
The post status. One of:
draft— keep as draftscheduled— schedule for the time given inscheduled_at(must be in the future)publishing— publish immediately: dispatches the publish job to all enabled platforms
scheduled requires a scheduled_at in the future.string
The post caption/text body.
array
Media items to associate with the post. Most callers upload first via
POST /posts/{post}/media (file) or POST /posts/{post} /media/from-url (URL) and let those endpoints
append to media[] directly.array
An array of platform entries to enable. Any platform NOT listed here will be disabled. Pass an empty array to disable all.
Show child attributes
Show child attributes
string
required
The post_platform entry ID (from
GET /posts/{id} or GET /posts).string
Override the content_type for this platform (e.g.
linkedin_carousel instead of the default linkedin_post). Use GET /content-types to discover valid values. Cross-validated against the platform of the underlying social account.object
Per-platform metadata override. Examples:
- Pinterest (
pinterest_pin,pinterest_video_pin,pinterest_carousel) —meta.board_idis required to publish. If you don’t pass it per-post and the social account doesn’t have adefault_board_idset, the publish job fails withPinterest board_id is required. Fetch board IDs from Pinterest’s/v5/boardsendpoint or pick one in the dashboard’s Accounts page. - TikTok (videos) —
meta.privacy_level(PUBLIC_TO_EVERYONE,MUTUAL_FOLLOW_FRIENDS,FOLLOWER_OF_CREATOR,SELF_ONLY),meta.disable_comment,meta.disable_duet,meta.disable_stitch,meta.brand_content_toggle,meta.brand_organic_toggle. Fortiktok_photo, onlyprivacy_levelanddisable_commentapply.
meta keys — unknown keys are stored and ignored at publish time. The web app validates meta.board_id upfront for Pinterest content types; REST callers must enforce it themselves.string
ISO 8601 datetime. Required when
status=scheduled.array
An array of label UUIDs to assign to the post. Replaces existing labels.
Response
Returns the updated post. Returns422 with { "message": "Cannot edit a published post." } if the post has already been published.
curl -X PUT https://app.getkavio.app/api/posts/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "publishing",
"content": "Launching now!",
"platforms": [
{ "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d", "content_type": "linkedin_post" }
],
"label_ids": ["c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f"]
}'
{
"id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"content": "Launching now!",
"media": [],
"status": "publishing",
"scheduled_at": "2025-01-15 10:30:00",
"published_at": null,
"platforms": [
{
"id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
"platform": "linkedin",
"content_type": "linkedin_post",
"status": "publishing",
"enabled": true,
"platform_url": null,
"published_at": null,
"error_message": null,
"display_name": "John Doe",
"display_username": "johndoe",
"display_avatar": "https://media.licdn.com/.../avatar.jpg",
"social_account": {
"id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
"platform": "linkedin",
"display_name": "John Doe",
"username": "johndoe",
"is_active": true,
"status": "connected"
}
}
],
"labels": [
{
"id": "c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f",
"name": "Product Launch",
"color": "#4f46e5",
"created_at": "2025-01-10 08:00:00",
"updated_at": "2025-01-10 08:00:00"
}
],
"created_at": "2025-01-14 09:00:00",
"updated_at": "2025-01-14 09:30:00"
}
Tips
- To publish an existing draft, send only
{ "status": "publishing" }— content/platforms already saved are kept. - To schedule, send
{ "status": "scheduled", "scheduled_at": "2025-12-31T15:30:00Z" }. - To toggle which platforms are active without changing content, send only the
platforms[]array.

