Skip to content

Schedule post

POST
/v1/accounts/{accountId}/posts/{postId}/schedule
curl --request POST \
--url https://api-v1.tailwind.ai/v1/accounts/example/posts/example/schedule \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "sendAt": "2026-04-15T12:00:00Z", "useNextOpenSlot": false, "boardId": "example", "boardSectionId": "example" }'

Schedule a draft post or reschedule a queued post, passing exactly one of sendAt or useNextOpenSlot. useNextOpenSlot places the Pin in the account’s next open smart schedule slot, honoring the account’s Pin Spacing rules for the Pin’s destination url — the same calculation the Pin Scheduler runs. The post must have title, description, and url set before it can be scheduled. Cannot reschedule posts that have already been sent or are uploading. A 422 means the account’s schedule has no open slot; a 503 means resolving one timed out. Neither writes anything, and any pin_schedule charge already taken is refunded.

accountId
required
string

Numeric Tailwind account ID returned by GET /v1/accounts

postId
required
string

Post ID

Media typeapplication/json
One of:

Provide exactly one of sendAt or useNextOpenSlot. A 422 means the account’s schedule has no open slot; a 503 means resolving one timed out. Neither writes anything, and any pin_schedule charge is refunded.

object
sendAt
required

Explicit publish time (ISO 8601), in the future and within 10 years. Exactly one of sendAt or useNextOpenSlot is required.

string format: date-time
useNextOpenSlot

Schedule into the account’s next open smart schedule slot, honoring the account’s Pin Spacing rules for the Pin’s destination url. Exactly one of sendAt or useNextOpenSlot is required; must be true when provided.

boolean
boardId

Target board ID. Must be the numeric Pinterest board ID from GET /v1/accounts/{accountId}/boards — not a board name or URL. A leading “b_” (Tailwind CSV export format) is accepted and stripped. Required when scheduling a draft that doesn’t already have a board assigned.

string
boardSectionId

Section to publish into, validated against the board this Pin ends up on. Send “” to publish to the board root. Supplying boardId WITHOUT this field clears any section the Pin already had, since a section is only valid on its own board. Use GET /v1/accounts/{accountId}/boards/{boardId}/sections to look up section IDs.

string

Post scheduled

Media typeapplication/json
object
data
object
post
object
id

Post ID

string
status

Post status

string
Allowed values: draft queued sent uploading
mediaUrl

URL of the media file

string
mediaType

Type of media

string
Allowed values: image video
carouselItems

Further images of a carousel Pin, in order after the cover in mediaUrl. Absent on a single-image Pin. Per-slide title, description and link are reported when the Pin carries them, but cannot be set through this API yet.

Array<object>
object
url

URL of this image

string
title

Per-slide title, when the Pin has one

string
description

Per-slide description, when the Pin has one

string
link

Per-slide destination, when the Pin has one

string
title

Pin title

string
nullable
description

Pin description

string
nullable
url

Destination URL

string
nullable
boardId

Target board ID

string
nullable
boardSectionId

Section of boardId the Pin publishes into. Null when it publishes to the board root.

string
nullable
altText

Alt text for accessibility

string
nullable
sendAt

Scheduled send time (Unix timestamp)

integer
nullable
sentAt

Actual send time (Unix timestamp)

integer
nullable
createdAt

Creation time (Unix timestamp)

integer
pinId

Pinterest pin ID (only present after publishing)

string
nullable
isSimplifiedPin

Whether this is a simplified pin (as opposed to a standard pin)

boolean
productTagPinIds

Pinterest product-catalog pin IDs tagged on the pin (business accounts only).

Array<string>
generationId

ID of the AI generation that produced this post, when it was generated from a URL (matches the id returned by POST /v1/accounts/{accountId}/generations). Absent for posts created any other way.

string
nullable
meta
object
requestId

Unique request ID for debugging

string
Example
{
"data": {
"post": {
"status": "draft",
"mediaType": "image"
}
}
}

Invalid request

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Example
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request body"
},
"meta": {
"requestId": "abc123"
}
}

Authentication required or invalid bearer credentials

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Example
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
},
"meta": {
"requestId": "abc123"
}
}

Billing denied — scheduling requires an available credit or trial allowance on the account, or would exceed the plan’s post limit for the billing period

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Example
{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Not enough credits to schedule this post.",
"reason": "insufficient_credits"
},
"meta": {
"requestId": "abc123"
}
}

Resource not found

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Example
{
"error": {
"code": "NOT_FOUND",
"message": "Account not found"
},
"meta": {
"requestId": "abc123"
}
}

UseNextOpenSlot only: the account’s smart schedule has no open slot to publish into.

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"reason": "example",
"resolve_url": "example"
},
"meta": {
"requestId": "example"
}
}

Rate limit exceeded

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Example
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Daily rate limit of 5000 requests exceeded. Resets at midnight UTC."
},
"meta": {
"requestId": "abc123"
}
}

UseNextOpenSlot only: timed out resolving the next open slot. Nothing was scheduled; retry, or pass an explicit sendAt instead.

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.

string
resolve_url

Present on PAYMENT_REQUIRED errors: where the denial can be resolved. Reason-specific, because buying credits does not clear a trial, access or connection denial. Requests sent with X-Request-Source: mcp receive an informational plans page instead, so agent surfaces never present a purchase link.

string
meta
object
requestId

Unique request ID for debugging

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"reason": "example",
"resolve_url": "example"
},
"meta": {
"requestId": "example"
}
}