Skip to content

POST Posts

POST /brands/{brandId}/collections/{collectionId}/posts

Creates a post in the given collection. The post is published to every channel in the collection, subject to publishMode.

ParameterTypeDescription
brandIdintegerID from the brands list.
collectionIdintegerID from the collections list.
FieldTypeRequired?Description
publishModestringQUEUE, SCHEDULE, IMMEDIATE, or DRAFT.
captionstring(unless poll is set)Main post text. 1-3000 characters.
pollobject⚠️ (required if no caption)Poll configuration. See below.
titlestringNoOptional title (used by YouTube, Pinterest, etc.). Max 255 chars.
altstringNoAlt text for accessibility. Max 255 chars.
linkstringNoURL to attach to the post. Max 1000 chars.
scheduledAtstring(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).
postAsStorybooleanNoIf 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.
commentobjectNoAuto-comment posted after publish. See below.
mediaarrayNoMedia attachments: use id from /media upload or a direct url. See below.
platformsobjectNoPlatform-specific overrides, see Platform-specific options.

ℹ️ scheduledAt timezone: Timestamps are interpreted in the brand’s timezone, which you can read from the timezone field returned by GET /brands. For example, if the brand’s timezone is America/New_York and you send “2026-10-10 12:12:00”, the post will publish at 12:12 PM Eastern Time.

ℹ️ publishMode values: Nuelink has a built-in Queue System per brand that manages scheduled posts (with pause, resume, and shuffle controls in the dashboard). QUEUE adds the post to that queue using the next available time slot; SCHEDULE places the post at an exact scheduledAt time; IMMEDIATE publishes now; DRAFT saves the post without publishing or scheduling.

FieldTypeRequired?Description
questionstringPoll question. Max 280 chars.
optionsarray2-4 option strings. Each option max 30 chars.
periodstringHow long the poll is open: 1d, 3d, or 7d.
correctOptionIndexintegerNoZero-based index of the “correct” answer (quiz mode).
explanationstringNoShown after voting. Max 512 chars.

ℹ️ Platforms that support polls: Polls and quizzes are supported on LinkedIn, X, Telegram, Threads, Mastodon, and Bluesky. Channels on other platforms in the collection will ignore the poll (or fall back to a caption-only post).

FieldTypeRequired?Description
commentstringComment text. Max 1000 chars.
delayintegerSeconds to wait after publishing before posting the comment.

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" }
]

ℹ️ Docs-only clarification: The OpenAPI schema marks both id and url as optional with no mutual-exclusion rule. Documenting the intended behavior here — worth tightening the schema using oneOf.

Terminal window
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"
}'

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”
Terminal window
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" }
]
}'

Response: 201 Created:

{
"status": "success",
"data": {
"id": 4364710,
"message": "Post created successfully"
}
}
Terminal window
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"
}
}'

This mirrors the Postman collection’s example. Most real requests will use a small subset of these fields.

Terminal window
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"] }
]
}
}
}'

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."
}
}