{"openapi":"3.1.0","info":{"title":"Postline API","version":"1.0.0","description":"Postline's public API: articles, social posts, images, comments and the plan of your projects, the same operations Postline's MCP server gives an agent. Every list takes `limit` and `cursor` and answers `{ data, nextCursor }`; every error is `{ error: { code, message, param?, requestId } }`, the request id also in the `x-request-id` header. Fields are camelCase."},"servers":[{"url":"https://app.postline.com.br"}],"tags":[{"name":"projects","x-displayName":"Projects"},{"name":"articles","x-displayName":"Articles"},{"name":"comments","x-displayName":"Comments"},{"name":"posts","x-displayName":"Posts"},{"name":"images","x-displayName":"Images"},{"name":"planning","x-displayName":"Planning"},{"name":"webhooks","x-displayName":"Webhooks"}],"components":{"securitySchemes":{"apiToken":{"type":"http","scheme":"bearer","description":"API token (`pl_live_…`) from Organization › API keys, with its scopes, limited to 60 calls a minute. A project token works in its project; an all-projects token names one with `projectId`."},"readToken":{"type":"http","scheme":"bearer","description":"The site's read token (`pl_read_…`), issued by `npx @postline/cli init` and stored as POSTLINE_READ_TOKEN. It reads only its project's published articles. Server side only."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"param":{"type":"string"},"requestId":{"type":"string"}},"required":["code","message","requestId"]}},"required":["error"]},"Block":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"heading"},"level":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]},"text":{"type":"string"}},"required":["type","level","text"]},{"type":"object","properties":{"type":{"type":"string","const":"paragraph"},"text":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"list"},"ordered":{"type":"boolean"},"items":{"type":"array","items":{"type":"string"}}},"required":["type","ordered","items"]},{"type":"object","properties":{"type":{"type":"string","const":"quote"},"text":{"type":"string"},"author":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"image"},"src":{"type":"string","format":"uri"},"alt":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"}},"required":["type","src","alt","width","height"]}]},"PublishedArticle":{"type":"object","properties":{"id":{"type":"string"},"revision":{"type":"integer"},"locale":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"seo":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}},"publishedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","revision","locale","slug","title","summary","seo","publishedAt","updatedAt"]}}},"paths":{"/api/v1/projects":{"get":{"operationId":"listProjects","tags":["projects"],"summary":"List projects","description":"The projects the token reaches.\n\nScope: `projects:read`.","security":[{"apiToken":[]}],"x-scope":"projects:read","x-mcp-tool":"list_projects","parameters":[{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"id":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","name":"Acme Analytics","siteUrl":"https://acme.com"}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/projects/{id}/brand":{"get":{"operationId":"getBrand","tags":["projects"],"summary":"Get a project's brand","description":"The published brand an agent writes with: business, audience, voice, terms, pillars, calls to action, glossary, competitors, languages and the best articles.\n\nScope: `projects:read`.","security":[{"apiToken":[]}],"x-scope":"projects:read","x-mcp-tool":"get_brand","parameters":[{"name":"id","in":"path","required":true,"description":"The project's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"brandVersion":4,"project":{"name":"Acme Analytics","siteUrl":"https://acme.com","language":"en","urlPattern":"/blog/{slug}"},"voice":{"tones":["direct","practical"],"formality":"neutral"},"bestArticles":[{"title":"How to cut churn in the first 30 days","url":"https://acme.com/blog/cut-churn-first-30-days","clicks90d":412}]}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles":{"get":{"operationId":"listArticles","tags":["articles"],"summary":"List articles","description":"A project's articles, most recently updated first, with their status: draft, generating, in_review, approved, scheduled or published. With the site's read token (`pl_read_…`) it answers only the project's published articles, with `locale` required, as the published shape.\n\nScope: `articles:read`.","security":[{"apiToken":[]},{"readToken":[]}],"x-scope":"articles:read","x-mcp-tool":"list_articles","parameters":[{"name":"projectId","in":"query","required":false,"description":"The project, from list_projects. A project API token fills it in.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","generating","in_review","approved","scheduled","published"]}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}},{"name":"locale","in":"query","required":false,"description":"Read token only: the language, such as `pt-BR` or `en`.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"examples":{"apiToken":{"value":{"data":[{"id":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","title":"How to cut churn in the first 30 days","status":"in_review","slug":"cut-churn-first-30-days","locale":"en","scheduledAt":null,"publishedAt":null,"updatedAt":"2026-10-15T09:41:00.000Z"}],"nextCursor":"NTA"}},"readToken":{"value":{"data":[{"id":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","title":"How to cut churn in the first 30 days","summary":"Most churn happens before the second invoice. Here is what to fix first.","seo":{"title":"Cut churn in the first 30 days","description":"A checklist for onboarding that keeps customers."},"publishedAt":"2026-10-14T12:00:00.000Z","updatedAt":"2026-10-15T09:41:00.000Z"}],"nextCursor":null}}}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"post":{"operationId":"createArticle","tags":["articles"],"summary":"Create an article","description":"Creates an article from Markdown, free. With `topicId` it fills that planned topic and takes its date. It goes to review unless `submit` is false; the project decides whether work from the API needs review. Never published by this.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"create_article","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","minLength":1,"maxLength":64,"description":"The project, from list_projects. A project API token fills it in."},"markdown":{"type":"string","maxLength":200000,"description":"The body: ## and ### headings, paragraphs, - or 1. lists, > quotes (a last line '— Name' is the author), **bold**, `code`, [links](https://…), and images as ![alt](image:<id>) from upload_image. A first # line is the title. Code blocks and HTML are dropped."},"title":{"type":"string","minLength":1,"maxLength":200},"slug":{"description":"lowercase-words-with-hyphens","type":"string","maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"summary":{"type":"string","maxLength":1000},"seoTitle":{"type":"string","maxLength":200},"seoDescription":{"type":"string","maxLength":500},"topicId":{"description":"From list_topics.","type":"string","minLength":1,"maxLength":64},"submit":{"default":true,"type":"boolean"}},"required":["markdown"]},"example":{"title":"How to cut churn in the first 30 days","markdown":"## Why the first month matters\n\nMost churn happens before the second invoice.","submit":false}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":1,"submitted":true,"droppedImages":[]}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles/{id}":{"get":{"operationId":"getArticle","tags":["articles"],"summary":"Get an article","description":"One article in full: Markdown body, revision, SEO fields, status, cover, open comments, the automatic checks' findings and the posts made from it. With the site's read token (`pl_read_…`) it answers only the project's published articles, with `locale` required, as the published shape.\n\nScope: `articles:read`.","security":[{"apiToken":[]},{"readToken":[]}],"x-scope":"articles:read","x-mcp-tool":"get_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}},{"name":"locale","in":"query","required":false,"description":"Read token only: the language, such as `pt-BR` or `en`.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"examples":{"apiToken":{"value":{"id":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","title":"How to cut churn in the first 30 days","status":"in_review","slug":"cut-churn-first-30-days","locale":"en","scheduledAt":null,"publishedAt":null,"updatedAt":"2026-10-15T09:41:00.000Z","revision":3,"url":"https://acme.com/blog/cut-churn-first-30-days","summary":"Most churn happens before the second invoice. Here is what to fix first.","seoTitle":"Cut churn in the first 30 days","seoDescription":"A checklist for onboarding that keeps customers.","cover":{"imageId":"a41d7c9e-2b58-4f03-8e6a-5c1f9d2b7e30","alt":"Retention chart","url":null},"markdown":"## Why the first month matters\n\nMost churn happens before the second invoice.","comments":[],"checkFindings":[],"checking":false,"factsSkipped":false,"posts":[{"id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","format":"linkedin","status":"in_review"}]}},"readToken":{"value":{"id":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","title":"How to cut churn in the first 30 days","summary":"Most churn happens before the second invoice. Here is what to fix first.","seo":{"title":"Cut churn in the first 30 days","description":"A checklist for onboarding that keeps customers."},"publishedAt":"2026-10-14T12:00:00.000Z","updatedAt":"2026-10-15T09:41:00.000Z","blocks":[{"type":"heading","level":2,"text":"Why the first month matters"},{"type":"paragraph","text":"Most churn happens before the second invoice."}]}}}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"patch":{"operationId":"updateArticle","tags":["articles"],"summary":"Update an article","description":"Saves a new revision over the one you read (`revision`); what you leave out stays. `coverImageId` sets the cover. An approved or scheduled article goes back to draft; one in review changes only for who may approve it.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"update_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":1,"description":"The revision get_article returned; a newer one is a conflict."},"markdown":{"type":"string","maxLength":200000,"description":"The body: ## and ### headings, paragraphs, - or 1. lists, > quotes (a last line '— Name' is the author), **bold**, `code`, [links](https://…), and images as ![alt](image:<id>) from upload_image. A first # line is the title. Code blocks and HTML are dropped."},"title":{"type":"string","minLength":1,"maxLength":200},"slug":{"description":"lowercase-words-with-hyphens","type":"string","maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"summary":{"type":"string","maxLength":1000},"seoTitle":{"type":"string","maxLength":200},"seoDescription":{"type":"string","maxLength":500},"coverImageId":{"description":"From upload_image.","type":"string","minLength":1,"maxLength":64}},"required":[]},"example":{"revision":3,"seoTitle":"Cut churn in 30 days"}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"revision":4,"status":"draft","slug":"cut-churn-first-30-days","droppedImages":[]}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"delete":{"operationId":"deleteArticle","tags":["articles"],"summary":"Delete an article","description":"Deletes an article for good, never one a site shows or is delivering.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"delete_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"deleted":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles/{id}/submit":{"post":{"operationId":"submitArticle","tags":["articles"],"summary":"Send an article to review","description":"Sends a draft's latest revision to review; the project's reviewers are told.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"submit_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"submitted":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles/{id}/approve":{"post":{"operationId":"approveArticle","tags":["articles"],"summary":"Approve an article","description":"Approves the revision in review, for reviewers, admins and owners. May start the project's routine posts, which charge credits as in the app.\n\nScope: `articles:approve`.","security":[{"apiToken":[]}],"x-scope":"articles:approve","x-mcp-tool":"approve_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":1,"description":"The revision get_article returned; a newer one is a conflict."}},"required":["revision"]},"example":{"revision":3}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"approved":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles/{id}/schedule":{"post":{"operationId":"scheduleArticle","tags":["articles"],"summary":"Schedule an article","description":"Schedules an approved article on a day and time in the project's time zone.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"schedule_article","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"day":{"type":"string","format":"date","description":"YYYY-MM-DD"},"time":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"HH:MM"}},"required":["day","time"]},"example":{"day":"2026-10-20","time":"09:00"}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"scheduled":"2026-10-20T09:00"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/articles/{id}/comments":{"get":{"operationId":"listComments","tags":["comments"],"summary":"List an article's comments","description":"The article's open review comments, oldest first, each with its replies.\n\nScope: `comments:read`.","security":[{"apiToken":[]}],"x-scope":"comments:read","x-mcp-tool":"list_comments","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"id":"c1","quote":"before the second invoice","body":"Add the source of this number.","author":"Marina Souza","createdAt":"2026-10-15T09:41:00.000Z","replies":[]}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"post":{"operationId":"createComment","tags":["comments"],"summary":"Comment on an article","description":"Adds a comment, or a reply to an open one with `parentId`. @mentions notify people.\n\nScope: `comments:write`.","security":[{"apiToken":[]}],"x-scope":"comments:write","x-mcp-tool":"create_comment","parameters":[{"name":"id","in":"path","required":true,"description":"The article's id (or, with the read token, its slug).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":4000},"parentId":{"description":"The comment this replies to.","type":"string","minLength":1,"maxLength":64},"quote":{"type":"string","maxLength":500}},"required":["body"]},"example":{"body":"Added the source.","parentId":"c1"}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"c2"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/comments/{id}/resolve":{"post":{"operationId":"resolveComment","tags":["comments"],"summary":"Resolve a comment","description":"Marks a comment resolved once it is addressed.\n\nScope: `comments:write`.","security":[{"apiToken":[]}],"x-scope":"comments:write","x-mcp-tool":"resolve_comment","parameters":[{"name":"id","in":"path","required":true,"description":"The comment's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"resolved":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts":{"get":{"operationId":"listPosts","tags":["posts"],"summary":"List posts","description":"A project's social posts (`linkedin`, `x`, `carousel`), newest first, with the article each comes from and each destination's status and date.\n\nScope: `posts:read`.","security":[{"apiToken":[]}],"x-scope":"posts:read","x-mcp-tool":"list_posts","parameters":[{"name":"projectId","in":"query","required":false,"description":"The project, from list_projects. A project API token fills it in.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["linkedin","carousel","x"]}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","format":"linkedin","status":"in_review","title":"Most churn happens before the second invoice.","articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","agent":"n8n","destinations":[{"destination":"linkedin","status":"pending","at":"2026-10-20T09:00","publishedAt":null,"url":null}]}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"post":{"operationId":"createPost","tags":["posts"],"summary":"Create a post","description":"Creates a post you wrote, free: `text` for LinkedIn, `parts` for X (checked with X's own count), `slides`, `caption` and `destinations` (instagram, linkedin, tiktok) for a carousel. In a project or from an article (`articleId`).\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"create_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["linkedin","carousel","x"]},"projectId":{"type":"string","minLength":1,"maxLength":64,"description":"The project, from list_projects. A project API token fills it in."},"articleId":{"description":"The article it comes from.","type":"string","minLength":1,"maxLength":64},"text":{"type":"string","minLength":1,"maxLength":3000,"description":"LinkedIn: the post; its first line is the headline."},"parts":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":1000},"description":"X: one part is a post, more a thread. Each fits X's 280 weighted characters (a link counts 23, an emoji 2); a link goes only in the last part."},"slides":{"minItems":3,"maxItems":10,"type":"array","items":{"type":"object","properties":{"kicker":{"type":"string","maxLength":24},"title":{"type":"string","minLength":1,"maxLength":56},"body":{"type":"string","maxLength":180},"image":{"description":"A media library image (generate_post_images).","type":"string","minLength":1,"maxLength":64}},"required":["title","body"]},"description":"Carousel: in order, the cover, the slides, the closing."},"caption":{"description":"Carousel.","type":"string","maxLength":2200},"hashtags":{"maxItems":30,"type":"array","items":{"type":"string","minLength":2,"maxLength":40}},"destinations":{"description":"Carousel: where it goes; all three by default.","minItems":1,"maxItems":3,"type":"array","items":{"type":"string","enum":["instagram","linkedin","tiktok"]}}},"required":["format"]},"example":{"format":"linkedin","articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","text":"Most churn happens before the second invoice.\n\nHere is what to fix first.","hashtags":["saas","churn"]}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","revision":1,"status":"in_review"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts/generate":{"post":{"operationId":"generatePost","tags":["posts"],"summary":"Generate a post","description":"Has Postline's model write a post from one of `topic`, `link`, `script` or `articleId`. Charges credits as in the app: LinkedIn 1 (2 with an image), X 1, carousel 2 (6 with images). The post is `generating`, ready in about a minute.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"generate_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["linkedin","carousel","x"]},"projectId":{"type":"string","minLength":1,"maxLength":64,"description":"The project, from list_projects. A project API token fills it in."},"topic":{"type":"string","minLength":3,"maxLength":500},"link":{"description":"A public page to write from.","type":"string","maxLength":2000,"format":"uri"},"script":{"description":"A ready outline.","type":"string","minLength":1,"maxLength":20000},"articleId":{"description":"An article to write from.","type":"string","minLength":1,"maxLength":64},"objective":{"default":"educate","type":"string","enum":["leads","authority","educate","launch","retain","save","engage","hire","sell"]},"tone":{"default":"consultative","type":"string","enum":["consultative","direct","didactic","casual"]},"size":{"description":"LinkedIn: characters, 600, 1300 (default) or 2500. X: parts, 1, 4 (default) or 8. Carousel: slides, 5, 7 (default) or 10.","type":"integer"},"images":{"default":"none","description":"LinkedIn and carousel.","type":"string","enum":["illustration","photo","none"]},"ratio":{"description":"Carousel.","type":"string","enum":["4:5","1:1"]},"destinations":{"description":"Carousel: where it goes; all three by default.","minItems":1,"maxItems":3,"type":"array","items":{"type":"string","enum":["instagram","linkedin","tiktok"]}}},"required":["format"]},"example":{"format":"carousel","articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","images":"none"}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","status":"generating"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"402":{"description":"The workspace has no credits for this (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"The workspace has no credits for this (`insufficient_credits`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts/{id}":{"get":{"operationId":"getPost","tags":["posts"],"summary":"Get a post","description":"One post in full: content (a carousel's slides as kicker, title, body), revision, status, article and destinations.\n\nScope: `posts:read`.","security":[{"apiToken":[]}],"x-scope":"posts:read","x-mcp-tool":"get_post","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","format":"linkedin","status":"in_review","title":"Most churn happens before the second invoice.","articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","agent":"n8n","destinations":[{"destination":"linkedin","status":"pending","at":"2026-10-20T09:00","publishedAt":null,"url":null}],"revision":1,"content":{"kind":"linkedin","text":"Most churn happens before the second invoice.\n\nHere is what to fix first.","hashtags":["saas","churn"],"headline":"Most churn happens before the second invoice."}}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"patch":{"operationId":"updatePost","tags":["posts"],"summary":"Update a post","description":"Saves a new revision over the one you read; what you leave out stays. An approved or scheduled post goes back to review.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"update_post","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0,"description":"The revision get_post returned; a newer one is a conflict."},"text":{"type":"string","minLength":1,"maxLength":3000,"description":"LinkedIn: the post; its first line is the headline."},"hashtags":{"maxItems":30,"type":"array","items":{"type":"string","minLength":2,"maxLength":40}},"parts":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":1000},"description":"X: one part is a post, more a thread. Each fits X's 280 weighted characters (a link counts 23, an emoji 2); a link goes only in the last part."},"slides":{"minItems":3,"maxItems":10,"type":"array","items":{"type":"object","properties":{"kicker":{"type":"string","maxLength":24},"title":{"type":"string","minLength":1,"maxLength":56},"body":{"type":"string","maxLength":180},"image":{"description":"A media library image (generate_post_images).","type":"string","minLength":1,"maxLength":64}},"required":["title","body"]},"description":"Carousel: in order, the cover, the slides, the closing."},"caption":{"description":"Carousel.","type":"string","maxLength":2200}},"required":["revision"]},"example":{"revision":1,"text":"Churn starts in week one."}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"revision":2,"status":"in_review"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"delete":{"operationId":"deletePost","tags":["posts"],"summary":"Delete a post","description":"Deletes a post for good, while nothing of it was published.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"delete_post","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"deleted":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts/{id}/destinations/{destination}/schedule":{"post":{"operationId":"schedulePost","tags":["posts"],"summary":"Schedule a post's destination","description":"Dates one destination of a post on a day and time in the project's time zone; review follows the project's choice.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"schedule_post","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}},{"name":"destination","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"day":{"type":"string","format":"date","description":"YYYY-MM-DD"},"time":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"HH:MM"}},"required":["day","time"]},"example":{"day":"2026-10-20","time":"09:00"}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"scheduled":"2026-10-20T09:00","status":"scheduled"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts/{id}/render":{"post":{"operationId":"renderPost","tags":["posts"],"summary":"Render a carousel","description":"Draws a carousel's file for a destination on Postline's worker. The first call returns an `exportId`; call again with it until `status` is `ready`, which brings a download URL valid for an hour.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"render_post","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"destination":{"type":"string","enum":["instagram","linkedin","tiktok"]},"exportId":{"description":"From the first call.","type":"string","minLength":1,"maxLength":64}},"required":["destination"]},"example":{"destination":"linkedin"}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"exportId":"e1","status":"pending","progress":0}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/posts/{id}/images":{"post":{"operationId":"generatePostImages","tags":["posts"],"summary":"Generate a carousel's images","description":"Has Postline's image model draw up to 4 variations for a slide, kept in the media library; 1 credit per image drawn.\n\nScope: `posts:write`.","security":[{"apiToken":[]}],"x-scope":"posts:write","x-mcp-tool":"generate_post_images","parameters":[{"name":"id","in":"path","required":true,"description":"The post's id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":3,"maxLength":1000},"size":{"default":"4:5","type":"string","enum":["4:5","1:1","9:16"]}},"required":["prompt"]},"example":{"prompt":"A team looking at a retention dashboard"}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"imageIds":["a41d7c9e-2b58-4f03-8e6a-5c1f9d2b7e30"]}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"402":{"description":"The workspace has no credits for this (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"The workspace has no credits for this (`insufficient_credits`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/images":{"post":{"operationId":"uploadImage","tags":["images"],"summary":"Upload an image","description":"Adds a JPG, PNG or WebP (up to 20 MB) to the project's media library, from `base64`, a public https `url`, or a multipart `file`. Returns the Markdown that places it in an article.\n\nScope: `images:write`.","security":[{"apiToken":[]}],"x-scope":"images:write","x-mcp-tool":"upload_image","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","minLength":1,"maxLength":64,"description":"The project, from list_projects. A project API token fills it in."},"base64":{"type":"string","maxLength":28000000},"url":{"type":"string","maxLength":2000,"format":"uri"},"fileName":{"type":"string","maxLength":200},"alt":{"description":"Describe the image for readers.","type":"string","maxLength":300},"license":{"default":"own","description":"own: the person's; licensed: needs credit; public: public domain.","type":"string","enum":["own","licensed","public"]},"credit":{"type":"string","maxLength":200}},"required":[]},"example":{"url":"https://acme.com/images/retention.png","alt":"Retention chart"}}}},"responses":{"201":{"description":"Created","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"id":"a41d7c9e-2b58-4f03-8e6a-5c1f9d2b7e30","width":1600,"height":900,"markdown":"![Retention chart](image:a41d7c9e-2b58-4f03-8e6a-5c1f9d2b7e30)"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/images/{id}":{"delete":{"operationId":"deleteImage","tags":["images"],"summary":"Delete an image","description":"Deletes an image from the media library; an article that had it as cover is left without one.\n\nScope: `images:write`.","security":[{"apiToken":[]}],"x-scope":"images:write","x-mcp-tool":"delete_image","parameters":[{"name":"id","in":"path","required":true,"description":"The image's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"deleted":true}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}},"get":{"operationId":"getImage","tags":["images"],"summary":"Get a published image","description":"An image of a published article, at the address the read API hands out. Public, cached for a day.","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"The image's id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The image bytes.","content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`)."}}}},"/api/v1/topics":{"get":{"operationId":"listTopics","tags":["planning"],"summary":"List planned topics","description":"The plan's topics waiting to be written, soonest first. Write one with Create an article and its `topicId`.\n\nScope: `calendar:read`.","security":[{"apiToken":[]}],"x-scope":"calendar:read","x-mcp-tool":"list_topics","parameters":[{"name":"projectId","in":"query","required":false,"description":"The project, from list_projects. A project API token fills it in.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"id":"t1","title":"Onboarding emails that cut churn","keyword":"onboarding emails","locale":"en","date":"2026-10-15T09:41:00.000Z","pillar":"Retention","cluster":"Onboarding","intent":"informational","callToAction":"Start a trial","avoid":null}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/topics/suggest":{"post":{"operationId":"suggestTopics","tags":["planning"],"summary":"Suggest topics","description":"Suggests topics to the project's strategy; a person decides which to plan.\n\nScope: `articles:write`.","security":[{"apiToken":[]}],"x-scope":"articles:write","x-mcp-tool":"suggest_topics","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","minLength":1,"maxLength":64,"description":"The project, from list_projects. A project API token fills it in."},"titles":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":160}}},"required":["titles"]},"example":{"titles":["Onboarding emails that cut churn","Churn benchmarks for SaaS"]}}}},"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{"suggested":2}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"409":{"description":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_state","message":"Not in a state for this (`invalid_state`, `locked`, `not_deletable`), or a newer revision was saved (`conflict`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/calendar":{"get":{"operationId":"getCalendar","tags":["planning"],"summary":"Get the calendar","description":"What is dated in the next 60 days, soonest first: planned topics, scheduled articles and each post destination (`type`: topic, article, post).\n\nScope: `calendar:read`.","security":[{"apiToken":[]}],"x-scope":"calendar:read","x-mcp-tool":"get_calendar","parameters":[{"name":"projectId","in":"query","required":false,"description":"The project, from list_projects. A project API token fills it in.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"type":"post","id":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","format":"linkedin","status":"scheduled","title":"Most churn happens before the second invoice.","destination":"linkedin","at":"2026-10-20T09:00"}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/api/v1/results":{"get":{"operationId":"getResults","tags":["planning"],"summary":"Get search results","description":"The last 28 days in Search Console by page, most clicked first.\n\nScope: `results:read`.","security":[{"apiToken":[]}],"x-scope":"results:read","x-mcp-tool":"get_results","parameters":[{"name":"projectId","in":"query","required":false,"description":"The project, from list_projects. A project API token fills it in.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"x-request-id":{"description":"requestId","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":["string","null"]}},"required":["data","nextCursor"]},"example":{"data":[{"page":"https://acme.com/blog/cut-churn-first-30-days","clicks":412,"impressions":9810}],"nextCursor":"NTA"}}}},"400":{"description":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_input","message":"Invalid input (`invalid_input`, with `param`), or a refusal of the input such as `invalid_url` or `invalid_image`.","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"401":{"description":"Missing, unknown, expired or revoked token (`invalid_token`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_token","message":"Missing, unknown, expired or revoked token (`invalid_token`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_scope","message":"The token lacks the scope (`insufficient_scope`), its creator's role may not (`not_allowed`), or the project is not the token's (`project_not_allowed`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"404":{"description":"Not found among the projects the token reaches (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"not_found","message":"Not found among the projects the token reaches (`not_found`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"More than 60 calls in a minute with this token (`rate_limited`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"More than 60 calls in a minute with this token (`rate_limited`).","requestId":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}}},"webhooks":{"article.published":{"post":{"operationId":"articlePublished","tags":["webhooks"],"summary":"article.published","description":"An article went live on the project's main destination.\n\nFires once the site confirms the article's revision is live: once per revision. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.published","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"publicationId":{"type":"string","description":"The delivery to the site this event comes from."}},"required":["articleId","revision","slug","publicationId"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.published","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"slug":"cut-churn-first-30-days","publicationId":"pub_1"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"article.review_requested":{"post":{"operationId":"articleReviewRequested","tags":["webhooks"],"summary":"article.review_requested","description":"An article is ready for review.\n\nFires when a draft's revision is sent to review, by a person or through the API: once per revision. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.review_requested","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."}},"required":["articleId","revision"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.review_requested","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"article.scheduled":{"post":{"operationId":"articleScheduled","tags":["webhooks"],"summary":"article.scheduled","description":"An article was scheduled, or its date changed.\n\nFires each time an article gets a new publication date. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.scheduled","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"scheduledAt":{"type":"string","format":"date-time","description":"When it goes out, ISO 8601."}},"required":["articleId","scheduledAt"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.scheduled","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","scheduledAt":"2026-10-20T12:00:00.000Z"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"post.scheduled":{"post":{"operationId":"postScheduled","tags":["webhooks"],"summary":"post.scheduled","description":"A social post was scheduled on a network.\n\nFires when a destination of a post is dated and the post is scheduled (not waiting in review): once per destination and date. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"post.scheduled","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"postId":{"type":"string","description":"The post's id, as the API's `/posts/{id}` takes it."},"format":{"type":"string","enum":["linkedin","x","carousel"],"description":"The post's format."},"destination":{"type":"string","enum":["linkedin","instagram","tiktok","x"],"description":"The network."},"scheduledAt":{"type":"string","format":"date-time","description":"When it goes out, ISO 8601."}},"required":["postId","format","destination","scheduledAt"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"post.scheduled","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"postId":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","format":"linkedin","destination":"linkedin","scheduledAt":"2026-10-20T12:00:00.000Z"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"post.published":{"post":{"operationId":"postPublished","tags":["webhooks"],"summary":"post.published","description":"A social post went out on a network.\n\nFires when Postline publishes a post's destination (X today) or someone marks it published: once per destination. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"post.published","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"postId":{"type":"string","description":"The post's id, as the API's `/posts/{id}` takes it."},"format":{"type":"string","enum":["linkedin","x","carousel"],"description":"The post's format."},"destination":{"type":"string","enum":["linkedin","instagram","tiktok","x"],"description":"The network."},"url":{"type":["string","null"],"description":"The post on the network, when Postline published it."},"publishedAt":{"type":"string","format":"date-time","description":"When it went out, ISO 8601."}},"required":["postId","format","destination","url","publishedAt"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"post.published","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"postId":"3c8e1f20-6a4b-4d7e-9f15-8b2c0d6e4a71","format":"x","destination":"x","url":"https://x.com/acme/status/1846000000000000000","publishedAt":"2026-10-20T12:00:03.000Z"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"delivery.failed":{"post":{"operationId":"deliveryFailed","tags":["webhooks"],"summary":"delivery.failed","description":"A publication didn't go live.\n\nFires when a delivery to the project's site gave up after its retries: once per delivery. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"delivery.failed","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"publicationId":{"type":"string","description":"The delivery to the site this event comes from."}},"required":["articleId","revision","slug","publicationId"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"delivery.failed","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"slug":"cut-churn-first-30-days","publicationId":"pub_1"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"credits.low":{"post":{"operationId":"creditsLow","tags":["webhooks"],"summary":"credits.low","description":"The cycle's credit usage passed a threshold.\n\nFires when a project's plan uses `percent` (80) of the month's credits: once per project and month. Sent once per occurrence: a retry carries the same `id`, so deduplicate by it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"credits.low","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"percent":{"type":"integer","description":"The share of the month's credits used, in percent."},"used":{"type":"number","description":"Credits used this month."},"limit":{"type":"number","description":"The month's credits."},"month":{"type":"string","description":"The month, YYYY-MM."}},"required":["percent","used","limit","month"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"credits.low","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"percent":80,"used":80,"limit":100,"month":"2026-10"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"ping":{"post":{"operationId":"ping","tags":["webhooks"],"summary":"ping","description":"A test event.\n\nSent when someone clicks “Send test event” on an endpoint or a webhook connector, to that one alone. Answer 2xx; nothing to do.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"ping","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"message":{"type":"string","description":"A note saying it is a test."}},"required":["message"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"ping","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":null,"data":{"message":"Postline test event"}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"site.article.published":{"post":{"operationId":"siteArticlePublished","tags":["webhooks"],"summary":"article.published (site)","description":"An article went live: the site shows it.\n\nSent when an article is published for the first time, or published again after it was taken down. It goes to the site's `/api/postline/webhook`, which `@postline/next` verifies and answers. It is sent again until the site answers 2xx; `data.sequence` orders an article's events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.published","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"locale":{"type":"string","description":"The article's language, such as `pt-BR`."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"previousSlug":{"type":["string","null"],"description":"The slug it had before, for `article.slug_changed`; else null."},"sequence":{"type":"integer","description":"The article's event counter: a lower one than the last you applied is an old event."}},"required":["articleId","revision","locale","slug","previousSlug","sequence"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.published","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","previousSlug":null,"sequence":7}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"site.article.updated":{"post":{"operationId":"siteArticleUpdated","tags":["webhooks"],"summary":"article.updated (site)","description":"A published article has a new revision.\n\nSent when a new revision of a live article is approved and goes out. It goes to the site's `/api/postline/webhook`, which `@postline/next` verifies and answers. It is sent again until the site answers 2xx; `data.sequence` orders an article's events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.updated","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"locale":{"type":"string","description":"The article's language, such as `pt-BR`."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"previousSlug":{"type":["string","null"],"description":"The slug it had before, for `article.slug_changed`; else null."},"sequence":{"type":"integer","description":"The article's event counter: a lower one than the last you applied is an old event."}},"required":["articleId","revision","locale","slug","previousSlug","sequence"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.updated","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","previousSlug":null,"sequence":7}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"site.article.unpublished":{"post":{"operationId":"siteArticleUnpublished","tags":["webhooks"],"summary":"article.unpublished (site)","description":"An article was taken off the site.\n\nSent when someone unpublishes an article; its page should answer 404. It goes to the site's `/api/postline/webhook`, which `@postline/next` verifies and answers. It is sent again until the site answers 2xx; `data.sequence` orders an article's events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.unpublished","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"locale":{"type":"string","description":"The article's language, such as `pt-BR`."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"previousSlug":{"type":["string","null"],"description":"The slug it had before, for `article.slug_changed`; else null."},"sequence":{"type":"integer","description":"The article's event counter: a lower one than the last you applied is an old event."}},"required":["articleId","revision","locale","slug","previousSlug","sequence"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.unpublished","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","previousSlug":null,"sequence":7}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"site.article.deleted":{"post":{"operationId":"siteArticleDeleted","tags":["webhooks"],"summary":"article.deleted (site)","description":"An article was deleted.\n\nSent when an article the site had is deleted, and after the connection check's test article. It goes to the site's `/api/postline/webhook`, which `@postline/next` verifies and answers. It is sent again until the site answers 2xx; `data.sequence` orders an article's events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.deleted","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"locale":{"type":"string","description":"The article's language, such as `pt-BR`."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"previousSlug":{"type":["string","null"],"description":"The slug it had before, for `article.slug_changed`; else null."},"sequence":{"type":"integer","description":"The article's event counter: a lower one than the last you applied is an old event."}},"required":["articleId","revision","locale","slug","previousSlug","sequence"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.deleted","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","previousSlug":null,"sequence":7}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}},"site.article.slug_changed":{"post":{"operationId":"siteArticleSlugChanged","tags":["webhooks"],"summary":"article.slug_changed (site)","description":"A published article moved to a new slug.\n\nSent when a live article's slug changes; `previousSlug` is the old address, to redirect. It goes to the site's `/api/postline/webhook`, which `@postline/next` verifies and answers. It is sent again until the site answers 2xx; `data.sequence` orders an article's events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The event's id, `evt_…`, the same in every retry and in the `webhook-id` header: deduplicate by it."},"type":{"type":"string","const":"article.slug_changed","description":"The event's name."},"version":{"type":"integer","const":1,"description":"The envelope's version."},"timestamp":{"type":"string","format":"date-time","description":"When the event happened, ISO 8601."},"organizationId":{"type":"string","description":"The workspace."},"projectId":{"type":["string","null"],"description":"The project, or null for a workspace-wide event."},"data":{"type":"object","description":"What the event is about.","properties":{"articleId":{"type":"string","description":"The article's id, as the API's `/articles/{id}` takes it."},"revision":{"type":"integer","description":"The article's revision the event is about."},"locale":{"type":"string","description":"The article's language, such as `pt-BR`."},"slug":{"type":"string","description":"The article's slug, its address on the site."},"previousSlug":{"type":["string","null"],"description":"The slug it had before, for `article.slug_changed`; else null."},"sequence":{"type":"integer","description":"The article's event counter: a lower one than the last you applied is an old event."}},"required":["articleId","revision","locale","slug","previousSlug","sequence"],"additionalProperties":false}},"required":["id","type","version","timestamp","organizationId","projectId","data"],"additionalProperties":false},"example":{"id":"evt_5f2b9c1e8a7d4630b1e9c2f0a4d8e7b3","type":"article.slug_changed","version":1,"timestamp":"2026-10-17T12:00:00.000Z","organizationId":"org_8c1d2e","projectId":"7f3a91c2-48e6-4b0d-a5c1-2e9d6b8f0a14","data":{"articleId":"0b9c4e7a-5d1f-4c2e-9a8b-3f6e2d1c7b90","revision":3,"locale":"en","slug":"cut-churn-first-30-days","previousSlug":"cut-churn","sequence":7}}}}},"responses":{"2XX":{"description":"Any 2xx answer acknowledges the event."}}}}}}