Generate Pin copy
const url = 'https://api-v1.tailwind.ai/v1/copy-generations';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"contentType":"lifestyle_content","topic":"example","keywords":["example"],"cta":"example","priorOutputs":[{"title":"example","description":"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/copy-generations \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "contentType": "lifestyle_content", "topic": "example", "keywords": [ "example" ], "cta": "example", "priorOutputs": [ { "title": "example", "description": "example" } ] }'Generate Pinterest Pin titles and descriptions with Tailwind’s Ghostwriter, using the organization’s saved brand context so the copy matches how this account already writes, and saving the result to the account’s Ghostwriter history. Asynchronous: the response returns a job id to poll with GET /v1/copy-generations/{jobId}. Each generation spends plan credits and is charged when the request is accepted; on legacy (non-credit) plans an exhausted AI-credit balance is instead rejected synchronously as a 400. Org-scoped — no accountId is needed. This endpoint generates Pinterest Pin copy only; Tailwind’s other Ghostwriter generators are not exposed here.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
The angle the copy should take.
What the Pin is about — a product, post, or idea in the user’s words.
Keywords to work into the copy.
Call to action to end each Pin with.
Copy you already have, so this generation varies from it rather than repeating it.
object
Responses
Section titled “Responses”Copy generation accepted and processing
object
object
object
Copy generation ID. Poll GET /v1/copy-generations/{jobId} with it.
Credits this generation costs, charged when the request is accepted. 0 when the org’s free trial allowance covered it instead of a credit.
object
Unique request ID for debugging
Example
{ "data": { "generation": { "status": "processing" } }}Invalid request
object
object
Error code
Error message
Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.
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 denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.
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" }}Billing denied — scheduling requires an available credit or trial allowance on the account, or would exceed the plan’s post limit for the billing period
object
object
Error code
Error message
Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.
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": "PAYMENT_REQUIRED", "message": "Not enough credits to schedule this post.", "reason": "insufficient_credits" }, "meta": { "requestId": "abc123" }}No Pinterest account exists to gate Ghostwriter against for this modular-billing org — connect one before generating.
Rate limit exceeded
object
object
Error code
Error message
Machine-readable denial reason. Present on PAYMENT_REQUIRED errors: insufficient_credits, trial_exhausted, no_access, account_not_connected, legacy_post_limit_exceeded.
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 5000 requests exceeded. Resets at midnight UTC." }, "meta": { "requestId": "abc123" }}