POST Posts
POST /brands/{brandId}/collections/{collectionId}/postsCreates a post in the given collection. The post is published to every channel in the collection, subject to publishMode.
Path parameters
Section titled “Path parameters”| Parameter | Type | Description |
|---|---|---|
brandId | integer | ID from the brands list. |
collectionId | integer | ID from the collections list. |
Request body fields
Section titled “Request body fields”| Field | Type | Required? | Description |
|---|---|---|---|
publishMode | string | ✅ | QUEUE, SCHEDULE, IMMEDIATE, or DRAFT. |
caption | string | ✅ (unless poll is set) | Main post text. 1-3000 characters. |
poll | object | ⚠️ (required if no caption) | Poll configuration. See below. |
title | string | No | Optional title (used by YouTube, Pinterest, etc.). Max 255 chars. |
alt | string | No | Alt text for accessibility. Max 255 chars. |
link | string | No | URL to attach to the post. Max 1000 chars. |
scheduledAt | string | ✅ (if publishMode = SCHEDULE) | Future timestamp in format Y-m-d H:i:s (e.g. “2026-10-10 12:12:00”). Interpreted in the brand’s timezone (see timezone field on the brand). |
postAsStory | boolean | No | If true, publish as a Story on channels that support Stories (Instagram and Facebook). Channels on other platforms in the collection will publish the post as a regular feed post. |
comment | object | No | Auto-comment posted after publish. See below. |
media | array | No | Media attachments: use id from /media upload or a direct url. See below. |
platforms | object | No | Platform-specific overrides, see Platform-specific options. |
Poll object
Section titled “Poll object”| Field | Type | Required? | Description |
|---|---|---|---|
question | string | ✅ | Poll question. Max 280 chars. |
options | array | ✅ | 2-4 option strings. Each option max 30 chars. |
period | string | ✅ | How long the poll is open: 1d, 3d, or 7d. |
correctOptionIndex | integer | No | Zero-based index of the “correct” answer (quiz mode). |
explanation | string | No | Shown after voting. Max 512 chars. |
Comment object
Section titled “Comment object”| Field | Type | Required? | Description |
|---|---|---|---|
comment | string | ✅ | Comment text. Max 1000 chars. |
delay | integer | ✅ | Seconds to wait after publishing before posting the comment. |
Media array
Section titled “Media array”Each element must have either id (from /media upload) or url (direct public URL), but not both.
"media": [ { "id": "bWVkaWEvWThQT0NxWWFRcEtIRXZYMW16U0hsZFRnN0hFdEpYVzIubXA0" }, { "url": "https://example.com/hero.jpg" }]Examples
Section titled “Examples”Example 1: Simple immediate text post
Section titled “Example 1: Simple immediate text post”curl -X POST https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "caption": "New drop alert 🌿 The Rosewater Mist is back in stock — shop now at fernwoodbotanicals.example.com", "publishMode": "IMMEDIATE" }'const payload = { caption: 'New drop alert 🌿 The Rosewater Mist is back in stock — shop now at fernwoodbotanicals.example.com', publishMode: 'IMMEDIATE',};
const response = await fetch( 'https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), });
const data = await response.json();console.log(data);<?php
$payload = [ 'caption' => 'New drop alert 🌿 The Rosewater Mist is back in stock — shop now at fernwoodbotanicals.example.com', 'publishMode' => 'IMMEDIATE',];
$ch = curl_init('https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts');
curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true,]);
$response = curl_exec($ch);curl_close($ch);
echo $response;Response: 201 Created
{ "status": "success", "data": { "id": 4364709, "message": "Post created successfully" }}Example 2: Scheduled post with a single image
Section titled “Example 2: Scheduled post with a single image”curl -X POST https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "caption": "Something new is coming to the garden next week 🌱 Stay tuned.", "alt": "Close-up of dew on a fern leaf at sunrise.", "publishMode": "SCHEDULE", "scheduledAt": "2026-10-10 12:12:00", "media": [ { "id": "bWVkaWEvcmo2dzRhSVY4YUJOMWJoU3c4U2t6VEJOenVXcjRoTmsuanBn" } ] }'const payload = { caption: 'Something new is coming to the garden next week 🌱 Stay tuned.', alt: 'Close-up of dew on a fern leaf at sunrise.', publishMode: 'SCHEDULE', scheduledAt: '2026-10-10 12:12:00', media: [ { id: 'bWVkaWEvcmo2dzRhSVY4YUJOMWJoU3c4U2t6VEJOenVXcjRoTmsuanBn' }, ],};
const response = await fetch( 'https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), });
const data = await response.json();console.log(data);<?php
$payload = [ 'caption' => 'Something new is coming to the garden next week 🌱 Stay tuned.', 'alt' => 'Close-up of dew on a fern leaf at sunrise.', 'publishMode' => 'SCHEDULE', 'scheduledAt' => '2026-10-10 12:12:00', 'media' => [ ['id' => 'bWVkaWEvcmo2dzRhSVY4YUJOMWJoU3c4U2t6VEJOenVXcjRoTmsuanBn'], ],];
$ch = curl_init('https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts');
curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true,]);
$response = curl_exec($ch);curl_close($ch);
echo $response;Response: 201 Created:
{ "status": "success", "data": { "id": 4364710, "message": "Post created successfully" }}Example 3: Poll post
Section titled “Example 3: Poll post”curl -X POST https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "publishMode": "IMMEDIATE", "poll": { "question": "Which scent should we bring back for summer?", "options": ["Rosewater & Oak", "Wild Fig", "Jasmine Honey"], "period": "3d" } }'const payload = { publishMode: 'IMMEDIATE', poll: { question: 'Which scent should we bring back for summer?', options: ['Rosewater & Oak', 'Wild Fig', 'Jasmine Honey'], period: '3d', },};
const response = await fetch( 'https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), });
const data = await response.json();console.log(data);<?php
$payload = [ 'publishMode' => 'IMMEDIATE', 'poll' => [ 'question' => 'Which scent should we bring back for summer?', 'options' => ['Rosewater & Oak', 'Wild Fig', 'Jasmine Honey'], 'period' => '3d', ],];
$ch = curl_init('https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts');
curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true,]);
$response = curl_exec($ch);curl_close($ch);
echo $response;Example 4: Full example with every option
Section titled “Example 4: Full example with every option”This mirrors the Postman collection’s example. Most real requests will use a small subset of these fields.
curl -X POST https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Spring Collection Launch", "caption": "Our new Spring Collection is live 🌿 Hand-formulated with botanicals from our own garden. Link in bio to shop.", "alt": "Flat lay of Spring Collection skincare bottles on a bed of fresh herbs.", "link": "https://fernwoodbotanicals.example.com/spring", "publishMode": "SCHEDULE", "scheduledAt": "2026-10-10 12:12:00", "postAsStory": true, "comment": { "comment": "Tap the link above to see the full collection 🌱", "delay": 30 }, "media": [ { "id": "bWVkaWEvWThQT0NxWWFRcEtIRXZYMW16U0hsZFRnN0hFdEpYVzIubXA0" }, { "url": "https://media.nuelink.com/media/bWVkaWEvanNadVY5Rm8xODdMUWJLZ2wzUmRyd2gzTkNRbHdZVE1TdUpR" } ], "platforms": { "instagram": { "collab": "harperandvine", "location": { "id": "abc123", "name": "Brooklyn, NY" }, "trialReel": "MANUAL", "shareToFeed": true }, "facebook": { "collab": "harperandvine", "location": { "id": "abc123", "name": "Brooklyn, NY" } }, "tiktok": { "sendToInbox": true }, "youtube": { "tags": ["skincare", "botanicals", "spring-collection"], "playlists": [ { "channelId": 60107, "playlistIds": ["PL123", "PL456"] } ] } } }'const payload = { title: 'Spring Collection Launch', caption: 'Our new Spring Collection is live 🌿 Hand-formulated with botanicals from our own garden. Link in bio to shop.', alt: 'Flat lay of Spring Collection skincare bottles on a bed of fresh herbs.', link: 'https://fernwoodbotanicals.example.com/spring', publishMode: 'SCHEDULE', scheduledAt: '2026-10-10 12:12:00', postAsStory: true, comment: { comment: 'Tap the link above to see the full collection 🌱', delay: 30, }, media: [ { id: 'bWVkaWEvWThQT0NxWWFRcEtIRXZYMW16U0hsZFRnN0hFdEpYVzIubXA0' }, { url: 'https://media.nuelink.com/media/bWVkaWEvanNadVY5Rm8xODdMUWJLZ2wzUmRyd2gzTkNRbHdZVE1TdUpR', }, ], platforms: { instagram: { collab: 'harperandvine', location: { id: 'abc123', name: 'Brooklyn, NY' }, trialReel: 'MANUAL', shareToFeed: true, }, facebook: { collab: 'harperandvine', location: { id: 'abc123', name: 'Brooklyn, NY' }, }, tiktok: { sendToInbox: true, }, youtube: { tags: ['skincare', 'botanicals', 'spring-collection'], playlists: [ { channelId: 60107, playlistIds: ['PL123', 'PL456'] }, ], }, },};
const response = await fetch( 'https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), });
const data = await response.json();console.log(data);<?php
$payload = [ 'title' => 'Spring Collection Launch', 'caption' => 'Our new Spring Collection is live 🌿 Hand-formulated with botanicals from our own garden. Link in bio to shop.', 'alt' => 'Flat lay of Spring Collection skincare bottles on a bed of fresh herbs.', 'link' => 'https://fernwoodbotanicals.example.com/spring', 'publishMode' => 'SCHEDULE', 'scheduledAt' => '2026-10-10 12:12:00', 'postAsStory' => true, 'comment' => [ 'comment' => 'Tap the link above to see the full collection 🌱', 'delay' => 30, ], 'media' => [ ['id' => 'bWVkaWEvWThQT0NxWWFRcEtIRXZYMW16U0hsZFRnN0hFdEpYVzIubXA0'], ['url' => 'https://media.nuelink.com/media/bWVkaWEvanNadVY5Rm8xODdMUWJLZ2wzUmRyd2gzTkNRbHdZVE1TdUpR'], ], 'platforms' => [ 'instagram' => [ 'collab' => 'harperandvine', 'location' => ['id' => 'abc123', 'name' => 'Brooklyn, NY'], 'trialReel' => 'MANUAL', 'shareToFeed' => true, ], 'facebook' => [ 'collab' => 'harperandvine', 'location' => ['id' => 'abc123', 'name' => 'Brooklyn, NY'], ], 'tiktok' => [ 'sendToInbox' => true, ], 'youtube' => [ 'tags' => ['skincare', 'botanicals', 'spring-collection'], 'playlists' => [ ['channelId' => 60107, 'playlistIds' => ['PL123', 'PL456']], ], ], ],];
$ch = curl_init('https://nuelink.com/api/public/v1/brands/13493/collections/40656/posts');
curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json', ], CURLOPT_RETURNTRANSFER => true,]);
$response = curl_exec($ch);curl_close($ch);
echo $response;Error Examples
Section titled “Error Examples”Missing caption and no poll - 422:
{ "status": "error", "message": "The given data was invalid.", "errors": { "caption": [ "The caption field is required when poll is not present." ] }}Invalid scheduledAt (past date) - 422:
{ "status": "error", "message": "The given data was invalid.", "errors": { "scheduledAt": [ "The scheduled at must be a future date." ] }}Unknown YouTube channel referenced in playlists - 404:
{ "status": "error", "message": "Channel not found or does not belong to the brand", "errors": { "platforms.youtube.playlists.0.channelId": "Channel not found or does not belong to the brand" }}Collection doesn’t exist — 404:
{ "status": "error", "message": "Collection not found.", "errors": { "collection": "Collection not found." }}