{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Posttar API","version":"1.0.0","description":"The Posttar API lets a customer automate their OWN account: create and edit content, schedule and publish, run the autopilot, and read reports. It does not let a third-party tool serve many Posttar customers; there is no OAuth or app identity here, only a per-workspace API key.\n\nThis document is generated from the same registry that serves the requests: it cannot describe an endpoint that does not exist, and it describes every one that does.\n\nAuthenticate with `Authorization: Bearer ptr_live_...`. Every error, from any endpoint, has the shape `{ \"error\": { \"code\": string, \"message\": string } }`; `code` is the stable contract, `message` is a human message and may change wording between releases.\n\nFour endpoints answer immediately with 202 instead of waiting for the result (creating a post, a reel, an audiogram, and publishing): they return the resource in its working state, and the caller polls the matching GET for the outcome.\n\nAn API key only works for a workspace that already has API access, available on the Plus and Scale plans."},"servers":[{"url":"https://api.posttar.com/v1","description":"The API host. Only /v1 is served here; every other path on this host answers 404 with the same error envelope as the API itself, and never HTML."},{"url":"https://app.posttar.com/api/v1","description":"The same endpoints on the app's own domain. This is the internal name of the same route, not a mirror: either base URL works, and the first one is the one to prefer."}],"security":[{"apiKey":[]}],"tags":[{"name":"posts"},{"name":"slides"},{"name":"reels"},{"name":"audiograms"},{"name":"autopilot"},{"name":"projects"},{"name":"brand-dna"},{"name":"radar"},{"name":"reports"},{"name":"team"}],"paths":{"/posts":{"get":{"operationId":"getPosts","summary":"List posts","description":"Lists the workspace's posts: status, scheduled date, and the first words of the caption. Use it to find which post to act on next, since every other post endpoint needs its id. Filter by status, period, or project to narrow the search; without filters, returns the most recent.","tags":["posts"],"parameters":[{"name":"status","in":"query","required":false,"description":"Comma-separated list of statuses to filter by.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"ISO date. Filters by scheduled date.","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"ISO date. Filters by scheduled date.","schema":{"type":"string"}},{"name":"projectId","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Default 25, max 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response's `next` field.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"posts":[{"id":"8c64bee5-f756-47b7-a64a-01f5db597202","status":"draft","scheduledFor":null,"textContent":"Seu nicho pode estar amplo demais sem você perceber. Quando a mensagem tenta alcançar todo mundo, ela deixa de ser memorável para qualquer pessoa.\nQual desses sinais aparece mai...","projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","contentFormat":"animated_audio","theme":"Tres sinais de que o seu nicho esta amplo demais"},{"id":"a6eed866-eed5-4f60-b3a5-1aaba4bee2eb","status":"draft","scheduledFor":null,"textContent":"Your first SaaS customers probably aren’t waiting for an ad. They’re already dealing with a painful problem you can solve.\n\nStart with direct conversations and a simple offer. W...","projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","contentFormat":"animated_audio","theme":"How to land your first 10 SaaS customers without spending on ads"}],"next":"eyJjaGF2ZSI6IjIwMjYtMDktMTNUMDU6NTg6MzYuNDUyNTI4KzAwOjAwIiwiaWQiOiJhNmVlZDg2Ni1lZWQ1LTRmNjAtYjNhNS0xYWFiYTRiZWUyZWIifQ"}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"postPosts","summary":"Create a post, in any of the six formats","description":"Creates a post from a theme and starts generating it. The `format` parameter picks which of the six formats to make, and defaults to `carrossel`. Every format costs 1 credit and takes on the order of a minute (the carousel: median 43s, p99 87s, measured in production). Fire-and-forget: responds 202 with `state: \"generating\"`; poll `GET /posts/{id}` for the outcome. The four formats in preview are refused with 403 unless the workspace has them enabled, and nothing is charged.","tags":["posts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string"},"theme":{"description":"What the post is about, in the client's words.","type":"string"},"format":{"description":"Which format to generate. Defaults to `carrossel`. Formats in preview (`audio_animado`, `narrated_photos`, `carrossel_profissional`, `infografico`) are refused with 403 unless the workspace has them enabled.","type":"string","enum":["carousel","caption_reel","animated_audio","narrated_photos","premium_carousel","infographic"]},"link":{"description":"A URL to read before writing. When present, `theme` becomes the instruction for what to do with it. Only the `carrossel` format reads a link; any other format is refused.","type":"string"}},"required":["projectId"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted. The resource is returned in its working state (for example `creating` or `publishing`); this call does not wait for the result. Poll the matching GET endpoint for the outcome.","content":{"application/json":{"schema":{}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}":{"get":{"operationId":"getPostsId","summary":"Get a post, whatever its format","description":"Returns one post in full, in any of the six formats. The envelope is always the same, `format` says which format it is, and `content` carries what belongs to that format: `slides` for the three carousel-shaped formats, the text blocks and look for `caption_reel`, the script and scenes for the two narrated ones. `content` is null while the post is still generating, which is a real state and not an error: read `status` to know.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"id":"e7869afa-d470-4e9b-a4c9-4c1936604a4b","format":"carousel","status":"draft","projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","workspaceId":"2bd5c04d-1dd4-456e-8704-9d7b84703fd0","scheduledFor":null,"textContent":null,"mediaUrls":[{"url":"https://.../post-images/ai-edits/e7869afa-d470-4e9b-a4c9-4c1936604a4b/b14c1fbe-b6f0-4ae0-bfd0-b1aaaf67a52b.webp","type":"image"}],"content":{"slides":[{"id":"1663f551-6958-41f6-bedb-e4294a9ff9a9","order":0,"variant":null,"fields":[{"name":"profissional","value":{"blocos":[{"peso":"etiqueta","texto":"04 · USO"},{"peso":"forte","texto":"Metricaas: mede se a galera realmente usa"}],"destaque":""}}],"titleFont":null,"bodyFont":null,"colors":{"background":"#fff1e2","text":"#1D2939","brand":"#ff6e05"}}]}}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"patchPostsId","summary":"Update a post, whatever its format","description":"Changes the caption and, on the formats that have one, the content inside the video: `reel` on `caption_reel`, `narration` on `animated_audio` and `narrated_photos`. Send only what changes; the caption is replaced in full and never merged. Sending `reel` on a post that is not a reel (or `narration` on one that is not narrated) is refused with the field name, never ignored. Only works before the post publishes.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"caption":{"description":"The Instagram caption, replaced in full. Up to 2200 characters, the same ceiling Instagram has.","type":"string","maxLength":2200},"reel":{"description":"Only on the `caption_reel` format: the three text blocks and the look of the video.","type":"object","properties":{"block1":{"description":"The hook, at the start of the video.","type":"string"},"block2":{"description":"The complement, at 2s. May be empty.","type":"string"},"block3":{"description":"The call to the caption, at 5s.","type":"string"},"font":{"type":"string"},"alignment":{"description":"As returned in `content.alignment` by GET /posts/:id.","type":"string","enum":["center","left"]},"boxStyle":{"description":"As returned in `content.boxStyle` by GET /posts/:id.","type":"string","enum":["rounded","square"]},"boxColor":{"description":"Hex, applies to all three blocks.","type":"string"},"textColor":{"description":"Hex, applies to all three blocks.","type":"string"},"boxColorByBlock":{"description":"Per-block box color. Null reverts to the general color.","type":"array","items":{"anyOf":[{"type":"string"},{"type":"null"}]}},"textColorByBlock":{"description":"Per-block text color. Null reverts to the general color.","type":"array","items":{"anyOf":[{"type":"string"},{"type":"null"}]}},"sizes":{"description":"Per-block font size, 20 to 140.","type":"array","items":{"anyOf":[{"type":"number"},{"type":"null"}]}}},"additionalProperties":false},"narration":{"description":"Only on `animated_audio` and `narrated_photos`: the spoken script and what is drawn over it. Changing `script` does NOT re-record the audio.","type":"object","properties":{"hook":{"description":"The line at the top of the video, up to 120 characters.","type":"string"},"script":{"description":"The full narrated text, with emotion markup. Changing it does NOT re-record the audio: the video keeps the voice that is already there, and the post is flagged as having stale media. Re-recording is not available through the API.","type":"string"},"speed":{"description":"Between 1 and 1.5.","type":"number"},"scenes":{"description":"`animated_audio` only. The complete scene list, replacing the current one; an empty list removes every illustration. Read the current ones in `content.scenes` from GET /posts/:id.","maxItems":60,"type":"array","items":{"oneOf":[{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"keyword"},"fields":{"type":"object","properties":{"value":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"big_number"},"fields":{"type":"object","properties":{"value":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"before_after"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"after":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"bullet_list"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"anyOf":[{"maxItems":10,"type":"array","items":{"type":"string","maxLength":200}},{"type":"null"}]},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"highlight"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"numbered_steps"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"anyOf":[{"maxItems":10,"type":"array","items":{"type":"string","maxLength":200}},{"type":"null"}]},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"question"},"fields":{"type":"object","properties":{"value":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"ratio_bar"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}]},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"bar_chart"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"anyOf":[{"maxItems":10,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":200},"value":{"type":"number"}},"required":["label","value"],"additionalProperties":false}},{"type":"null"}]}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"rising_line"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"after":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"progress_ring"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}]},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"timeline"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"anyOf":[{"maxItems":10,"type":"array","items":{"type":"string","maxLength":200}},{"type":"null"}]},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false},{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"type":{"type":"string","const":"wave_only"},"fields":{"type":"object","properties":{"value":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"label":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"text":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"before":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"after":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"items":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"steps":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"percent":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"},"bars":{"description":"Not a field of this scene type. Must be null or omitted.","type":"null"}},"additionalProperties":false}},"required":["start","end","type","fields"],"additionalProperties":false}]}},"photoScenes":{"description":"`narrated_photos` only. The complete scene list, as returned in `content.scenes` by GET /posts/:id.","maxItems":60,"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"spokenText":{"type":"string"},"depicts":{"type":"string"},"imagePrompt":{"type":"string"},"imageUrl":{"type":"string"},"origin":{"type":"string","enum":["ai","upload","edit"]}},"required":["id","start","end","spokenText","depicts","imagePrompt","imageUrl","origin"],"additionalProperties":false}}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"deletePostsId","summary":"Delete a post","description":"Permanently deletes the post. Irreversible.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/media":{"post":{"operationId":"postPostsIdMedia","summary":"Replace a post's media","description":"Replaces a single-image post's media with the given list. Does not apply to a carousel (its image is generated from its slides) or to a reel (its background video is replaced via `POST /posts/{id}/clip`). An empty list removes the media. Only works before the post publishes.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"media":{"maxItems":10,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"type":{"type":"string","enum":["image","video"]}},"required":["url","type"],"additionalProperties":false},"description":"The full media list, at most 10 items (the Instagram carousel limit). An empty list removes the media."}},"required":["media"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/schedule":{"post":{"operationId":"postPostsIdSchedule","summary":"Schedule a post","description":"Schedules the post to publish on its own at a future date and time, or changes the date of a post already scheduled. Only works on a draft, a previously failed post, or one already scheduled: a post in flight (publishing, queued, generating) or already published cannot be rescheduled this way.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"when":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"ISO 8601 with a timezone, in the future. Either `Z` or an offset like `-03:00`."}},"required":["when"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/unschedule":{"post":{"operationId":"postPostsIdUnschedule","summary":"Unschedule a post","description":"Takes the post out of the schedule queue and returns it to draft, without deleting anything. Only works on a scheduled post.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/archive":{"post":{"operationId":"postPostsIdArchive","summary":"Archive a post","description":"Removes the post from the Posttar calendar without deleting it; `reactivate` brings it back. Does NOT remove anything from Instagram: an already published post stays published there.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/reactivate":{"post":{"operationId":"postPostsIdReactivate","summary":"Reactivate a post","description":"Takes the post out of the archive and returns it to draft, ready to edit and schedule again. Only works on an archived post.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/publish":{"post":{"operationId":"postPostsIdPublish","summary":"Publish a post now","description":"Publishes the post to Instagram right away. Fire-and-forget: responds 202 with the post in `publishing` state (median 38s, p99 61s, measured in production); poll `GET /posts/{id}` for the outcome. Irreversible.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted. The resource is returned in its working state (for example `creating` or `publishing`); this call does not wait for the result. Poll the matching GET endpoint for the outcome.","content":{"application/json":{"schema":{}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/slides":{"post":{"operationId":"postPostsIdSlides","summary":"Add a slide","description":"Appends a new slide to the end of the carousel, inheriting the last slide's layout with placeholder text. Edit that text afterwards with `PATCH /slides/{id}`. Carousel only.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"layoutId":{"description":"Without it, inherits the layout of the post's last slide.","type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/slides/order":{"post":{"operationId":"postPostsIdSlidesOrder","summary":"Reorder slides","description":"Changes the order of the carousel's slides. Send the complete list of slide ids in the new order; a missing or repeated id is rejected, because the order cannot have a gap.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","maxLength":64},"description":"The complete list of slide ids, in the new order."}},"required":["order"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/edit-budget":{"get":{"operationId":"getPostsIdEditBudget","summary":"Get a post's image-edit budget","description":"Returns how many AI image edits (`POST /slides/{id}/reimagine`) this post has used and how many remain, so a client can check before spending one (about $0.015 each, capped at 2 on the standard plan) instead of risking a call just to find the budget empty.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"used":1,"cap":2,"remaining":1}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/slides/{id}":{"patch":{"operationId":"patchSlidesId","summary":"Update a slide's fields","description":"Changes one or more text fields of a single slide: title, body, or any other text field the slide's layout has. Use `GET /posts/{id}/slides` first to learn the field names and current values, and send them exactly as they appeared there. Does not change color, font, texture (`POST /slides/{id}/style`) or the photo. Carousel only.","tags":["slides"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":2200},"description":"Field name to new value, only for fields the slide's layout accepts. Values are text, up to 2200 characters each, at most 20 fields per request."}},"required":["fields"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"deleteSlidesId","summary":"Delete a slide","description":"Removes a slide from the carousel and renumbers the rest. Deleting the only remaining slide is rejected: a carousel needs at least one.","tags":["slides"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/slides/{id}/style":{"post":{"operationId":"postSlidesIdStyle","summary":"Update a slide's visual style","description":"Changes the font, colors (background, text, brand), or background texture of a single slide, never the whole post and never the project's brand. Send only the fields that need to change; colors must be hex (#rrggbb).","tags":["slides"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"titleFont":{"type":"string"},"bodyFont":{"type":"string"},"backgroundColor":{"description":"Hex, e.g. #112233.","type":"string"},"textColor":{"description":"Hex, e.g. #112233.","type":"string"},"brandColor":{"description":"Hex, e.g. #112233.","type":"string"},"texture":{"type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/slides/{id}/variant":{"post":{"operationId":"postSlidesIdVariant","summary":"Change a slide's layout variant","description":"Swaps a single slide's layout variant for another one from the catalog.","tags":["slides"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"layoutId":{"type":"string","minLength":1}},"required":["layoutId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/slides/{id}/reimagine":{"post":{"operationId":"postSlidesIdReimagine","summary":"Reimagine a slide with AI","description":"Only for the formats whose slide is a finished image (`premium_carousel` and `infographic`), where the whole slide is AI-designed and the text is baked into the image, so there is no field for `PATCH /slides/{id}` to change. Describe the change in one sentence and the slide is redesigned, preserving the rest. Limited edits per carousel; `GET /posts/{id}/edit-budget` reports how many remain.","tags":["slides"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"instruction":{"type":"string","minLength":1,"description":"The change, in one sentence."}},"required":["instruction"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/clips":{"get":{"operationId":"getPostsIdClips","summary":"List a reel's available clips","description":"Lists the background clips available to this reel from the project's video library: id and description of each, before choosing one with `POST /posts/{id}/clip`.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"clips":[]}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/clip":{"post":{"operationId":"postPostsIdClip","summary":"Set a reel's background clip","description":"Replaces the reel's background video with a clip from the project's video library. `clipId` must come from `GET /posts/{id}/clips`.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"clipId":{"type":"string","minLength":1}},"required":["clipId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/tracks":{"get":{"operationId":"getPostsIdTracks","summary":"List a reel's available tracks","description":"Lists the music tracks this reel can use: name, description, duration, which one is currently in use, and a link to listen to each, before choosing one with `POST /posts/{id}/track`.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"tracks":[{"id":"94917ea8-17e6-47de-a2df-c79146cb5771","name":"Bad Bunny - MONACO (Instrumental) - TYPE","description":null,"durationSeconds":267.377778,"suggestedStartSeconds":19,"url":"https://.../audio-tracks/posttar/bad-bunny-monaco-instrumental-type.mp3","inUse":false},{"id":"b6bb3c6d-9324-4df2-aced-70a6aead9a55","name":"INSONAMIA - Ronald Figo","description":null,"durationSeconds":181.36815,"suggestedStartSeconds":15,"url":"https://.../audio-tracks/posttar/insonamia-ronald-figo.mp3","inUse":false}],"inUse":"fda25fc1-6f3f-4eb6-b7d5-c53501a8c077"}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/posts/{id}/track":{"post":{"operationId":"postPostsIdTrack","summary":"Set a reel's track","description":"Sets, changes, or removes the reel's music. `trackId` must come from `GET /posts/{id}/tracks`; null mutes the reel. `startSeconds` picks which second of the track the reel's 7 seconds start from.","tags":["posts"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trackId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"From GET /posts/:id/tracks. Null mutes the reel."},"startSeconds":{"description":"What second of the track the reel's 7 seconds start from.","type":"number"}},"required":["trackId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/autopilot":{"get":{"operationId":"getProjectsIdAutopilot","summary":"Get a project's autopilot schedule","description":"Returns the autopilot's weekly grid: whether it is on, which days and hours are set, each slot's fixed theme, and the project's timezone, plus any blockers that would prevent publication even while on.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","enabled":false,"emailReport":true,"requiresApproval":false,"timezone":"America/Porto_Velho","slots":[],"blockers":["no_slots","no_instagram"]}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/autopilot/enable":{"post":{"operationId":"postProjectsIdAutopilotEnable","summary":"Turn on autopilot","description":"Turns on the autopilot: Posttar starts generating and scheduling posts on its own at the grid's slots. Rejected when the grid is empty.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/autopilot/disable":{"post":{"operationId":"postProjectsIdAutopilotDisable","summary":"Turn off autopilot","description":"Turns off the autopilot. No slot is deleted: the grid is kept and comes back in full when turned on again.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/autopilot/slots":{"post":{"operationId":"postProjectsIdAutopilotSlots","summary":"Add an autopilot slot","description":"Adds one more day and hour to the autopilot's grid, optionally with a fixed theme. Does not turn the autopilot on by itself.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"dayOfWeek":{"type":"integer","minimum":0,"maximum":6,"description":"0 is Monday, 6 is Sunday."},"hour":{"type":"integer","minimum":0,"maximum":23,"description":"Whole hour, in the project's timezone."},"theme":{"description":"Fixed topic for this slot. Without it, the autopilot picks the topic.","type":"string"}},"required":["dayOfWeek","hour"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/autopilot/slots/{slotId}":{"patch":{"operationId":"patchProjectsIdAutopilotSlotsSlotId","summary":"Update an autopilot slot's theme","description":"Changes a slot's fixed theme. A blank value erases it, and the autopilot goes back to choosing the topic on its own for that slot.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"slotId","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string","description":"Blank erases the fixed topic: the autopilot goes back to choosing it."}},"required":["theme"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"deleteProjectsIdAutopilotSlotsSlotId","summary":"Delete an autopilot slot","description":"Removes a slot from the autopilot's grid. Does not turn the autopilot off and does not touch other slots.","tags":["autopilot"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"slotId","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects":{"get":{"operationId":"getProjects","summary":"List projects","description":"Lists the account's projects, with each one's Instagram handle, how many projects the plan allows, and whether another one still fits.","tags":["projects"],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"projects":[{"id":"c85848ba-2881-4a2e-9bdd-841b26d07359","name":"Projeto de teste","instagram":null,"createdAt":"2026-07-31T14:29:14.237659+00:00"}],"limit":1,"canCreateMore":false}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"postProjects","summary":"Create a project","description":"Creates a new project. A project is an Instagram account with its own brand. Born without brand DNA and without Instagram connected; rejected when the plan's project limit is already reached.","tags":["projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1},"timezone":{"description":"IANA, e.g. America/Sao_Paulo. Without it, born in Sao Paulo.","type":"string"}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}":{"patch":{"operationId":"patchProjectsId","summary":"Rename a project","description":"Changes a project's display name in the app. Does not touch the profile name inside the brand DNA, which signs the posts' artwork.","tags":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/dna":{"get":{"operationId":"getProjectsIdDna","summary":"Get a project's brand DNA","description":"Returns the project's brand DNA: business description, target audience, content preferences, tone of voice, image style, title and body fonts, and the two brand colors, together with the catalog of fonts and image styles this project can choose from, which is where the valid values for `PATCH /projects/{id}/dna` come from.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"locale","in":"query","required":false,"schema":{"type":"string","enum":["pt","en","es"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","projectName":"Projeto de teste","description":"A Posttar é uma ferramenta da VINTTI Soluções Digitais que automatiza a criação, personalização, agendamento e publicação de carrosséis no Instagram. Gera textos e imagens, revi...","audience":"Pessoas, marcas e empresas que querem manter constância no Instagram, mas não têm tempo, equipe ou conhecimento para criar carrosséis. Fala especialmente com empreendedores, neg...","contentPreferences":"Priorizar conteúdos práticos sobre crescimento no Instagram, constância, automação, criação de carrosséis, identidade visual, geração de leads e produtividade. Mostrar como a fe...","toneOfVoice":"Escreva em português, de forma direta, simples e comercial, com frases curtas e foco no benefício. Use linguagem acessível, evitando excesso de termos técnicos. Fale com quem qu...","imageStyle":"modern","titleFont":null,"bodyFont":null,"colors":{"brand":"#3C50DD","background":"#FDFDFF"},"options":{"fonts":["Inter","Poppins","Sora","Manrope","Space Grotesk","Fraunces","Instrument Serif","Bebas Neue","JetBrains Mono","Permanent Marker","Caveat"],"imageStyles":[{"key":"journalistic","name":"Jornalístico"},{"key":"illustration","name":"Ilustração"}]}}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"patchProjectsIdDna","summary":"Update a project's brand DNA","description":"Saves only the fields sent; anything omitted stays exactly as it is. Text fields are replaced in full, never merged; an empty text field is rejected. Colors must be hex. Applies to what Posttar generates from now on: no existing post, caption, or slide text is rewritten, and an already published post never changes.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"targetAudience":{"type":"string"},"contentPreferences":{"type":"string"},"toneOfVoice":{"type":"string"},"imageStyle":{"description":"A key from GET /projects/:id/dna's `opcoes.estilosDeImagem`.","type":"string"},"titleFont":{"description":"A font from GET /projects/:id/dna's `opcoes.fontes`.","type":"string"},"bodyFont":{"description":"A font from GET /projects/:id/dna's `opcoes.fontes`.","type":"string"},"brandColor":{"description":"Hex, e.g. #112233.","type":"string"},"backgroundColor":{"description":"Hex, e.g. #112233. This is the posts' background.","type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/palettes":{"get":{"operationId":"getProjectsIdPalettes","summary":"List a project's color palettes","description":"Posttar's ready-made color palettes, each with the key `POST /projects/{id}/palettes/apply` accepts, plus the colors this project uses today.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"projectId":"c85848ba-2881-4a2e-9bdd-841b26d07359","ready":[{"key":"verde","brandColor":"#099250","schemes":[{"name":"Padrão","brandColor":"#099250","backgroundColor":"#F6FEF9","textColor":"#1D2939"},{"name":"Fundo escuro","brandColor":"#3CCB7F","backgroundColor":"#052E1C","textColor":"#FFFFFF"}]},{"key":"teal","brandColor":"#0E9384","schemes":[{"name":"Padrão","brandColor":"#0E9384","backgroundColor":"#F6FEFC","textColor":"#1D2939"},{"name":"Fundo escuro","brandColor":"#2ED3B7","backgroundColor":"#0A2926","textColor":"#FFFFFF"}]}],"current":[{"id":"7c927623-f8c3-4f7a-8d5c-94a0d0430281","name":"Padrão","brandColor":"#3C50DD","backgroundColor":"#FDFDFF","textColor":"#1D2939","hasLogo":false}],"usesMoreThanOnePalette":false}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/palettes/apply":{"post":{"operationId":"postProjectsIdPalettesApply","summary":"Apply a color palette","description":"Replaces the brand's colors with one of the ready-made palettes (or the project's own brand color hex), preserving the logo. Applies to what Posttar generates from now on; an already published post never changes.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1,"description":"From GET /projects/:id/palettes, either the preset key or the brand color hex."}},"required":["key"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/brand/photo":{"post":{"operationId":"postProjectsIdBrandPhoto","summary":"Set the brand's round photo","description":"Replaces the round photo shown in the header of the slides. `url` must already be in Posttar's public bucket. Applies to what is generated from now on.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"description":"Must be in our public bucket."}},"required":["url"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/brand/logo":{"post":{"operationId":"postProjectsIdBrandLogo","summary":"Set the brand's logo","description":"Replaces the logo stamped on the slides' artwork. `url` must already be in Posttar's public bucket. Applies to every palette of the project at once.","tags":["brand-dna"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"description":"Must be in our public bucket."}},"required":["url"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/radar/analysis":{"get":{"operationId":"getProjectsIdRadarAnalysis","summary":"Get the project's latest Radar analysis","description":"Returns the project's latest Radar run. Check `estado` first: a run may be in progress, interrupted, failed, or there may be none yet. Starting a new run only happens from the Radar screen, not through the API.","tags":["radar"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"state":"completed","startedAt":"2026-08-22T00:45:37.177413+00:00","phase":null,"error":null,"lastCompleted":{"id":"12831dc4-f950-4125-aa85-0a31cac0c66d","completedAt":"2026-08-22T00:45:37.177413+00:00","insight":null,"targets":{"terms":["instagram"],"hashtags":[],"yt_terms":[],"competitors":["use.posttar"],"yt_channels":[]},"kpis":{"all":{"views":1280681274,"studied":109},"youtube":{"views":0,"studied":0},"instagram":{"views":1280681274,"studied":109}}}}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/radar/inspirations":{"get":{"operationId":"getProjectsIdRadarInspirations","summary":"List the project's Radar inspirations","description":"Lists the posts Radar has already found for this project, best to worst, with who published each one, the link, the caption, and the views. Read-only: does not start an analysis and does not create a post.","tags":["radar"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","youtube"]}},{"name":"limit","in":"query","required":false,"description":"Default 10, max 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"total":4,"next":"eyJjaGF2ZSI6OTIuOSwiaWQiOiJEYVpXZ2NYeDJMVCJ9","inspirations":[{"shortcode":"DcNflthvNwy","url":"https://www.instagram.com/p/DcNflthvNwy/","handle":"simran.verma125","caption":"Relatable 💯…\n•\n•\n#Corporate #instagram #reels #viral #follow , Explore, Office, work, Comedy, Corporatelife, employees, reality","platform":"instagram","format":"video","score":93.4,"views":13856429,"firstSeenAt":"2026-08-22T00:43:51.906847+00:00","publishedAt":"2026-08-19T07:04:52+00:00"},{"shortcode":"DaZWgcXx2LT","url":"https://www.instagram.com/p/DaZWgcXx2LT/","handle":"fyndingplaces","caption":"😂🔥 Think you know every Instagram trick? Think again! 👀📱\n\nI just shared 3 fun Instagram pranks that will leave your friends totally confused! 🤯🤣 These are easy to try, harmless,...","platform":"instagram","format":"video","score":92.9,"views":11870423,"firstSeenAt":"2026-08-22T00:43:21.423496+00:00","publishedAt":"2026-07-05T03:32:33+00:00"}]}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/reports/summary":{"get":{"operationId":"getProjectsIdReportsSummary","summary":"Get a period summary","description":"How many posts the project has published, scheduled, and in draft, optionally within a period. Also reports how many published posts were never measured, which is absence of measurement, not zero views.","tags":["reports"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"period":{"from":null,"to":null},"published":0,"scheduled":0,"drafts":21,"publishedWithoutMetrics":0,"publishedWithoutDate":0}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/reports/performance":{"get":{"operationId":"getProjectsIdReportsPerformance","summary":"Get posts' performance","description":"Published posts with each one's numbers, in two lists that are never mixed: measured ones with real views, likes, and comments, and unmeasured ones Posttar never measured (their views are `null`, which is not the same as zero).","tags":["reports"],"parameters":[{"name":"id","in":"path","required":true,"description":"Opaque id from a previous response.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Default 20, max 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"period":{"from":null,"to":null},"measured":[],"totalMeasured":0,"withoutMetrics":[],"totalWithoutMetrics":0,"totals":null}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/team":{"get":{"operationId":"getTeam","summary":"List the workspace's team","description":"Who is in the workspace, with role and email, plus pending invites, how many people the plan allows, and how many seats remain. Read-only: inviting and canceling invites are not available through the API. See this document's `x-posttar-excluded` for why.","tags":["team"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Default 50, max 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{},"example":{"yourRole":"owner","members":[{"id":"f8090f41-2e10-4a7d-b0b1-27051e8f2c24","userId":"fe7840c7-4f22-42cb-8786-4e486b5db8f2","role":"owner","name":"Alex Rivera","email":"member@example.com","joinedAt":"2026-04-05T02:45:37.858819+00:00","isYou":true}],"pendingInvites":[],"planLimit":1,"seatsUsed":1,"seatsFree":0}}}},"204":{"description":"Success, with no body."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"ptr_live_<prefix>_<secret>","description":"An API key created from the app's settings screen. Only the secret is checked; the prefix before it is just how the app displays and revokes a key."}},"schemas":{"Error":{"type":"object","description":"The v1 error envelope. Every non-2xx response, from the edge or from the operation, has this shape.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code. This is the contract: match on this, never on `message`."},"message":{"type":"string","description":"Human-readable message, in Portuguese. Not stable across releases: safe to show a user, unsafe to pattern-match on."}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The path parameter, query string, or request body failed validation. `message` names the offending field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"The API key is missing, malformed, revoked, or belongs to someone no longer on the workspace. Every key that was presented and rejected returns the identical message on purpose: telling them apart would let a caller probe which one applies. Fix this by sending a valid key; a key that is valid but not entitled gets 403 instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The API key is valid, but the workspace does not have access to this resource: the API is available on the Plus and Scale plans. This response is the same regardless of the underlying reason, on purpose, down to the status code: retrying with a different key will not help.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Either the path does not match any v1 endpoint, or the resource does not exist, or it exists but belongs to a different workspace. These return the identical response on purpose: telling them apart would let a caller probe for ids that are not theirs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"MethodNotAllowed":{"description":"The path exists, but not with this HTTP method. The `Allow` header lists the methods that do.","headers":{"Allow":{"schema":{"type":"string"},"description":"Comma-separated list of allowed methods."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The resource is not in a state that allows this action (for example, scheduling a post that is already publishing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"TooManyRequests":{"description":"Best effort, not a guarantee: 60 requests per minute per API key, 120 per minute per IP, counted in memory per server instance (Fluid Compute may spread one caller across instances, so the real ceiling can run a little over these numbers). The hard ceiling is the workspace's credit balance.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before trying again."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Something failed on our side: an unexpected error, or a dependency the operation needed (usually the database) that did not answer. Logged; the cause is not in this response. Safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"x-posttar-excluded":[{"name":"re-recording an audiogram's narration","reason":"Not available through the API. Editing the script through PATCH /posts/:id keeps the voice that is already there and flags the post as having stale media."},{"name":"delivering a rendered preview into a chat","reason":"Not available through the API: it delivers the image into a conversation, and the API has no conversation to deliver into."},{"name":"listing the layouts available for one slide","reason":"Not available through the API yet. POST /slides/:id/variant does change a slide's layout when you already know the layout id."},{"name":"choosing a default project","reason":"Not available through the API, and not needed: every endpoint that belongs to a project takes the project id in the path."},{"name":"creating, listing and revoking API keys","reason":"Not available through the API. Keys are managed from the app's settings screen: a key that could create another key would survive being revoked."},{"name":"connecting an Instagram account","reason":"Not available through the API: it is an authorization a person grants in a browser."},{"name":"checkout and plan changes","reason":"Not available through the API: paying and changing plan happen in the app."},{"name":"moving, resizing or repositioning an element","reason":"Not available through the API: fine geometry is something you drag, in the editor."},{"name":"deleting a project","reason":"Not available through the API: it takes the project's posts, slides, Instagram account, Radar and brand DNA with it, and only the app shows what is about to go."},{"name":"inviting someone to the team","reason":"Not available through the API: an invite creates a person's access, and revoking the key that sent it does not take that access away. GET /team, which reads who is on the team, is available."},{"name":"cancelling a pending invite","reason":"Not available through the API, together with sending one. Team management lives in the app."},{"name":"removing someone from the team","reason":"Not available through the API: it cuts off a real person's access, with no undo."}]}