Skip to content

List top-performing Pins

GET
/v1/accounts/{accountId}/top-pins
curl --request GET \
--url 'https://api-v1.tailwind.ai/v1/accounts/example/top-pins?sortBy=ENGAGEMENT' \
--header 'Authorization: Bearer <token>'

The account’s best-performing Pins over a date window, ranked by one metric and returned in Pinterest’s ranked order.

Ranks by ENGAGEMENT unless sortBy says otherwise, and echoes the metric used back as sortBy. Engagement is the default rather than impressions because it counts what people did with a Pin rather than how often Pinterest showed it.

Each entry carries the Pinterest pinId, which is what GET /v1/accounts/{accountId}/pins/{pinId}/analytics takes — this endpoint is the usual way to find Pins worth reading in detail.

Omit startDate and endDate for the last 30 days (today and the 29 days before it, UTC). Supply both to choose a window; supplying only one is a 400. The window actually used is echoed back as startDate/endDate inside data, so a caller never has to infer the period a number covers. Pinterest’s own limits apply: startDate no more than 90 days before today, endDate no more than 90 days after startDate.

accountId
required
string

Numeric Tailwind account ID returned by GET /v1/accounts

sortBy
string
Allowed values: ENGAGEMENT SAVE IMPRESSION OUTBOUND_CLICK PIN_CLICK

Metric to rank by. Defaults to ENGAGEMENT. Only these five are accepted — Pinterest’s documented sort vocabulary.

startDate
string format: date

First day of the reporting window, as a UTC calendar date (YYYY-MM-DD). Must be supplied together with endDate; omit both for the last 30 days. Pinterest does not report further back than 90 days.

endDate
string format: date

Last day of the reporting window, inclusive, as a UTC calendar date (YYYY-MM-DD). Must be supplied together with startDate. Cannot be more than 90 days after startDate.

Top-performing Pins over the resolved window, ranked by the resolved metric

Media typeapplication/json
object
data
object
accountId
required
string
startDate
required
string format: date
endDate
required
string format: date
sortBy
required
string
Allowed values: ENGAGEMENT SAVE IMPRESSION OUTBOUND_CLICK PIN_CLICK
pins
required
Array<object>

One of the account’s best-performing Pins. A deliberately narrow projection of Pinterest’s Pin payload — tracking parameters, per-metric status flags, promotion state and internal identifiers are not passed through.

object
pinId
required

The Pinterest Pin id. This is the id GET /v1/accounts/{accountId}/pins/{pinId}/analytics takes — not a Tailwind postId.

string
title
string
description
string
destinationUrl

Where the Pin links to

string
pinUrl

The Pin’s own page on Pinterest

string
imageUrl
string
createdAt
string
metrics
required

Pinterest metrics, camelCased (impression, save, saveRate, pinClick, outboundClick, engagement, engagementRate, …). A metric Pinterest does not report for this subject is ABSENT; a metric it reports as not-yet-computed is present and NULL. The two mean different things — absent will never arrive, null may.

object
key
additional properties
number
nullable
meta
object
requestId

Unique request ID for debugging

string
Example
{
"data": {
"sortBy": "ENGAGEMENT"
}
}

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

Pinterest refused to report analytics for this subject. PERMANENT, and distinct from the collaborator-board 403 on the board endpoints: for a Pin, Pinterest has forbidden analytics on it and it will never start reporting; for an account, analytics require a Pinterest business account. Retrying will return the same answer.

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": "FORBIDDEN",
"message": "Pinterest does not permit analytics for this Pin. This is permanent for this Pin — it will not start reporting later, so do not retry.",
"reason": "pinterest_analytics_forbidden"
},
"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"
}
}

The account’s Pinterest connection is no longer usable. Your API key is fine — this is not an authentication failure on Tailwind’s side, which is why it is not a 401. The account holder needs to reconnect Pinterest in Tailwind before this operation can succeed.

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": "UNPROCESSABLE_ENTITY",
"message": "Reconnect your Pinterest account to manage Boards.",
"reason": "pinterest_reconnect_required"
},
"meta": {
"requestId": "abc123"
}
}

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