Skip to content

Tag saved keywords

POST
/v1/keywords/tag
curl --request POST \
--url https://api-v1.tailwind.ai/v1/keywords/tag \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "keywordIds": [ "example" ], "tags": [ "example" ] }'

Apply tags, by name, to up to 100 saved keywords. Every keyword gets every tag in the request. A name the organization has no tag for yet creates that tag; an existing tag is reused rather than duplicated, and re-applying a tag a keyword already has changes nothing, so the call is safe to retry.

If any keyword id is not on this organization’s list, nothing is changed and the unknown ids are named in the error message. Tagging is free and does not consume credits.

Media typeapplication/json
object
keywordIds
required

Saved keyword IDs, from list-keywords

Array<string>
>= 1 items <= 100 items
tags
required

Tag names. Leading and trailing whitespace is trimmed.

Array<string>
>= 1 items <= 10 items
Examplegenerated
{
"keywordIds": [
"example"
],
"tags": [
"example"
]
}

Every keyword in the request, with its tags after the change

Media typeapplication/json
object
data
object
keywords
Array<object>

A keyword on the organization’s saved list — the same list the Tailwind dashboard’s Saved Keywords page shows.

object
id

Saved keyword ID

string
term

The keyword text

string
savedAt

When the keyword was added to the list

string format: date-time
urls

URLs of the organization’s own that this keyword is associated with

Array<string>
tags

Tags the organization has applied to this keyword

Array<object>
object
id
string
name
string
pinterestSearchVolume

Estimated monthly Pinterest search volume. Absent when Tailwind has no volume data for the term; treat a missing value as unknown, not as zero demand.

integer
commercialIntentScore

How strongly the term signals buying intent. Absent when Tailwind has no interest data for it.

number
detectedLanguage

Language detected for the term, e.g. “english”. Absent when Tailwind has no interest data for it.

string
meta
object
requestId

Unique request ID for debugging

string
Examplegenerated
{
"data": {
"keywords": [
{
"id": "example",
"term": "example",
"savedAt": "2026-04-15T12:00:00Z",
"urls": [
"example"
],
"tags": [
{
"id": "example",
"name": "example"
}
],
"pinterestSearchVolume": 1,
"commercialIntentScore": 1,
"detectedLanguage": "example"
}
]
},
"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"
}
}

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.