Content Items
Create and manage reusable content items.
Content items are the core reusable content entity in Wahlu. Each content item stores per-platform settings (text, media, and options) that define what gets published. Set the platform settings for each platform you want to publish to — leave a platform as null to skip it.
All endpoints use /content-items.
List content items
/v1/brands/:brand_id/content-itemsReturns content items for a brand. Requires posts:read.
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number. Defaults to 1. |
limit | integer | Items per page. Defaults to 50, max 100. |
sort_by | string | Field to sort by. One of: created_at, updated_at, name. Defaults to created_at. |
sort_dir | string | Sort direction. One of: asc, desc. Defaults to desc. |
curl "https://api.wahlu.com/v1/brands/brand_abc123/content-items?limit=10" \
-H "Authorization: Bearer wahlu_live_your_api_key_here"{
"success": true,
"data": [
{
"id": "content_item_xyz789",
"name": "Product Launch Announcement",
"brand_id": "brand_abc123",
"label_ids": ["label_promo"],
"created_by": "user_abc",
"thumbnail_timestamp": 0,
"instagram_settings": {
"description": "Excited to share our latest update! #launch",
"media_ids": ["media_img1"],
"post_type": "GRID_POST"
},
"tiktok_settings": null,
"facebook_settings": null,
"youtube_settings": null,
"linkedin_settings": null,
"created_at": "2026-02-10T09:00:00Z",
"updated_at": "2026-02-10T09:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"has_more": false
}
}Get a content item
/v1/brands/:brand_id/content-items/:content_item_idReturns a single content item. Requires posts:read.
Create a content item
/v1/brands/:brand_id/content-itemsCreates a new content item. Requires posts:write.
Request body
| Parameter | Type | Description |
|---|---|---|
name* | string | Content item name/title. Max 500 characters. |
label_ids | string[] | Label IDs to attach. Max 50 items. |
thumbnail_timestamp | number | Video thumbnail timestamp in seconds. |
instagram_settings | object | null | Instagram post configuration. See platform settings below. |
tiktok_settings | object | null | TikTok post configuration. See platform settings below. |
facebook_settings | object | null | Facebook post configuration. See platform settings below. |
youtube_settings | object | null | YouTube post configuration. See platform settings below. |
linkedin_settings | object | null | LinkedIn post configuration. See platform settings below. |
curl -X POST https://api.wahlu.com/v1/brands/brand_abc123/content-items \
-H "Authorization: Bearer wahlu_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Product Launch Announcement",
"instagram_settings": {
"description": "Excited to share our latest update! #launch",
"media_ids": ["media_img1"],
"post_type": "GRID_POST"
},
"linkedin_settings": {
"description": "We are thrilled to announce our latest product launch.",
"media_ids": ["media_img1"],
"post_type": "LI_IMAGE",
"visibility": "PUBLIC"
}
}'Platform settings
Each platform has its own settings object. All fields within a platform settings object are optional — sensible defaults are applied. Set a platform to null (or omit it) to skip publishing to that platform. Media IDs reference files uploaded via the Media API — media must reach completed status before being used.
instagram_settings
| Parameter | Type | Description |
|---|---|---|
description | string | Post caption. |
media_ids | string[] | Media IDs to attach. Upload media first via the Media API. |
post_type | string | One of: GRID_POST, STORY, REEL. Defaults to REEL. |
{
"description": "Check out our new product! #launch",
"media_ids": ["media_abc123"],
"post_type": "REEL"
}tiktok_settings
| Parameter | Type | Description |
|---|---|---|
description | string | Post caption. |
media_ids | string[] | Media IDs to attach. |
post_type | string | One of: VIDEO, IMAGE, CAROUSEL. |
privacy_level | string | null | One of: PUBLIC_TO_EVERYONE, FOLLOWER_OF_CREATOR, MUTUAL_FOLLOW_FRIENDS, SELF_ONLY. |
agreed_to_terms | boolean | Must be true to publish. Defaults to false. |
is_aigc | boolean | Whether the content is AI-generated. Defaults to false. |
is_commercial_content | boolean | Whether this is commercial content. Defaults to false. |
commercial_types | string[] | Required when is_commercial_content is true. Values: YOUR_BRAND, BRANDED_CONTENT. |
allow_comment | boolean | Whether comments are allowed. |
allow_duet | boolean | Whether duets are allowed. |
allow_stitch | boolean | Whether stitches are allowed. |
auto_add_music | boolean | Whether to auto-add music. |
{
"description": "New product demo #fyp",
"media_ids": ["media_video1"],
"post_type": "VIDEO",
"privacy_level": "PUBLIC_TO_EVERYONE",
"agreed_to_terms": true,
"is_aigc": false
}facebook_settings
| Parameter | Type | Description |
|---|---|---|
description | string | Post caption. |
media_ids | string[] | Media IDs to attach. |
post_type | string | One of: FB_POST, FB_STORY, FB_REEL, FB_TEXT. Defaults to FB_REEL. |
{
"description": "Exciting news from us today!",
"media_ids": ["media_img1", "media_img2"],
"post_type": "FB_POST"
}youtube_settings
| Parameter | Type | Description |
|---|---|---|
title | string | Video title. |
description | string | Video description. |
media_ids | string[] | Media IDs to attach. |
post_type | string | One of: YT_SHORT, YT_VIDEO. Defaults to YT_SHORT. |
privacy_level | string | One of: PUBLIC, UNLISTED, PRIVATE. Defaults to PUBLIC. |
tags | string[] | Video tags for discoverability. |
notify_subscribers | boolean | Whether to notify subscribers. Defaults to false. |
made_for_kids | boolean | Whether the video is made for kids. Defaults to false. |
{
"title": "Product Demo - Quick Overview",
"description": "A 60-second look at our new features.",
"media_ids": ["media_video1"],
"post_type": "YT_SHORT",
"privacy_level": "PUBLIC",
"tags": ["product", "demo", "launch"],
"notify_subscribers": true
}linkedin_settings
| Parameter | Type | Description |
|---|---|---|
description | string | Post text. |
media_ids | string[] | Media IDs to attach. |
post_type | string | One of: LI_TEXT, LI_IMAGE, LI_VIDEO, LI_ARTICLE. Defaults to LI_TEXT. |
visibility | string | One of: PUBLIC, CONNECTIONS. Defaults to PUBLIC. |
title | string | Article title. Used with LI_ARTICLE post type. |
original_url | string | Article URL. Used with LI_ARTICLE post type. |
{
"description": "Thrilled to announce our latest product launch.",
"media_ids": ["media_img1"],
"post_type": "LI_IMAGE",
"visibility": "PUBLIC"
}Full example: create and schedule
This example uploads media, creates a content item for Instagram and LinkedIn, then schedules it via a publish run.
const API = "https://api.wahlu.com/v1";
const headers = {
Authorization: "Bearer wahlu_live_your_api_key_here",
"Content-Type": "application/json",
};
// 1. Upload media (see Media API for full details)
const uploadRes = await fetch(`${API}/brands/${brandId}/media/upload-url`, {
method: "POST",
headers,
body: JSON.stringify({
filename: "product-hero.jpg",
content_type: "image/jpeg",
}),
});
const { data: upload } = await uploadRes.json();
await fetch(upload.upload_url, {
method: "PUT",
headers: { "Content-Type": "image/jpeg" },
body: imageBuffer,
});
await fetch(`${API}/brands/${brandId}/media/${upload.id}`, {
method: "PATCH",
headers,
body: JSON.stringify({ status: "ready_for_processing" }),
});
// Wait for media processing to complete
// (poll GET /media/:id until status === "completed")
// 2. Create the content item
const itemRes = await fetch(`${API}/brands/${brandId}/content-items`, {
method: "POST",
headers,
body: JSON.stringify({
name: "Product Launch",
instagram_settings: {
description: "Our new product is here! #launch",
media_ids: [upload.id],
post_type: "GRID_POST",
},
linkedin_settings: {
description: "We are excited to announce our latest product.",
media_ids: [upload.id],
post_type: "LI_IMAGE",
visibility: "PUBLIC",
},
}),
});
const { data: item } = await itemRes.json();
// 3. Schedule a publish run
await fetch(`${API}/brands/${brandId}/publish-runs`, {
method: "POST",
headers,
body: JSON.stringify({
content_item_id: item.id,
scheduled_at: "2026-02-20T09:00:00Z",
integration_ids: ["int_instagram_123", "int_linkedin_456"],
}),
});Update a content item
/v1/brands/:brand_id/content-items/:content_item_idUpdates a content item. Only provided fields are changed. Requires posts:write.
Delete a content item
/v1/brands/:brand_id/content-items/:content_item_idDeletes a content item. Requires posts:write.
curl -X DELETE https://api.wahlu.com/v1/brands/brand_abc123/content-items/content_item_xyz789 \
-H "Authorization: Bearer wahlu_live_your_api_key_here"