Skip to content

Get Pin analytics

GET
/v1/accounts/{accountId}/pins/{pinId}/analytics
curl --request GET \
--url https://api-v1.tailwind.ai/v1/accounts/example/pins/example/analytics \
--header 'Authorization: Bearer <token>'

One Pin’s Pinterest performance over a date window: summary totals, a per-day series, and lifetime totals that ignore the window. Figures are organic-only: Pinterest’s per-Pin analytics exclude paid (promoted) distribution, so a promoted Pin reads far lower here than in GET /v1/accounts/{accountId}/top-pins or GET /v1/accounts/{accountId}/analytics — that gap is expected, not an error.

pinId is the PINTEREST Pin id, not the Tailwind postId returned by the posts endpoints. A published post carries its Pinterest pinId; GET /v1/accounts/{accountId}/pins and GET /v1/accounts/{accountId}/top-pins return them directly. Passing a Tailwind postId here returns 404.

A Pin this account owns can be read, including one it saved to a group board owned by someone else. A Pin someone else saved to a group board shared with this account can return 403. Any other Pin id — absent, someone else’s, or unreadable — returns the same 404, so this endpoint cannot be used to probe which Pins exist.

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

pinId
required
string

The Pinterest Pin id — a numeric string. NOT the Tailwind postId from GET /v1/accounts/{accountId}/posts.

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.

The Pin’s analytics over the resolved window

Media typeapplication/json
object
data
object
pinId
required
string
accountId
required
string
boardId
required

The Pinterest board the Pin is saved to — the same id GET /v1/accounts/{accountId}/boards returns.

string
startDate
required
string format: date
endDate
required
string format: date
summaryMetrics
required

This Pin’s totals over the window; dailyMetrics carries the same fields per day. Comment and reaction counts are not windowed: see lifetimeMetrics.

object
dailyMetrics
required
Array<object>
object
date
required

The UTC day these metrics cover

string format: date
dataStatus

Pinterest’s readiness marker for this day — READY, PROCESSING, BEFORE_PIN_CREATED and similar. Anything other than READY explains why the day’s metrics are null or zero; PROCESSING is the only one worth re-reading later.

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
lifetimeMetrics

Totals since the Pin was created, ignoring the requested window. The only place Pinterest reports totalComments (the comment count) and totalReactions; absent when Pinterest reports none.

object
meta
object
requestId

Unique request ID for debugging

string
Examplegenerated
{
"data": {
"pinId": "example",
"accountId": "example",
"boardId": "example",
"startDate": "2026-04-15",
"endDate": "2026-04-15",
"summaryMetrics": {
"additionalProperty": 1
},
"dailyMetrics": [
{
"date": "2026-04-15",
"dataStatus": "example",
"metrics": {
"additionalProperty": 1
}
}
],
"lifetimeMetrics": {
"additionalProperty": 1
}
},
"meta": {
"requestId": "example"
}
}

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

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

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

Pinterest failed the read with an error on its side. Whether it is permanent is unknown, so this stays a 500, but retrying right away will not help; try again later.

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": "INTERNAL_ERROR",
"message": "Pinterest failed to return analytics for this Pin. The error is on Pinterest's side, so retrying right away will not help. Try again later.",
"reason": "pinterest_upstream_error"
},
"meta": {
"requestId": "abc123"
}
}

Pinterest rate-limited the request. Pinterest refused it before acting, so nothing was changed. Distinct from a 429, which means the organization’s shared daily request limit — retry this request in a few minutes rather than backing off across the API.

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": "SERVICE_UNAVAILABLE",
"message": "Pinterest is limiting requests for this account right now. Nothing was changed. Retry in a few minutes.",
"reason": "pinterest_rate_limited"
},
"meta": {
"requestId": "abc123"
}
}
Retry-After
integer

Seconds until Pinterest’s limit for this account resets. Sent by the analytics and Pin inventory operations when Pinterest reports it; absent otherwise.