Skip to content

List posts

GET
/v1/accounts/{accountId}/posts
curl --request GET \
--url 'https://api-v1.tailwind.ai/v1/accounts/example/posts?status=draft&limit=50' \
--header 'Authorization: Bearer <token>'

List scheduled posts for an account. Filter by status to get drafts, queued, sent, uploading, failed, or missed posts. status=draft omits drafts not yet assigned to any Pinterest account (such as some Made For You drafts), which the Pin Scheduler counts in its “drafts that aren’t assigned to a Pinterest account yet” banner. The draft count can be lower than the dashboard’s by that number: that gap is expected, not missing drafts, but a larger one is worth reporting. Assigning them to the account from that banner makes them list. A missed post is a queued post whose send time has passed without publishing; it is listed with status missed. Failed, missed and uploading posts are windowed by their send time; a failed post that had already published is windowed by when it published. Queued posts are returned in send-time order, soonest first, and without a startDate begin at the current time, so overdue ones are listed only as missed; every other status is returned newest first. A draft carrying a generationId was generated by Tailwind’s AI, from POST /v1/accounts/{accountId}/generations or a connected feed, and is waiting for review: it never publishes on its own until it is scheduled, and it can be edited, re-designed through the design endpoints, or deleted instead.

accountId
required
string

Numeric Tailwind account ID returned by GET /v1/accounts

status
string
default: queued
Allowed values: draft queued sent uploading failed missed

Filter by post status

cursor
string

Pagination cursor from the previous response. Pass it unchanged with the same status, startDate and endDate; a cursor that cannot be used for this list is a 400.

limit
integer
default: 50 >= 1 <= 100

Number of results to return (1-100)

startDate
string format: date-time

Filter posts scheduled after this date (ISO 8601). Required for sent, uploading and missed status; for queued and failed, give both startDate and endDate or neither.

endDate
string format: date-time

Filter posts scheduled before this date (ISO 8601). Required for sent, uploading and missed status; for queued and failed, give both startDate and endDate or neither. For missed, a date after now is treated as now.

List of posts

Media typeapplication/json
object
data
object
posts
Array<object>
object
id

Post ID

string
status

Post status. draft = saved in Tailwind only, not created on Pinterest; queued = scheduled; sent = published to Pinterest.

string
Allowed values: draft queued sent uploading failed missed
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
boardName

Name of the Board in boardId, as Tailwind last saw it when listing the account’s Boards. Returned by the get and list reads only; absent when the Pin has no Board or the Board has not been listed yet, such as one created moments ago.

string
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). This is the id GET /v1/accounts/{accountId}/pins/{pinId}/analytics takes.

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 Tailwind’s AI generated it from a URL (matches the id returned by POST /v1/accounts/{accountId}/generations) or from a connected feed. Absent for posts created any other way. A draft with one is a generated draft waiting for review.

string
nullable
failureReason

Why a failed Pin did not publish, as a stable code such as board_not_found, expired_token or user_rate_limit. Present only when status is failed and Tailwind recorded a reason. New codes are added over time, so treat an unrecognized code as a generic failure.

string
failureMessage

A user-facing explanation of failureReason and what to do next, the same copy the Tailwind dashboard shows for a failed Pin. Present whenever failureReason is; a code with no specific copy gets a generic explanation.

string
cursor

Cursor for next page, null if no more results

string
nullable
meta
object
requestId

Unique request ID for debugging

string
Example
{
"data": {
"posts": [
{
"status": "draft",
"mediaType": "image"
}
]
}
}

Invalid request

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable reason. On PAYMENT_REQUIRED errors it is the denial reason: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded. Other errors may carry an operation-specific reason, such as pinterest_reconnect_required, pinterest_rate_limited, pinterest_timeout, pinterest_request_failed or list_boards_upstream_failed; each operation’s documented error responses show the values it returns. Branch on reason rather than parsing message.

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 reason. On PAYMENT_REQUIRED errors it is the denial reason: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded. Other errors may carry an operation-specific reason, such as pinterest_reconnect_required, pinterest_rate_limited, pinterest_timeout, pinterest_request_failed or list_boards_upstream_failed; each operation’s documented error responses show the values it returns. Branch on reason rather than parsing message.

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

Resource not found

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable reason. On PAYMENT_REQUIRED errors it is the denial reason: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded. Other errors may carry an operation-specific reason, such as pinterest_reconnect_required, pinterest_rate_limited, pinterest_timeout, pinterest_request_failed or list_boards_upstream_failed; each operation’s documented error responses show the values it returns. Branch on reason rather than parsing message.

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

Rate limit exceeded

Media typeapplication/json
object
error
object
code

Error code

string
message

Error message

string
reason

Machine-readable reason. On PAYMENT_REQUIRED errors it is the denial reason: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded. Other errors may carry an operation-specific reason, such as pinterest_reconnect_required, pinterest_rate_limited, pinterest_timeout, pinterest_request_failed or list_boards_upstream_failed; each operation’s documented error responses show the values it returns. Branch on reason rather than parsing message.

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 10000 requests for this organization exceeded. Resets at midnight UTC."
},
"meta": {
"requestId": "abc123"
}
}
Retry-After
integer

Seconds until the daily limit resets at midnight UTC.