Select a design variation
const url = 'https://api-v1.tailwind.ai/v1/accounts/example/posts/example/design/variation';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"templateImageUrl":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api-v1.tailwind.ai/v1/accounts/example/posts/example/design/variation \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "templateImageUrl": "example" }'Make one of the Pin’s already-rendered variations the active design. Free and instant: no rendering and no credits. The URL must be one this draft already carries - a templateImageUrl from the design read, the variationUrl a finished regeneration produced, or the pendingMediaUrl reported when workspaceStatus is pending_apply.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Numeric Tailwind account ID returned by GET /v1/accounts
Post ID
Request Bodyrequired
Section titled “Request Bodyrequired”object
A variation URL this draft already carries
Examplegenerated
{ "templateImageUrl": "example"}Responses
Section titled “Responses”The updated design
object
object
A generated Pin’s design, plus the operations this particular draft accepts.
object
How the Pin was generated. template and original are re-renderable; premium is AI-designed. Legacy values are normalized for display, which is why eligibility is reported separately in supportedOperations rather than inferred from this.
The operations this draft actually accepts. Each entry mirrors the predicate its own endpoint enforces; anything absent here is rejected.
The image the Pin will publish with
Text overlaid on the design, not the Pin’s title
object
Pending_apply means a previous edit rendered a design the Pin never received. Apply pendingMediaUrl through the variation endpoint; no re-render is needed.
Present only when workspaceStatus is pending_apply
Returned by GET only. Source photos stored on the SmartPin that generated this Pin, as the SmartPin stands now rather than when this draft was generated. These are not designs: pass a url as mediaUrl to the design update endpoint, or to regenerate on a premium Pin.
object
Present when status is unavailable. smart_pin_not_found: the SmartPin was deleted or the Pin predates the link. lookup_failed: temporary; read again.
Images the user chose for the SmartPin. Empty when Tailwind picks images itself.
Images Tailwind scraped from the source page and scored at its latest ranking. Hosted by Tailwind.
object
Width divided by height
object
Unique request ID for debugging
Example
{ "data": { "design": { "supportedOperations": [ "update" ], "workspaceStatus": "in_sync", "sourceImageCandidates": { "status": "available", "reason": "smart_pin_not_found", "ranked": [ { "quality": "great" } ] } } }}Invalid request
object
object
Error code
Error message
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.
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.
object
Unique request ID for debugging
Example
{ "error": { "code": "BAD_REQUEST", "message": "Invalid request body" }, "meta": { "requestId": "abc123" }}Authentication required or invalid bearer credentials
object
object
Error code
Error message
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.
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.
object
Unique request ID for debugging
Example
{ "error": { "code": "UNAUTHORIZED", "message": "Invalid API key" }, "meta": { "requestId": "abc123" }}Resource not found
object
object
Error code
Error message
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.
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.
object
Unique request ID for debugging
Example
{ "error": { "code": "NOT_FOUND", "message": "Account not found" }, "meta": { "requestId": "abc123" }}The Pin changed status mid-edit
Rate limit exceeded
object
object
Error code
Error message
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.
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.
object
Unique request ID for debugging
Example
{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Daily rate limit of 10000 requests for this organization exceeded. Resets at midnight UTC." }, "meta": { "requestId": "abc123" }}Headers
Section titled “Headers”Seconds until the daily limit resets at midnight UTC.
