{"openapi":"3.1.0","info":{"title":"Ampost API","version":"1.0.0","description":"Publish to Instagram, Facebook, LinkedIn, TikTok, Threads, X, YouTube, Pinterest, Bluesky, Telegram and Discord with one API. Every operation is also an MCP tool at /mcp with the same input and output."},"servers":[{"url":"https://api.ampost.io"}],"security":[{"apiKey":[]}],"paths":{"/api/platforms":{"get":{"operationId":"platforms_list","summary":"List platforms and their capabilities","description":"List every supported platform with its rules: text length, link support, scheduling, unpublish (delete a published post), editPublished (edit a published post's text), firstComment (comment posted after publish, and its length), media types, counts, sizes and required metadata, placements by media shape, and the JSON Schema of its `options`. Read this instead of hardcoding platform differences.\n\nMCP tool: `platforms_list`. Key scope: `posts:read`.","tags":["platforms"],"security":[{"apiKey":["posts:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List platforms and their capabilities","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts":{"get":{"operationId":"posts_list","summary":"List posts","description":"List your posts, newest first, optionally filtered by status, platform, platform set (posts with an account in it) or text.\n\nMCP tool: `posts_list`. Key scope: `posts:read`.","tags":["posts"],"security":[{"apiKey":["posts:read"]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","scheduled","queued","posting","published","partial","failed","discarded","deleted"],"description":"Post status. `deleted`: every account's post was deleted from its platform (posts_unpublish)."}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}},{"name":"platformSetId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Only posts with an account in this platform set"}},{"name":"search","in":"query","required":false,"description":"Case-insensitive match on the post text","schema":{"description":"Case-insensitive match on the post text","type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List posts","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"posts_create","summary":"Create, schedule or publish a post","description":"Create a post for one or more platforms. `targets` lists platform sets, each with its platforms; omit `platformSetId` for your default set. List several sets to reach several accounts of the same platform in one post (each set holds one account per platform); `platformPosts` then has one entry per account. Without `scheduledFor` it is a draft; set `publishNow` to publish it right away, or `scheduledFor` to publish later. `media` items are public URLs with a required `type` (REST also accepts multipart file uploads up to 4 MB per request; for larger files or files on the user's device use media_upload_create). Use `options.<platform>` for per-platform text and settings. `firstComment` is posted as a comment (a reply on X, Threads and Bluesky) on each new post right after it publishes; a failed comment leaves the post published with `platformPosts[].firstComment.status` failed. Call platforms_list (GET /api/platforms) for each platform's limits, placements and options.\n\nMCP tool: `posts_create`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"}},"multipart/form-data":{"description":"File uploads. The whole request must be at most 4 MB (413 `PAYLOAD_TOO_LARGE`); send larger files with a media upload (`POST /api/media/uploads`).","schema":{"type":"object","required":["data"],"properties":{"data":{"type":"string","contentMediaType":"application/json","description":"JSON matching CreatePostMultipartData. Media items reference file parts with `{ \"file\": \"<part name>\" }`."}},"additionalProperties":{"type":"string","format":"binary"}}}}},"responses":{"201":{"description":"Create, schedule or publish a post","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"413":{"description":"The request body is over 4 MB: `PAYLOAD_TOO_LARGE`. A body over 4.5 MB never reaches Ampost: the hosting edge answers a plain-text 413 `FUNCTION_PAYLOAD_TOO_LARGE`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/bulk":{"post":{"operationId":"posts_import_csv","summary":"Import posts from CSV","description":"Create many posts from a CSV file: one post per row, each checked like posts_create. Columns: `text`, `platforms` (space-separated, with an optional `platformSetId`) or `accountIds`, `scheduledFor` or `useQueue` (neither: a draft), `linkUrl`, `media` (space-separated public URLs; `.mp4`, `.m4v`, `.mov` and `.webm` are videos, the rest images) and `text_<platform>` for per-platform text. The dashboard's CSV export has the same columns, so an exported file imports again (its read-only columns are skipped). Send `dryRun: true` first: it checks every row without creating anything. A bad row does not stop the others; `rows[]` gives each row's `status` (`valid`, `created` or `error`) and `errors` with the column. Unknown columns are skipped with a warning. Plans import at most 50 (Free), 1,000 (Pro), 2,500 (Max) or 5,000 (Scale) rows per request. An import and a dry run each take one token per row from the hourly `importPosts` limit (two runs of the plan's largest file an hour, e.g. a dry run and its import); a file with more rows than are left fails with 429 `RATE_LIMITED` and creates nothing. Send an idempotency key with the import: a retry with the same key and file returns the first result and creates nothing new. REST also accepts multipart with the file in a part named `file`.\n\nMCP tool: `posts_import_csv`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportPostsCsvRequest"}},"multipart/form-data":{"description":"The CSV as a file upload. The whole request must be at most 4 MB (413 `PAYLOAD_TOO_LARGE`).","schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The CSV file (UTF-8)"},"dryRun":{"type":"string","enum":["true","false"],"description":"`true` checks the rows without creating posts. Default `false`."}}}}}},"responses":{"200":{"description":"Import posts from CSV","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportPostsCsvResult"}}}},"413":{"description":"The request body is over 4 MB: `PAYLOAD_TOO_LARGE`. A body over 4.5 MB never reaches Ampost: the hosting edge answers a plain-text 413 `FUNCTION_PAYLOAD_TOO_LARGE`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{postId}":{"get":{"operationId":"posts_get","summary":"Get a post","description":"Get one post with its result per account (`platformPosts`).\n\nMCP tool: `posts_get`. Key scope: `posts:read`.","tags":["posts"],"security":[{"apiKey":["posts:read"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}}],"responses":{"200":{"description":"Get a post","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"posts_update","summary":"Update a post","description":"Change a draft or scheduled post. Send only the fields to change; `media` and `targets` replace the whole list (accounts the post keeps keep their results). `options` is merged per platform: each `options.<platform>` you send replaces that platform's options as a whole, `null` removes them, and other platforms keep theirs. Set `scheduledFor` to null to turn a scheduled post back into a draft. To change the text of a published post, use posts_edit_published.\n\nMCP tool: `posts_update`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostRequest"}}}},"responses":{"200":{"description":"Update a post","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"posts_delete","summary":"Delete a post","description":"Discard a post that has not been published, including a scheduled one. The post stays readable with status `discarded`, and its media in Ampost storage is deleted. To take a published post down from the platforms, use posts_unpublish.\n\nMCP tool: `posts_delete`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}}],"responses":{"200":{"description":"Delete a post","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{postId}/publish":{"post":{"operationId":"posts_publish","summary":"Publish a post now","description":"Publish a draft or scheduled post to all its accounts now. Check `platformPosts` for each account's result; videos may stay `processing` for a while.\n\nMCP tool: `posts_publish`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"responses":{"200":{"description":"Publish a post now","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{postId}/unpublish":{"post":{"operationId":"posts_unpublish","summary":"Unpublish a post","description":"Take a published post down from the platforms: every account where it is published, or only the given `accountIds` (from `platformPosts[].accountId`). Each account's result is in `platformPosts`: `deleted`, or still `published` with `error` saying why (`UNPUBLISH_NOT_SUPPORTED` on Instagram and TikTok, which have no delete API; the platform's own refusal otherwise, such as Telegram's 48-hour limit for bots). The post becomes `deleted` once no account has it; it stays readable in Ampost. Call platforms_list for `unpublish.supported` per platform. Deleting from X costs X units like a post.\n\nMCP tool: `posts_unpublish`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnpublishPostRequest"}}}},"responses":{"200":{"description":"Unpublish a post","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{postId}/edit-published":{"post":{"operationId":"posts_edit_published","summary":"Edit a published post's text","description":"Replace the text of a published post on the platforms: every account where it is published, or only the given `accountIds` (from `platformPosts[].accountId`). Text only; media and links stay. Each account's result is in `platformPosts`: an edited account's `text` holds the new text, and an account the platform refused keeps its text with `error` (`EDIT_NOT_SUPPORTED` on Instagram, Threads, TikTok, Bluesky and X, and on Facebook stories; the platform's own refusal otherwise). Facebook edits only posts Ampost published; a Telegram caption under media stays limited to 1024 characters. YouTube and Pinterest replace the video or Pin description. Call platforms_list for `editPublished.supported` per platform. To change a draft or scheduled post, use posts_update.\n\nMCP tool: `posts_edit_published`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditPublishedPostRequest"}}}},"responses":{"200":{"description":"Edit a published post's text","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{postId}/retry":{"post":{"operationId":"posts_retry","summary":"Retry failed accounts","description":"Publish again to the accounts that failed, or only to the given `accountIds` (from `platformPosts[].accountId`). Ampost already retries retryable failures (rate limits, timeouts, platform errors) by itself, up to 5 attempts with backoff; an account waiting for that shows `pending` with `nextAttemptAt`. Call this for an account that is `failed`, after fixing the cause. It starts `attempts` again from 0. A published account whose first comment failed (`platformPosts[].firstComment.status` failed) posts only the comment again, without publishing the post twice or counting it again.\n\nMCP tool: `posts_retry`. Key scope: `posts:write`.","tags":["posts"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"postId","in":"path","required":true,"description":"Post id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Post id"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryPostRequest"}}}},"responses":{"200":{"description":"Retry failed accounts","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/media/uploads":{"post":{"operationId":"media_upload_create","summary":"Start a media upload","description":"Get a way to upload a local file for a post. Media in posts_create must be a public URL; use this when the user has the file on their device or you have the file itself. Returns `uploadPageUrl`, an Ampost page where the user uploads files in a browser (in MCP, a client that supports URL elicitation asks the user to open it itself and leaves `uploadPageUrl` out), and `uploadUrl` + `method` + `headers` to PUT one file directly. Both stop accepting files after 60 minutes. Then poll media_upload_status; when it is completed, its `files` are `media[]` items for posts_create. Files that no post uses are deleted 24 hours after the upload was created (by the daily cleanup).\n\nMCP tool: `media_upload_create`. Key scope: `media:write`.","tags":["media"],"security":[{"apiKey":["media:write"]}],"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMediaUploadRequest"}}}},"responses":{"201":{"description":"Start a media upload","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadCreated"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/media/uploads/{uploadId}":{"get":{"operationId":"media_upload_status","summary":"Get a media upload","description":"Read a media upload: `pending` until files arrive, `completed` with `files`, `failed` with `error` (the direct upload's content was not the type it was sent as), or `expired`. Poll every 3-5 seconds after media_upload_create. Each item in `files` is a `media[]` item (`url`, `type`, `mimeType`, `sizeBytes`, `width`, `height`, `durationSeconds`): pass them to posts_create unchanged.\n\nMCP tool: `media_upload_status`. Key scope: `media:write`.","tags":["media"],"security":[{"apiKey":["media:write"]}],"parameters":[{"name":"uploadId","in":"path","required":true,"description":"Media upload id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Media upload id"}}],"responses":{"200":{"description":"Get a media upload","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUpload"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts":{"get":{"operationId":"accounts_list","summary":"List connected accounts","description":"List your social accounts, optionally only one platform or one platform set. `status` defaults to `active`, the accounts that can publish; pass `revoked` for disconnected accounts or `all` for both. The `active` total for a set equals that set's `accountCount` in platform_sets_list. `health` says whether each account can publish (`canPost`), whether only a reconnect helps (`needsReconnect`), and why (`issues[]` with codes such as `TOKEN_EXPIRED` or `MISSING_SCOPE:w_member_social`). Fix with accounts_connect and the account's id as `accountId`. `platformMetadata` has public per-platform details, such as the TikTok creator's allowed privacy levels.\n\nMCP tool: `accounts_list`. Key scope: `accounts:read`.","tags":["accounts"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}},{"name":"platformSetId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Only accounts in this platform set"}},{"name":"status","in":"query","required":false,"description":"`active` (default): accounts that can publish. `revoked`: disconnected accounts. `all`: both.","schema":{"default":"active","description":"`active` (default): accounts that can publish. `revoked`: disconnected accounts. `all`: both.","type":"string","enum":["active","revoked","all"]}},{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List connected accounts","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/{accountId}":{"get":{"operationId":"accounts_get","summary":"Get a connected account","description":"Get one social account by id, including revoked ones (`status: revoked`). `health`: `canPost`, `needsReconnect` and `issues[]` (codes such as `ACCOUNT_REVOKED`, `TOKEN_EXPIRED`, `MISSING_SCOPE:<scope>`, each with a message to relay). When `needsReconnect` is true, call accounts_connect with `accountId` set to this id; the account keeps its id. `platformMetadata` has public per-platform details.\n\nMCP tool: `accounts_get`. Key scope: `accounts:read`.","tags":["accounts"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"responses":{"200":{"description":"Get a connected account","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"accounts_disconnect","summary":"Disconnect an account","description":"Disconnect a social account: Ampost revokes its access at the platform where the platform allows it, deletes the stored tokens and sets `status: revoked`. Scheduled posts for the account will fail. The account keeps its id and can be reconnected later with accounts_connect and `accountId`. `providerRevoked` says whether the platform confirmed the revoke; when false, `providerAccessSettings` says where the user removes Ampost in the platform's settings. Instagram and Threads have no revoke endpoint, so they always return `providerRevoked: false`. Calling it again on a disconnected account returns the account unchanged with `providerRevoked: false`.\n\nMCP tool: `accounts_disconnect`. Key scope: `accounts:write`.","tags":["accounts"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"responses":{"200":{"description":"Disconnect an account","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisconnectedAccount"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/{accountId}/analytics":{"patch":{"operationId":"accounts_set_analytics","summary":"Turn X analytics on or off","description":"Opt an X account in to analytics, or out again. Every X read is billed, so X analytics are off until the account opts in, and the reads count against the plan's monthly X units like publishing (Max and Scale). When on, Ampost reads the metrics of the posts it published to the account during their first 29 days (daily for 3 days, then weekly) and the follower count once a day; three post reads or one follower read cost one X unit. The sync pauses when the units run out and resumes when they reset. Other platforms need no opt-in (`analytics.optInRequired` is false) and return 400. A plan without X returns 403 UPGRADE_REQUIRED. Returns the account with its `analytics` state.\n\nMCP tool: `accounts_set_analytics`. Key scope: `accounts:write`.","tags":["accounts"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetAccountAnalyticsRequest"}}}},"responses":{"200":{"description":"Turn X analytics on or off","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/{accountId}/boards":{"get":{"operationId":"accounts_list_boards","summary":"List a Pinterest account's boards","description":"List the boards of an active Pinterest account (up to 250), read live from Pinterest. `defaultBoardId` is the board Pins go to when a post sets no `options.pinterest.boardId`; it is `null` until one is picked, and the account then has the `BOARD_NOT_SELECTED` health warning. Ask the user which board to use and call accounts_set_board. An account with a single board gets it as the default at connect. Other platforms return 400.\n\nMCP tool: `accounts_list_boards`. Key scope: `accounts:read`.","tags":["accounts"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"responses":{"200":{"description":"List a Pinterest account's boards","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinterestBoardList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/{accountId}/board":{"patch":{"operationId":"accounts_set_board","summary":"Pick a Pinterest account's default board","description":"Set the board Pins go to when a post sets no `options.pinterest.boardId`: pass `boardId` (from accounts_list_boards), or `newBoardName` to create a public board and use it. Ampost checks the board with Pinterest first. The choice survives a reconnect. Returns the account; `platformMetadata.boardId` and `boardName` show the default. Other platforms return 400.\n\nMCP tool: `accounts_set_board`. Key scope: `accounts:write`.","tags":["accounts"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPinterestBoardRequest"}}}},"responses":{"200":{"description":"Pick a Pinterest account's default board","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/connect":{"post":{"operationId":"accounts_connect","summary":"Start connecting an account","description":"Create a short-lived Ampost-hosted link that connects one social account to a platform set. The user opens `connectUrl` in a browser and authorizes there; consent cannot happen in chat. In MCP, a client that supports URL elicitation asks the user to open the page itself, and the result then has no `connectUrl`. Then poll the connection request until it is connected, failed or expired. To reconnect an existing account (a revoked one, or an active one whose `health.needsReconnect` is true), pass its id as `accountId`; `platform` may then be omitted. For a new connection, `expectedUsername` or `expectedPlatformAccountId` makes sure the user signs in to the right account. If the user signs in to another account, the request fails with ACCOUNT_MISMATCH and nothing changes. A new request replaces the pending one for the same platform and set, also one the user opened but did not finish (it fails with SUPERSEDED), so call this again when the user lost or closed the page.\n\nMCP tool: `accounts_connect`. Key scope: `accounts:write`.","tags":["accounts"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectAccountRequest"}}}},"responses":{"201":{"description":"Start connecting an account","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectRequestCreated"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/accounts/connect/{connectRequestId}":{"get":{"operationId":"accounts_connect_status","summary":"Get a connection request","description":"Read the status of an account connection request: pending, awaiting_selection, connected, failed or expired. Poll every 2-5 seconds. When connected, `accountId` is the account's id (a reconnected account keeps its id). When failed or expired, `error.message` says why and what the user should do next; relay it as is. `ACCOUNT_MISMATCH` means the user signed in to another account than `accountId` or the expected one; nothing was changed. `SOCIAL_ACCOUNT_IN_USE` means a Free workspace tried to connect a social account another Ampost workspace has (or had in the last 30 days); a paid plan can connect it. `SUPERSEDED` means a newer request for this platform replaced this one: poll the newer request instead. `USER_CANCELLED` means the user cancelled or declined consent.\n\nMCP tool: `accounts_connect_status`. Key scope: `accounts:read`.","tags":["accounts"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"connectRequestId","in":"path","required":true,"description":"Connection request id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Connection request id"}}],"responses":{"200":{"description":"Get a connection request","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectRequest"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/platform-sets":{"get":{"operationId":"platform_sets_list","summary":"List platform sets","description":"List your platform sets with their active account counts, default set first. `accountCount` counts only active accounts, the same ones accounts_list returns by default; revoked accounts are not counted. A platform set groups at most one account per platform; every post targets one set.\n\nMCP tool: `platform_sets_list`. Key scope: `accounts:read`.","tags":["platform-sets"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List platform sets","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSetList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"platform_sets_create","summary":"Create a platform set","description":"Create an empty platform set. You can have at most 20 sets.\n\nMCP tool: `platform_sets_create`. Key scope: `accounts:write`.","tags":["platform-sets"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSetRequest"}}}},"responses":{"201":{"description":"Create a platform set","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSet"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/platform-sets/{platformSetId}":{"get":{"operationId":"platform_sets_get","summary":"Get a platform set","description":"Get one platform set with its active account count (revoked accounts are not counted).\n\nMCP tool: `platform_sets_get`. Key scope: `accounts:read`.","tags":["platform-sets"],"security":[{"apiKey":["accounts:read"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}}],"responses":{"200":{"description":"Get a platform set","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSet"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"platform_sets_update","summary":"Rename a platform set","description":"Rename a platform set, including the default set.\n\nMCP tool: `platform_sets_update`. Key scope: `accounts:write`.","tags":["platform-sets"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSetRequest"}}}},"responses":{"200":{"description":"Rename a platform set","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSet"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"platform_sets_delete","summary":"Delete a platform set","description":"Delete a platform set and revoke its active accounts. Its disconnected accounts and its posts are kept without a set; reconnect an account with accounts_connect and its accountId to put it in another set. Your last remaining set cannot be deleted (409 LAST_PLATFORM_SET). 409 PLATFORM_SET_IN_USE means an account was connected to the set during the delete: retry.\n\nMCP tool: `platform_sets_delete`. Key scope: `accounts:write`.","tags":["platform-sets"],"security":[{"apiKey":["accounts:write"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}}],"responses":{"200":{"description":"Delete a platform set","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deleted"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/platform-sets/{platformSetId}/queue":{"get":{"operationId":"queue_get","summary":"Get a posting queue","description":"Get the posting queue of a platform set. A set without a saved queue answers with no slots in UTC. Each platform set has one queue: weekly slots (weekday and HH:MM) in an IANA time zone, which follow its daylight saving changes. posts_create with `useQueue: true` schedules the post in the set's next free slot. A slot is taken while a queued post is scheduled at its time; rescheduling, publishing or deleting the post frees it.\n\nMCP tool: `queue_get`. Key scope: `posts:read`.","tags":["platform-sets"],"security":[{"apiKey":["posts:read"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}}],"responses":{"200":{"description":"Get a posting queue","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Queue"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"queue_update","summary":"Update a posting queue","description":"Set the time zone or the weekly slots of a platform set's queue; `slots` replaces the whole list. Queues need the Pro plan or above (403 UPGRADE_REQUIRED). Posts already in the queue keep their time. Each platform set has one queue: weekly slots (weekday and HH:MM) in an IANA time zone, which follow its daylight saving changes. posts_create with `useQueue: true` schedules the post in the set's next free slot. A slot is taken while a queued post is scheduled at its time; rescheduling, publishing or deleting the post frees it.\n\nMCP tool: `queue_update`. Key scope: `posts:write`.","tags":["platform-sets"],"security":[{"apiKey":["posts:write"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateQueueRequest"}}}},"responses":{"200":{"description":"Update a posting queue","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Queue"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/platform-sets/{platformSetId}/queue/slots":{"get":{"operationId":"queue_slots","summary":"Preview queue slots","description":"The queue's next slot times from now on, each with the queued post holding it (`postId`, null when free). With `filter: free` the first slot is where posts_create with `useQueue` puts the next post. Each platform set has one queue: weekly slots (weekday and HH:MM) in an IANA time zone, which follow its daylight saving changes. posts_create with `useQueue: true` schedules the post in the set's next free slot. A slot is taken while a queued post is scheduled at its time; rescheduling, publishing or deleting the post frees it.\n\nMCP tool: `queue_slots`. Key scope: `posts:read`.","tags":["platform-sets"],"security":[{"apiKey":["posts:read"]}],"parameters":[{"name":"platformSetId","in":"path","required":true,"description":"Platform set id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}},{"name":"count","in":"query","required":false,"description":"How many slots, 1-50. Default 10.","schema":{"default":10,"description":"How many slots, 1-50. Default 10.","type":"integer","minimum":1,"maximum":50}},{"name":"filter","in":"query","required":false,"description":"`free`: only free slots, the ones posts_create with `useQueue` fills next, in order. Default `all`: taken slots too, with their post.","schema":{"default":"all","description":"`free`: only free slots, the ones posts_create with `useQueue` fills next, in order. Default `all`: taken slots too, with their post.","type":"string","enum":["all","free"]}}],"responses":{"200":{"description":"Preview queue slots","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueuePreview"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/posts":{"get":{"operationId":"analytics_posts","summary":"Post analytics","description":"Metrics of your published posts, newest first: one `platformPosts` entry per account the post went to, with views, reach, likes, comments, shares and saves (null when the platform does not report one). Pass `postId` for one post. `analyticsStatus` says why an entry has no metrics. Analytics cover Facebook Pages, Instagram, Threads, TikTok, Bluesky, YouTube and Pinterest accounts (YouTube and Pinterest: only posts published through Ampost) (LinkedIn once its API access is approved), X accounts that opted in with accounts_set_analytics (Max and Scale; only posts published through Ampost), and Telegram followers (no post metrics). Discord has no analytics: asking for it fails with 422 `ANALYTICS_NOT_AVAILABLE_ON_PLATFORM`. When none of the matching accounts has analytics enabled the call fails with 403 `ANALYTICS_NOT_ENABLED` (its `details.accounts` say why per account). Ampost reads analytics in the background and serves the stored numbers: each account about hourly (daily on the Free plan), a post's metrics hourly in its first 48 hours, every 6 hours up to 14 days and daily up to 90 days. X posts are read daily in their first 3 days and weekly up to 29 days, which costs the plan's X units. Meta itself can lag 24-48 hours. `syncedAt` says when each number was read.\n\nMCP tool: `analytics_posts`. Key scope: `analytics:read`.","tags":["analytics"],"security":[{"apiKey":["analytics:read"]}],"parameters":[{"name":"postId","in":"query","required":false,"description":"Only this post","schema":{"description":"Only this post","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}},{"name":"platformSetId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Post analytics","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsPostList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/overview":{"get":{"operationId":"analytics_overview","summary":"Analytics overview","description":"Per account and in total, for posts published between `from` and `to` (UTC days, default the last 30): post count, summed views, reach, likes, comments, shares and saves, followers and their change, and sync state. These are the dashboard's numbers. `unavailableAccounts` lists matching accounts without analytics and why. Analytics cover Facebook Pages, Instagram, Threads, TikTok, Bluesky, YouTube and Pinterest accounts (YouTube and Pinterest: only posts published through Ampost) (LinkedIn once its API access is approved), X accounts that opted in with accounts_set_analytics (Max and Scale; only posts published through Ampost), and Telegram followers (no post metrics). Discord has no analytics: asking for it fails with 422 `ANALYTICS_NOT_AVAILABLE_ON_PLATFORM`. When none of the matching accounts has analytics enabled the call fails with 403 `ANALYTICS_NOT_ENABLED` (its `details.accounts` say why per account). Ampost reads analytics in the background and serves the stored numbers: each account about hourly (daily on the Free plan), a post's metrics hourly in its first 48 hours, every 6 hours up to 14 days and daily up to 90 days. X posts are read daily in their first 3 days and weekly up to 29 days, which costs the plan's X units. Meta itself can lag 24-48 hours. `syncedAt` says when each number was read.\n\nMCP tool: `analytics_overview`. Key scope: `analytics:read`.","tags":["analytics"],"security":[{"apiKey":["analytics:read"]}],"parameters":[{"name":"from","in":"query","required":false,"description":"First day (UTC), YYYY-MM-DD. Default: 29 days before `to`. At most 90 days with `to`.","schema":{"description":"First day (UTC), YYYY-MM-DD. Default: 29 days before `to`. At most 90 days with `to`.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"to","in":"query","required":false,"description":"Last day (UTC), YYYY-MM-DD, included. Default: today.","schema":{"description":"Last day (UTC), YYYY-MM-DD, included. Default: today.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}},{"name":"platformSetId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}],"responses":{"200":{"description":"Analytics overview","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsOverview"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/followers":{"get":{"operationId":"analytics_followers","summary":"Follower history","description":"Follower count per account with one daily snapshot per day between `from` and `to` (UTC days, default the last 30). History starts when Ampost first read the account; a day without a snapshot is missing. Analytics cover Facebook Pages, Instagram, Threads, TikTok, Bluesky, YouTube and Pinterest accounts (YouTube and Pinterest: only posts published through Ampost) (LinkedIn once its API access is approved), X accounts that opted in with accounts_set_analytics (Max and Scale; only posts published through Ampost), and Telegram followers (no post metrics). Discord has no analytics: asking for it fails with 422 `ANALYTICS_NOT_AVAILABLE_ON_PLATFORM`. When none of the matching accounts has analytics enabled the call fails with 403 `ANALYTICS_NOT_ENABLED` (its `details.accounts` say why per account). Ampost reads analytics in the background and serves the stored numbers: each account about hourly (daily on the Free plan), a post's metrics hourly in its first 48 hours, every 6 hours up to 14 days and daily up to 90 days. X posts are read daily in their first 3 days and weekly up to 29 days, which costs the plan's X units. Meta itself can lag 24-48 hours. `syncedAt` says when each number was read.\n\nMCP tool: `analytics_followers`. Key scope: `analytics:read`.","tags":["analytics"],"security":[{"apiKey":["analytics:read"]}],"parameters":[{"name":"from","in":"query","required":false,"description":"First day (UTC), YYYY-MM-DD. Default: 29 days before `to`. At most 90 days with `to`.","schema":{"description":"First day (UTC), YYYY-MM-DD. Default: 29 days before `to`. At most 90 days with `to`.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"to","in":"query","required":false,"description":"Last day (UTC), YYYY-MM-DD, included. Default: today.","schema":{"description":"Last day (UTC), YYYY-MM-DD, included. Default: today.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}},{"name":"platformSetId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Follower history","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsFollowersList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/endpoints":{"get":{"operationId":"webhooks_list","summary":"List webhooks","description":"List your webhooks, oldest first. Secrets show only as `secretPreview`. Webhooks see every platform set, so keys restricted to some sets get 403 PLATFORM_SET_NOT_ALLOWED.\n\nMCP tool: `webhooks_list`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List webhooks","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"webhooks_create","summary":"Create a webhook","description":"Send events to an https URL. Ampost POSTs each event as JSON, signed with the webhook's secret (`Ampost-Signature`), and retries a failed delivery 7 times (1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h). After 5 deliveries in a row fail all retries the webhook is turned off. At most 10 webhooks. The response is the only one with the full `secret`: store it now. Revoking the key or app that created the webhook turns it off. Events: post.scheduled, post.unscheduled, post.discarded, post.published, post.partial, post.failed, post.platform.published, post.platform.failed, post.platform.deleted, post.platform.edited, account.connected, account.disconnected, account.needs_reconnect, analytics.synced. Webhooks see every platform set, so keys restricted to some sets get 403 PLATFORM_SET_NOT_ALLOWED.\n\nMCP tool: `webhooks_create`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Create a webhook","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/endpoints/{webhookId}":{"get":{"operationId":"webhooks_get","summary":"Get a webhook","description":"Get one webhook with its status and failure count. The secret shows only as `secretPreview`. Webhooks see every platform set, so keys restricted to some sets get 403 PLATFORM_SET_NOT_ALLOWED.\n\nMCP tool: `webhooks_get`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}}],"responses":{"200":{"description":"Get a webhook","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"webhooks_update","summary":"Update a webhook","description":"Change a webhook's URL, events or description, turn it on or off, or rotate its secret (the response then has the new `secret`, the only time it is shown). While a webhook is off no events are queued for it. Turning it back on resets its failure count; events it missed are not sent, so resend the ones you need with webhooks_redeliver. A webhook turned off because its key or app was revoked (`disabledReason: \"key_revoked\"`) can only be turned on in the dashboard. Changing the URL or rotating the secret ties the webhook to the calling key or app.\n\nMCP tool: `webhooks_update`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Update a webhook","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"webhooks_delete","summary":"Delete a webhook","description":"Delete a webhook and its delivery log. Pending deliveries are not sent.\n\nMCP tool: `webhooks_delete`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}}],"responses":{"200":{"description":"Delete a webhook","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deleted"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/endpoints/{webhookId}/test":{"post":{"operationId":"webhooks_test","summary":"Send a test event","description":"Send a signed `webhook.test` event to the webhook now, also when it is turned off, and return the delivery with your URL's response. One attempt, no retries.\n\nMCP tool: `webhooks_test`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}}],"responses":{"200":{"description":"Send a test event","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/endpoints/{webhookId}/deliveries":{"get":{"operationId":"webhooks_deliveries_list","summary":"List webhook deliveries","description":"The webhook's delivery log, newest first: each event sent, its status, attempts, and the last response code and body. Kept for 30 days.\n\nMCP tool: `webhooks_deliveries_list`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}},{"name":"limit","in":"query","required":false,"description":"Page size, 1-100. Default 20.","schema":{"default":20,"description":"Page size, 1-100. Default 20.","type":"integer","minimum":1,"maximum":100}},{"name":"offset","in":"query","required":false,"description":"Number of items to skip. Default 0.","schema":{"default":0,"description":"Number of items to skip. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"List webhook deliveries","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryList"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/endpoints/{webhookId}/deliveries/{deliveryId}/redeliver":{"post":{"operationId":"webhooks_redeliver","summary":"Redeliver an event","description":"Send a past delivery's event again now, with the same event id and body, as a new delivery (one attempt, also when the webhook is turned off). Returns the new delivery with your URL's response.\n\nMCP tool: `webhooks_redeliver`. Key scope: `webhooks:write`.","tags":["webhooks"],"security":[{"apiKey":["webhooks:write"]}],"parameters":[{"name":"webhookId","in":"path","required":true,"description":"Webhook id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Webhook id"}},{"name":"deliveryId","in":"path","required":true,"description":"Delivery id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Delivery id"}}],"responses":{"200":{"description":"Redeliver an event","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/docs/search":{"get":{"operationId":"docs_search","summary":"Search the docs","description":"Search the Ampost docs (`/docs`, `/docs/mcp` and `/llms-full.txt`) for a question such as \"schedule a post to instagram\". Returns the best matching sections, each with its title, a short excerpt and its URL. Any valid key may call it.\n\nMCP tool: `docs_search`. Key scope: none (any key).","tags":["docs"],"security":[{"apiKey":[]}],"parameters":[{"name":"query","in":"query","required":true,"description":"What you want to know, in plain words, e.g. \"schedule a post to instagram\".","schema":{"type":"string","minLength":1,"maxLength":200,"description":"What you want to know, in plain words, e.g. \"schedule a post to instagram\"."}},{"name":"limit","in":"query","required":false,"description":"Number of sections, 1-20. Default 5.","schema":{"default":5,"description":"Number of sections, 1-20. Default 5.","type":"integer","minimum":1,"maximum":20}}],"responses":{"200":{"description":"Search the docs","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocsSearchResults"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/feedback":{"post":{"operationId":"feedback_submit","summary":"Report a bug or suggest a change","description":"Send the Ampost team a bug report or a suggestion. When an Ampost call fails in a way you can't explain or fix, report it with the `request` you sent (method, path or tool, body) and the `error` you got (status, code, message, `X-Request-Id`). Ampost adds the user's plan and connected accounts with their health. Fields named like secrets and Ampost keys in strings are removed; don't send credentials. Any valid key may call it; at most 10 reports an hour.\n\nMCP tool: `feedback_submit`. Key scope: none (any key).","tags":["feedback"],"security":[{"apiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first request still runs, 409 `IDEMPOTENCY_REQUEST_IN_PROGRESS`. Only successful responses are kept (24 hours); after an error the same key can be retried.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$","description":"Idempotency key (1-255 visible ASCII characters, for example a UUID). A retry with the same key and arguments within 24 hours returns the first result instead of running again. Send a new key for each new action."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["bug","suggestion"],"description":"`bug` for something that went wrong, `suggestion` for a change you want"},"message":{"type":"string","minLength":1,"maxLength":5000,"description":"What happened and what you expected, or what you want changed. At most 5000 characters."},"route":{"description":"The dashboard page, or the API path or MCP tool the report is about","type":"string","maxLength":500},"request":{"type":"object","properties":{"method":{"description":"HTTP method, or `MCP` for a tool call","type":"string","maxLength":10},"path":{"description":"REST path, or the MCP tool name","type":"string","maxLength":500},"requestId":{"type":"string","maxLength":128,"description":"The `X-Request-Id` of the response"},"body":{"description":"The JSON body or tool arguments you sent. Leave out API keys and tokens; Ampost removes fields named like secrets."}},"additionalProperties":false,"description":"The request that failed, as you sent it"},"error":{"type":"object","properties":{"status":{"description":"HTTP status","type":"integer","minimum":100,"maximum":599},"code":{"description":"`error.code` from the response","type":"string","maxLength":100},"message":{"description":"`error.message` from the response","type":"string","maxLength":2000},"requestId":{"type":"string","maxLength":128,"description":"The `X-Request-Id` of the response"}},"additionalProperties":false,"description":"The error Ampost answered"},"recentRequests":{"description":"The dashboard's last API calls; the dashboard fills it in","maxItems":20,"type":"array","items":{"type":"object","properties":{"method":{"type":"string","maxLength":10},"path":{"type":"string","maxLength":500},"status":{"anyOf":[{"type":"integer","minimum":100,"maximum":599},{"type":"null"}],"description":"Null when the request got no response"},"requestId":{"anyOf":[{"type":"string","maxLength":128,"description":"The `X-Request-Id` of the response"},{"type":"null"}]},"errorCode":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"errorMessage":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["method","path","status","requestId","errorCode","errorMessage","at"],"additionalProperties":false}},"browser":{"description":"The browser's user agent; the dashboard fills it in","type":"string","maxLength":500},"screenshot":{"description":"Optional PNG or JPEG, base64 (a `data:` URL is fine). Ampost re-encodes it as JPEG.","type":"string","maxLength":2000000}},"required":["kind","message"],"additionalProperties":false}}}},"responses":{"201":{"description":"Report a bug or suggest a change","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"`true` when this is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackReceipt"}}}},"429":{"description":"`RATE_LIMITED` (the operation's bucket is empty) or `QUOTA_EXCEEDED` (the monthly post quota is used up). `details.retryAfterSeconds` matches `Retry-After`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Size of the operation's token bucket: requests allowed at once, refilled at this many per window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests allowed right now (tokens left in the bucket)","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"When the bucket is full again, in Unix seconds","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before the next request can pass","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Error. The body is `{ error: { code, message, details? } }`.","headers":{"X-Request-Id":{"description":"Id of this request. A valid incoming `X-Request-Id` (8-128 of `A-Z a-z 0-9 . _ : -`) is echoed, otherwise one is generated. Quote it when you contact support.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An Ampost API key from Settings > API keys. Each operation needs one scope (its `security` entry); a key without it gets 403 `INSUFFICIENT_SCOPE`.\nA key restricted to platform sets sees only those sets; writes to other sets get 403 `PLATFORM_SET_NOT_ALLOWED`. Scopes:\n- `posts:read`: List and read posts and posting queues, and read platform rules\n- `posts:write`: Create, change, publish, retry, delete and import posts; edit posting queues\n- `accounts:read`: List and read accounts, platform sets and connection requests\n- `accounts:write`: Connect and disconnect accounts; create, rename and delete platform sets\n- `media:write`: Upload media for posts\n- `analytics:read`: Read post metrics, account overviews and follower history\n- `webhooks:write`: Create, change, test and delete webhooks, read their delivery logs, and redeliver events"}},"schemas":{"Pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total number of matching items"},"hasMore":{"type":"boolean","description":"True when another page exists after this one"}},"required":["limit","offset","total","hasMore"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable error code"},"message":{"type":"string","description":"Human-readable explanation"},"details":{"description":"Extra context, for example the invalid field or the validation issues","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","message"]}},"required":["error"]},"PostOptions":{"type":"object","properties":{"instagram":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"placement":{"description":"Where the post appears. Allowed values depend on the media; see `placements` in GET /api/platforms. When omitted: one image is `feed`, 2+ images are `carousel`, one video is `reel`. A `story` disappears after 24 hours.","type":"string","enum":["feed","story","reel","carousel"]}},"additionalProperties":false},"facebook":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"placement":{"description":"Where the post appears. Allowed values depend on the media; see `placements` in GET /api/platforms. When omitted: `feed`. A `story` disappears after 24 hours.","type":"string","enum":["feed","story","reel"]}},"additionalProperties":false},"linkedin":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"visibility":{"description":"Who can see the post. Default PUBLIC.","type":"string","enum":["PUBLIC","CONNECTIONS"]},"isReshareDisabledByAuthor":{"description":"Stop others from resharing the post.","type":"boolean"},"articleTitle":{"description":"Link preview title. Requires `linkUrl`.","type":"string"},"articleDescription":{"description":"Link preview description. Requires `linkUrl`.","type":"string"},"videoTitle":{"description":"Video title. Requires a video.","type":"string"}},"additionalProperties":false},"tiktok":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"privacyLevel":{"description":"Must be one of the creator's allowed levels. Default SELF_ONLY when the creator allows it.","type":"string","enum":["PUBLIC_TO_EVERYONE","MUTUAL_FOLLOW_FRIENDS","FOLLOWER_OF_CREATOR","SELF_ONLY"]},"disableComment":{"type":"boolean"},"disableDuet":{"description":"Video posts only.","type":"boolean"},"disableStitch":{"description":"Video posts only.","type":"boolean"},"videoCoverTimestampMs":{"description":"Video frame used as the cover, in milliseconds.","type":"integer","minimum":0,"maximum":9007199254740991},"photoCoverIndex":{"description":"Index of the photo used as the cover. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991},"autoAddMusic":{"description":"Photo posts only.","type":"boolean"},"brandContentToggle":{"description":"Paid partnership disclosure.","type":"boolean"},"brandOrganicToggle":{"description":"Promotes the creator's own business.","type":"boolean"},"isAigc":{"description":"Content is AI-generated.","type":"boolean"}},"additionalProperties":false},"threads":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},"twitter":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},"discord":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."}},"additionalProperties":false},"telegram":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."}},"additionalProperties":false},"bluesky":{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},"youtube":{"type":"object","properties":{"text":{"description":"Video description for YouTube instead of the post's `text`.","type":"string"},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"title":{"description":"Video title, up to 100 characters, no `<` or `>`. The post's text becomes the description. When omitted: the text's first line, cut to 100 characters.","type":"string","maxLength":100},"privacyStatus":{"description":"Who can watch the video. Default `public`. Until Ampost's Google project passes YouTube's API audit, YouTube makes every upload `private`.","type":"string","enum":["public","unlisted","private"]},"madeForKids":{"description":"Required for YouTube: whether the video is made for kids (COPPA; YouTube's `selfDeclaredMadeForKids`). Made-for-kids videos take no comments, so no first comment either.","type":"boolean"},"tags":{"description":"Video tags; together at most 500 characters.","type":"array","items":{"type":"string","minLength":1}},"categoryId":{"description":"YouTube video category id, e.g. `22` (People & Blogs, the default) or `28` (Science & Technology).","type":"string","pattern":"^[0-9]+$"},"playlistId":{"description":"Adds the video to this playlist of the channel after upload. A refused add leaves the video published and is reported in `apiResponse.warnings`.","type":"string","minLength":1},"notifySubscribers":{"description":"Notify the channel's subscribers. Default true.","type":"boolean"},"containsSyntheticMedia":{"description":"The video has realistic altered or synthetic (AI-generated) content.","type":"boolean"}},"additionalProperties":false},"pinterest":{"type":"object","properties":{"text":{"description":"Pin description for Pinterest instead of the post's `text`.","type":"string"},"boardId":{"description":"The board to save the Pin to. When omitted: the account's default board (accounts_set_board). See accounts_list_boards for the ids.","type":"string","pattern":"^[0-9]+$"},"title":{"description":"Pin title, up to 100 characters.","type":"string","maxLength":100}},"additionalProperties":false}},"additionalProperties":false,"description":"Per-platform options keyed by platform. Every platform accepts `text`, and the platforms that take a first comment accept `firstComment`; see GET /api/platforms for the rest."},"PostOptionsUpdate":{"type":"object","properties":{"instagram":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"placement":{"description":"Where the post appears. Allowed values depend on the media; see `placements` in GET /api/platforms. When omitted: one image is `feed`, 2+ images are `carousel`, one video is `reel`. A `story` disappears after 24 hours.","type":"string","enum":["feed","story","reel","carousel"]}},"additionalProperties":false},{"type":"null"}]},"facebook":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"placement":{"description":"Where the post appears. Allowed values depend on the media; see `placements` in GET /api/platforms. When omitted: `feed`. A `story` disappears after 24 hours.","type":"string","enum":["feed","story","reel"]}},"additionalProperties":false},{"type":"null"}]},"linkedin":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"visibility":{"description":"Who can see the post. Default PUBLIC.","type":"string","enum":["PUBLIC","CONNECTIONS"]},"isReshareDisabledByAuthor":{"description":"Stop others from resharing the post.","type":"boolean"},"articleTitle":{"description":"Link preview title. Requires `linkUrl`.","type":"string"},"articleDescription":{"description":"Link preview description. Requires `linkUrl`.","type":"string"},"videoTitle":{"description":"Video title. Requires a video.","type":"string"}},"additionalProperties":false},{"type":"null"}]},"tiktok":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"privacyLevel":{"description":"Must be one of the creator's allowed levels. Default SELF_ONLY when the creator allows it.","type":"string","enum":["PUBLIC_TO_EVERYONE","MUTUAL_FOLLOW_FRIENDS","FOLLOWER_OF_CREATOR","SELF_ONLY"]},"disableComment":{"type":"boolean"},"disableDuet":{"description":"Video posts only.","type":"boolean"},"disableStitch":{"description":"Video posts only.","type":"boolean"},"videoCoverTimestampMs":{"description":"Video frame used as the cover, in milliseconds.","type":"integer","minimum":0,"maximum":9007199254740991},"photoCoverIndex":{"description":"Index of the photo used as the cover. Default 0.","type":"integer","minimum":0,"maximum":9007199254740991},"autoAddMusic":{"description":"Photo posts only.","type":"boolean"},"brandContentToggle":{"description":"Paid partnership disclosure.","type":"boolean"},"brandOrganicToggle":{"description":"Promotes the creator's own business.","type":"boolean"},"isAigc":{"description":"Content is AI-generated.","type":"boolean"}},"additionalProperties":false},{"type":"null"}]},"threads":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},{"type":"null"}]},"twitter":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},{"type":"null"}]},"discord":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."}},"additionalProperties":false},{"type":"null"}]},"telegram":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."}},"additionalProperties":false},{"type":"null"}]},"bluesky":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text for this platform instead of the post's `text`."},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."}},"additionalProperties":false},{"type":"null"}]},"youtube":{"anyOf":[{"type":"object","properties":{"text":{"description":"Video description for YouTube instead of the post's `text`.","type":"string"},"firstComment":{"type":"string","description":"First comment for this platform instead of the post's `firstComment`; `\"\"` posts none here."},"title":{"description":"Video title, up to 100 characters, no `<` or `>`. The post's text becomes the description. When omitted: the text's first line, cut to 100 characters.","type":"string","maxLength":100},"privacyStatus":{"description":"Who can watch the video. Default `public`. Until Ampost's Google project passes YouTube's API audit, YouTube makes every upload `private`.","type":"string","enum":["public","unlisted","private"]},"madeForKids":{"description":"Required for YouTube: whether the video is made for kids (COPPA; YouTube's `selfDeclaredMadeForKids`). Made-for-kids videos take no comments, so no first comment either.","type":"boolean"},"tags":{"description":"Video tags; together at most 500 characters.","type":"array","items":{"type":"string","minLength":1}},"categoryId":{"description":"YouTube video category id, e.g. `22` (People & Blogs, the default) or `28` (Science & Technology).","type":"string","pattern":"^[0-9]+$"},"playlistId":{"description":"Adds the video to this playlist of the channel after upload. A refused add leaves the video published and is reported in `apiResponse.warnings`.","type":"string","minLength":1},"notifySubscribers":{"description":"Notify the channel's subscribers. Default true.","type":"boolean"},"containsSyntheticMedia":{"description":"The video has realistic altered or synthetic (AI-generated) content.","type":"boolean"}},"additionalProperties":false},{"type":"null"}]},"pinterest":{"anyOf":[{"type":"object","properties":{"text":{"description":"Pin description for Pinterest instead of the post's `text`.","type":"string"},"boardId":{"description":"The board to save the Pin to. When omitted: the account's default board (accounts_set_board). See accounts_list_boards for the ids.","type":"string","pattern":"^[0-9]+$"},"title":{"description":"Pin title, up to 100 characters.","type":"string","maxLength":100}},"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false,"description":"Per-platform options to change. Each platform key you send replaces that platform's options as a whole (send every field you want to keep, e.g. both `text` and `placement`); `null` removes them. Platforms you leave out keep their options."},"Platform":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"name":{"type":"string"},"text":{"type":"object","properties":{"maxLength":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Maximum characters of the effective text"}},"required":["maxLength"]},"link":{"type":"object","properties":{"supported":{"type":"boolean","description":"False when the platform ignores `linkUrl`"}},"required":["supported"]},"scheduling":{"type":"object","properties":{"supported":{"type":"boolean"}},"required":["supported"]},"unpublish":{"type":"object","properties":{"supported":{"type":"boolean","description":"Whether posts_unpublish can delete a published post on this platform"}},"required":["supported"]},"editPublished":{"type":"object","properties":{"supported":{"type":"boolean","description":"Whether posts_edit_published can change a published post's text on this platform"}},"required":["supported"]},"firstComment":{"type":"object","properties":{"supported":{"type":"boolean","description":"Whether Ampost can post `firstComment` on this platform's new posts"},"maxLength":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Maximum characters of the first comment, or null when unsupported"}},"required":["supported","maxLength"]},"media":{"type":"object","properties":{"required":{"type":"boolean","description":"True when the platform rejects text-only posts"},"types":{"type":"array","items":{"type":"string","enum":["image","video"],"description":"Media kind"}},"maxItems":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maxImages":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maxVideos":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"mixedTypes":{"type":"boolean","description":"Whether images and videos can be combined"},"maxImageSizeBytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"maxVideoSizeBytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"maxVideoDurationSeconds":{"anyOf":[{"type":"number"},{"type":"null"}]},"mimeTypes":{"anyOf":[{"type":"object","properties":{"image":{"type":"array","items":{"type":"string"}},"video":{"type":"array","items":{"type":"string"}}},"required":["image","video"]},{"type":"null"}],"description":"Accepted MIME types, or null when any uploadable type is accepted"},"requiredFields":{"type":"object","properties":{"image":{"type":"array","items":{"type":"string"}},"video":{"type":"array","items":{"type":"string"}}},"required":["image","video"],"description":"Media metadata the platform needs, by media type"},"dimensions":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video"],"description":"Media kind"},"placement":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The placement the rule applies to, or null for every placement"},"minWidth":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"maxWidth":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"minHeight":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"maxHeight":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"aspectRatio":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Required width:height, e.g. \"9:16\", or null for any"}},"required":["type","placement","minWidth","maxWidth","minHeight","maxHeight","aspectRatio"]},"description":"Pixel size and aspect ratio rules, in px; null means no limit. Media that breaks one is rejected when the post is created. Empty when Ampost checks none."}},"required":["required","types","maxItems","maxImages","maxVideos","mixedTypes","maxImageSizeBytes","maxVideoSizeBytes","maxVideoDurationSeconds","mimeTypes","requiredFields","dimensions"]},"placements":{"anyOf":[{"type":"object","properties":{"values":{"type":"array","items":{"type":"string"}},"byMediaShape":{"type":"object","properties":{"none":{"type":"array","items":{"type":"string"}},"single-image":{"type":"array","items":{"type":"string"}},"multi-image":{"type":"array","items":{"type":"string"}},"single-video":{"type":"array","items":{"type":"string"}}},"required":["none","single-image","multi-image","single-video"]},"defaultByMediaShape":{"type":"object","properties":{"none":{"anyOf":[{"type":"string"},{"type":"null"}]},"single-image":{"anyOf":[{"type":"string"},{"type":"null"}]},"multi-image":{"anyOf":[{"type":"string"},{"type":"null"}]},"single-video":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["none","single-image","multi-image","single-video"]}},"required":["values","byMediaShape","defaultByMediaShape"]},{"type":"null"}],"description":"Placement choices by media shape, or null when the platform has no placements"},"options":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"JSON Schema of `options.<platform>`"}},"required":["platform","name","text","link","scheduling","unpublish","editPublished","firstComment","media","placements","options"]},"PlatformMetadata":{"type":"object","properties":{"displayName":{"description":"LinkedIn, Instagram, Threads, X, Bluesky, Pinterest: the profile's display name","type":"string"},"locale":{"description":"LinkedIn: the member's locale","type":"string"},"organizationPostingEnabled":{"description":"LinkedIn: whether posting as a Company Page is enabled","type":"boolean"},"accountType":{"description":"Instagram: the account type, for example BUSINESS or MEDIA_CREATOR. Pinterest: BUSINESS or PINNER","type":"string"},"pageId":{"description":"Facebook: the Page id","type":"string"},"pageName":{"description":"Facebook: the Page name","type":"string"},"creatorNickname":{"description":"TikTok: the creator's nickname","type":"string"},"privacyLevelOptions":{"description":"TikTok: the privacy levels the creator allows; options.tiktok.privacyLevel must be one of them","type":"array","items":{"type":"string"}},"commentDisabled":{"description":"TikTok: comments are off for this creator","type":"boolean"},"duetDisabled":{"description":"TikTok: duets are off for this creator","type":"boolean"},"stitchDisabled":{"description":"TikTok: stitches are off for this creator","type":"boolean"},"maxVideoPostDurationSec":{"description":"TikTok: the longest video the creator may post, in seconds","type":"number"},"guildName":{"description":"Discord: the server the channel belongs to","type":"string"},"channelId":{"description":"Discord: the channel id messages are posted to","type":"string"},"chatTitle":{"description":"Telegram: the channel or group title","type":"string"},"chatType":{"description":"Telegram: channel, group or supergroup","type":"string"},"botUsername":{"description":"Telegram: the bot that posts, without @","type":"string"},"channelTitle":{"description":"YouTube: the channel's title","type":"string"},"customUrl":{"description":"YouTube: the channel's handle, for example @ampost","type":"string"},"boardId":{"description":"Pinterest: the default board Pins go to (accounts_set_board changes it; options.pinterest.boardId overrides it per post)","type":"string"},"boardName":{"description":"Pinterest: the default board's name","type":"string"}},"description":"Public details captured at connect time; each platform fills only its own fields."},"AccountHealthIssue":{"type":"object","properties":{"code":{"type":"string","description":"`ACCOUNT_REVOKED`: disconnected. `TOKEN_EXPIRED`: the platform login expired and Ampost cannot renew it. `MISSING_SCOPE:<scope>`: a permission needed to publish was not granted, e.g. `MISSING_SCOPE:w_member_social`. `REFRESH_TOKEN_EXPIRING`: the platform login (refresh token) ends within 7 days; after that the account needs a reconnect. `TOKEN_EXPIRING`: the token expires within 7 days and Ampost cannot renew it (no refresh token, or the platform refused the renewal); reconnect before then. `BOARD_NOT_SELECTED` (Pinterest, warning): the account has no default board, so every post needs `options.pinterest.boardId`; pick one with accounts_set_board (no reconnect needed)."},"severity":{"type":"string","enum":["error","warning"],"description":"`error`: the account cannot publish. `warning`: it can publish now but needs attention soon."},"message":{"type":"string","description":"What is wrong and what to do, safe to show to the user"}},"required":["code","severity","message"]},"AccountHealth":{"type":"object","properties":{"canPost":{"type":"boolean","description":"The account can publish now: it is active and has no `error` issue"},"needsReconnect":{"type":"boolean","description":"The account has an issue only a reconnect fixes, now or within 7 days: call accounts_connect with this account's id as `accountId`"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/AccountHealthIssue"},"description":"Empty when the account is healthy"}},"required":["canPost","needsReconnect","issues"],"description":"Whether the account can publish, and why not. Derived from the status, token expiry and granted scopes."},"AccountAnalytics":{"type":"object","properties":{"available":{"type":"boolean","description":"Ampost collects analytics on this platform (not on Discord)"},"optInRequired":{"type":"boolean","description":"Analytics reads cost X units, so the account must opt in with accounts_set_analytics (X on Max and Scale)"},"enabled":{"type":"boolean","description":"Ampost syncs this account's analytics: available, and opted in where required"}},"required":["available","optInRequired","enabled"],"description":"Whether Ampost collects analytics for the account."},"Account":{"type":"object","properties":{"id":{"type":"string"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"platformAccountId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The account's id on the platform"},"username":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","revoked"],"description":"`active` can publish. `revoked` was disconnected and cannot publish until reconnected with accounts_connect."},"scopes":{"type":"array","items":{"type":"string"}},"tokenExpiresAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"tokenHealth":{"type":"string","enum":["healthy","non_expiring","expiring_soon","expired","inactive"],"description":"Whether the account can publish. `healthy`: yes. `non_expiring`: yes, the token does not expire (Facebook Pages). `expiring_soon`: yes, the token expires within 24 hours; Ampost refreshes it before publishing, nothing to do. `expired`: the token has expired; Ampost tries to refresh it before publishing and revokes the account if the platform refuses, so reconnect it if a post fails with an auth error. `inactive`: the account is revoked and cannot publish; reconnect it with accounts_connect (same platform and set), which keeps its id."},"health":{"$ref":"#/components/schemas/AccountHealth"},"platformMetadata":{"$ref":"#/components/schemas/PlatformMetadata"},"analytics":{"$ref":"#/components/schemas/AccountAnalytics"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]}},"required":["id","platform","platformSetId","platformAccountId","username","avatarUrl","status","scopes","tokenExpiresAt","tokenHealth","health","platformMetadata","analytics","createdAt","updatedAt","lastUsedAt"]},"SetAccountAnalyticsRequest":{"type":"object","properties":{"enabled":{"type":"boolean","description":"`true` starts the metered X analytics sync for the account; `false` stops it"}},"required":["enabled"],"additionalProperties":false},"PinterestBoard":{"type":"object","properties":{"id":{"type":"string","description":"Pinterest board id; pass it as `boardId` to accounts_set_board or in `options.pinterest.boardId`"},"name":{"type":"string"},"privacy":{"anyOf":[{"type":"string","enum":["PUBLIC","PROTECTED","SECRET"]},{"type":"null"}],"description":"`SECRET` boards keep their Pins private"},"isDefault":{"type":"boolean","description":"The account's default board, where Pins go without `options.pinterest.boardId`"}},"required":["id","name","privacy","isDefault"]},"PinterestBoardList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PinterestBoard"},"description":"The account's boards (up to 250)"},"defaultBoardId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`null` until a default board is picked"}},"required":["data","defaultBoardId"]},"SetPinterestBoardRequest":{"type":"object","properties":{"boardId":{"description":"An existing board of the account, from accounts_list_boards. Pass this or `newBoardName`","type":"string","minLength":1,"maxLength":64},"newBoardName":{"description":"Creates a public board with this name and makes it the default. Pass this or `boardId`","type":"string","minLength":1,"maxLength":50}},"additionalProperties":false},"DisconnectedAccount":{"type":"object","properties":{"id":{"type":"string"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"platformAccountId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The account's id on the platform"},"username":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["active","revoked"],"description":"`active` can publish. `revoked` was disconnected and cannot publish until reconnected with accounts_connect."},"scopes":{"type":"array","items":{"type":"string"}},"tokenExpiresAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"tokenHealth":{"type":"string","enum":["healthy","non_expiring","expiring_soon","expired","inactive"],"description":"Whether the account can publish. `healthy`: yes. `non_expiring`: yes, the token does not expire (Facebook Pages). `expiring_soon`: yes, the token expires within 24 hours; Ampost refreshes it before publishing, nothing to do. `expired`: the token has expired; Ampost tries to refresh it before publishing and revokes the account if the platform refuses, so reconnect it if a post fails with an auth error. `inactive`: the account is revoked and cannot publish; reconnect it with accounts_connect (same platform and set), which keeps its id."},"health":{"$ref":"#/components/schemas/AccountHealth"},"platformMetadata":{"$ref":"#/components/schemas/PlatformMetadata"},"analytics":{"$ref":"#/components/schemas/AccountAnalytics"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"providerRevoked":{"type":"boolean","description":"Whether the platform confirmed that Ampost's access was revoked in this call. Always `false` for platforms without a revoke endpoint (Instagram, Threads, Telegram, Bluesky, Pinterest); also `false` when another active account still uses the same platform login (Facebook Pages of one user), when the revoke failed, or when the account was already disconnected. When `false`, the user can remove Ampost in the platform's own settings: see `providerAccessSettings`."},"providerAccessSettings":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When `providerRevoked` is `false`: where the user removes Ampost in the platform itself, e.g. \"Instagram: Settings > Website permissions > Apps and websites\". Relay it to the user. `null` when the platform confirmed the revoke."}},"required":["id","platform","platformSetId","platformAccountId","username","avatarUrl","status","scopes","tokenExpiresAt","tokenHealth","health","platformMetadata","analytics","createdAt","updatedAt","lastUsedAt","providerRevoked","providerAccessSettings"]},"AccountList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"PlatformSet":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isDefault":{"type":"boolean"},"accountCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Active accounts in the set: the total of accounts_list with this platformSetId and the default status=active"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","name","isDefault","accountCount","createdAt","updatedAt"]},"PlatformSetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PlatformSet"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"PlatformSetRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":50,"description":"Set name, 1-50 characters"}},"required":["name"],"additionalProperties":false},"Deleted":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"]},"ConnectAccountRequest":{"type":"object","properties":{"platform":{"description":"The platform to connect. Required unless `accountId` is given.","type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"]},"platformSetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Target platform set. Default: your default set, or for a reconnect the account's own set. An active account cannot change sets."},"accountId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Reconnect this existing account (active: refreshes its token and permissions; revoked: reactivates it). The user must sign in to the same platform account, otherwise the request fails with ACCOUNT_MISMATCH and nothing changes."},"expectedUsername":{"type":"string","minLength":1,"maxLength":512,"description":"New connections: the username the user must sign in to, as `username` in accounts_get (Facebook: the Page name). Case and a leading @ are ignored. Otherwise the request fails with ACCOUNT_MISMATCH."},"expectedPlatformAccountId":{"type":"string","minLength":1,"maxLength":512,"description":"New connections: the platform's id of the account the user must sign in to, as `platformAccountId` in accounts_get. Otherwise the request fails with ACCOUNT_MISMATCH."}},"additionalProperties":false},"ConnectRequestCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","const":"pending"},"reconnectAccountId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The account this request reconnects (`accountId` of accounts_connect); null for a new connection"},"expectedPlatformAccountId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The platform account id the user must sign in to: the reconnected account's, or the one passed in; null when any account is accepted"},"expectedUsername":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The username the user must sign in to, or null"},"connectUrl":{"type":"string","format":"uri","description":"Open this in a browser to authorize the account"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"expiresAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","platform","platformSetId","status","reconnectAccountId","expectedPlatformAccountId","expectedUsername","connectUrl","createdAt","expiresAt"],"additionalProperties":false},"ConnectRequest":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["pending","awaiting_selection","connected","failed","expired"]},"accountId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The connected account's id once the status is connected"},"reconnectAccountId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The account this request reconnects (`accountId` of accounts_connect); null for a new connection"},"expectedPlatformAccountId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The platform account id the user must sign in to: the reconnected account's, or the one passed in; null when any account is accepted"},"expectedUsername":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The username the user must sign in to, or null"},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string","enum":["USER_CANCELLED","SUPERSEDED","REQUEST_EXPIRED","API_KEY_REVOKED","PLATFORM_SET_NOT_FOUND","ACCOUNT_LIMIT_REACHED","PLATFORM_ALREADY_CONNECTED","ACCOUNT_ALREADY_CONNECTED","ACCOUNT_MISMATCH","SOCIAL_ACCOUNT_IN_USE","OAUTH_DENIED","REQUIRED_PERMISSIONS_MISSING","CONNECTION_FAILED"],"description":"`USER_CANCELLED`: the user cancelled or declined consent. `SUPERSEDED`: a newer connection request for this platform replaced this one; use the newer link. `REQUIRED_PERMISSIONS_MISSING`: the platform did not grant a permission Ampost needs. `ACCOUNT_MISMATCH`: the user signed in to another account. `SOCIAL_ACCOUNT_IN_USE`: on Free, the social account is in another Ampost workspace or left one less than 30 days ago. `error.message` explains each."},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"expiresAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","platform","platformSetId","status","accountId","reconnectAccountId","expectedPlatformAccountId","expectedUsername","error","createdAt","expiresAt","completedAt","updatedAt"],"additionalProperties":false},"MediaInput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Public https URL Ampost can download. Private, loopback, link-local and internal hosts are rejected."},"type":{"type":"string","enum":["image","video"],"description":"Media kind"},"mimeType":{"description":"MIME type. Inferred from the URL extension when omitted.","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"sizeBytes":{"description":"File size in bytes","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"width":{"description":"Width in pixels","anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"description":"Height in pixels","anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"durationSeconds":{"description":"Video duration in seconds","anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"null"}]},"altText":{"description":"Alt text for accessibility","anyOf":[{"type":"string"},{"type":"null"}]},"thumbnailUrl":{"description":"Thumbnail image URL","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["url","type"],"additionalProperties":false,"description":"A media item at a public URL. Platforms may require metadata: see `media.requiredFields` in GET /api/platforms."},"MediaFileInput":{"type":"object","properties":{"file":{"type":"string","minLength":1,"description":"Name of the multipart form part that holds the file"},"width":{"description":"Width in pixels","anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"height":{"description":"Height in pixels","anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"durationSeconds":{"description":"Video duration in seconds","anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"null"}]},"altText":{"description":"Alt text for accessibility","anyOf":[{"type":"string"},{"type":"null"}]},"thumbnailUrl":{"description":"Thumbnail image URL","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["file"],"additionalProperties":false,"description":"A file uploaded in the same multipart request (the whole request max 4 MB; larger files go through POST /api/media/uploads). Type, MIME type and size come from the file."},"Media":{"type":"object","properties":{"url":{"type":"string"},"type":{"type":"string","enum":["image","video"],"description":"Media kind"},"mimeType":{"type":"string"},"sizeBytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"durationSeconds":{"anyOf":[{"type":"number"},{"type":"null"}]},"altText":{"anyOf":[{"type":"string"},{"type":"null"}]},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["url","type","mimeType","sizeBytes","width","height","durationSeconds","altText","thumbnailUrl"]},"PlatformFirstComment":{"type":"object","properties":{"status":{"type":"string","enum":["pending","published","failed"],"description":"pending: waits for the post to publish; failed: posts_retry with this account retries only the comment"},"commentId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The comment's (or reply's) id on the platform"},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"platformCode":{"anyOf":[{"type":"number"},{"type":"null"}]},"platformSubcode":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["code","message","retryable","platformCode","platformSubcode"]},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["status","commentId","error","updatedAt"]},"PlatformPost":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"accountId":{"type":"string","description":"The connected account the post goes to"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The account's platform set; null once the set is deleted"},"status":{"type":"string","enum":["draft","pending","uploading","processing","publishing","published","failed","cancelled","deleted"],"description":"Status on one platform. `draft`: the post is a draft, nothing will publish until you publish or schedule it. `pending`: waiting for its scheduled time or its turn in the queue. `deleted`: published, then deleted from the platform with posts_unpublish."},"platformPostId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The post's id on the platform"},"publishedUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The text live on the platform after posts_edit_published. Null: the post's text for this platform (`options.<platform>.text`, else `text`)."},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"platformCode":{"anyOf":[{"type":"number"},{"type":"null"}]},"platformSubcode":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["code","message","retryable","platformCode","platformSubcode"]},{"type":"null"}],"description":"The last failure. On a `pending` account with `nextAttemptAt`, the failure Ampost retries automatically."},"warnings":{"type":"array","items":{"type":"string"},"description":"Notes from the platform that did not fail the post, e.g. YouTube made an upload private because Ampost's Google project is not audited yet, or refused the playlist or thumbnail. Empty when there are none."},"attempts":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Publish attempts so far, automatic retries included. posts_retry starts again from 0."},"nextAttemptAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"When Ampost tries this account next: after a retryable failure (backoff, or the platform's rate-limit reset), or when Ampost's own per-account queue spreads a burst of posts. Null when nothing is waiting."},"firstComment":{"anyOf":[{"$ref":"#/components/schemas/PlatformFirstComment"},{"type":"null"}],"description":"The first comment on this account's post; null when there is none. A failed comment leaves the post published."},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["platform","accountId","platformSetId","status","platformPostId","publishedUrl","text","error","warnings","attempts","nextAttemptAt","firstComment","createdAt","updatedAt"]},"PostTarget":{"type":"object","properties":{"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Platform set id; null once the set is deleted"},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"}}},"required":["platformSetId","platforms"]},"Post":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","queued","posting","published","partial","failed","discarded","deleted"],"description":"Post status. `deleted`: every account's post was deleted from its platform (posts_unpublish)."},"targets":{"type":"array","items":{"$ref":"#/components/schemas/PostTarget"},"description":"The platform sets and platforms the post goes to, as in the request"},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"description":"Every platform the post goes to, once each"},"text":{"type":"string"},"firstComment":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comment posted on each new post right after it publishes"},"linkUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"}},"options":{"$ref":"#/components/schemas/PostOptions"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"queuePlatformSetId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The platform set whose queue slot the post holds (`useQueue`); null once it is rescheduled or was not queued"},"source":{"anyOf":[{"type":"string","enum":["api","mcp","dashboard"],"description":"Where the post was created: `api` (REST with an API key), `mcp` (an MCP tool) or `dashboard` (the Ampost app). Null for posts created before sources were recorded."},{"type":"null"}]},"metadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Your own object from posts_create, unchanged. Webhook post events carry it too."},"platformPosts":{"type":"array","items":{"$ref":"#/components/schemas/PlatformPost"}},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","status","targets","platforms","text","firstComment","linkUrl","media","options","scheduledFor","queuePlatformSetId","source","metadata","platformPosts","createdAt","updatedAt"]},"PostList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"PostTargetInput":{"type":"object","properties":{"platformSetId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Platform set id. Default: your default set."},"platforms":{"minItems":1,"type":"array","items":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"description":"Platforms to publish to. Each needs an active account in the platform set."}},"required":["platforms"],"additionalProperties":false,"description":"Platforms of one platform set. Each goes to the set's account for that platform."},"CreatePostRequest":{"type":"object","properties":{"targets":{"minItems":1,"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/PostTargetInput"},"description":"Where the post goes: one entry per platform set (max 10). A set holds one account per platform, so to reach several accounts of one platform (two LinkedIn accounts, several clients' Instagram) list their sets. The post gets one platformPosts entry per account."},"text":{"default":"","type":"string","description":"Post text. Use `options.<platform>.text` to vary it per platform."},"firstComment":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"description":"Comment Ampost posts on each new post right after it publishes (X, Threads and Bluesky: a reply). Every target platform must support it (`firstComment.supported` in GET /api/platforms); use `options.<platform>.firstComment` to set or turn it off (`\"\"`) per platform. A failed comment does not fail the post."},"linkUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Link to attach. Ignored by platforms whose `link.supported` is false."},"media":{"default":[],"maxItems":35,"type":"array","items":{"$ref":"#/components/schemas/MediaInput"}},"options":{"default":{},"$ref":"#/components/schemas/PostOptions"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"Publish time in the future. Null or omitted: the post is a draft (or published now with `publishNow`)."},"publishNow":{"default":false,"description":"Publish right after creating. Cannot be combined with `scheduledFor`.","type":"boolean"},"useQueue":{"default":false,"description":"Schedule the post in the next free slot of its platform set's queue (see queue_get) instead of at `scheduledFor`. Needs exactly one target and a queue with slots. Cannot be combined with `scheduledFor` or `publishNow`.","type":"boolean"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Your own JSON object (max 4096 bytes), such as your ids. Returned on the post and in every webhook post event. Set on create only."}},"required":["targets"],"additionalProperties":false},"CreatePostMultipartData":{"type":"object","properties":{"targets":{"minItems":1,"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/PostTargetInput"},"description":"Where the post goes: one entry per platform set (max 10). A set holds one account per platform, so to reach several accounts of one platform (two LinkedIn accounts, several clients' Instagram) list their sets. The post gets one platformPosts entry per account."},"text":{"default":"","type":"string","description":"Post text. Use `options.<platform>.text` to vary it per platform."},"firstComment":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"description":"Comment Ampost posts on each new post right after it publishes (X, Threads and Bluesky: a reply). Every target platform must support it (`firstComment.supported` in GET /api/platforms); use `options.<platform>.firstComment` to set or turn it off (`\"\"`) per platform. A failed comment does not fail the post."},"linkUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Link to attach. Ignored by platforms whose `link.supported` is false."},"media":{"default":[],"maxItems":35,"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/MediaInput"},{"$ref":"#/components/schemas/MediaFileInput"}]}},"options":{"default":{},"$ref":"#/components/schemas/PostOptions"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"Publish time in the future. Null or omitted: the post is a draft (or published now with `publishNow`)."},"publishNow":{"default":false,"description":"Publish right after creating. Cannot be combined with `scheduledFor`.","type":"boolean"},"useQueue":{"default":false,"description":"Schedule the post in the next free slot of its platform set's queue (see queue_get) instead of at `scheduledFor`. Needs exactly one target and a queue with slots. Cannot be combined with `scheduledFor` or `publishNow`.","type":"boolean"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Your own JSON object (max 4096 bytes), such as your ids. Returned on the post and in every webhook post event. Set on create only."}},"required":["targets"],"additionalProperties":false},"UpdatePostRequest":{"type":"object","properties":{"targets":{"description":"Replaces all targets. Accounts the post keeps also keep their results.","minItems":1,"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/PostTargetInput"}},"text":{"type":"string","description":"Post text. Use `options.<platform>.text` to vary it per platform."},"firstComment":{"description":"New first comment; null removes it","anyOf":[{"type":"string","maxLength":8000},{"type":"null"}]},"linkUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Link to attach. Ignored by platforms whose `link.supported` is false."},"media":{"description":"Replaces all media","maxItems":35,"type":"array","items":{"$ref":"#/components/schemas/MediaInput"}},"options":{"$ref":"#/components/schemas/PostOptionsUpdate"},"scheduledFor":{"description":"New publish time; null turns the post back into a draft","anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]}},"additionalProperties":false,"description":"Fields to change. Omitted fields keep their value. Only draft and scheduled posts can change."},"UnpublishPostRequest":{"type":"object","properties":{"accountIds":{"description":"Accounts to delete the post from (`platformPosts[].accountId`). Default: every account where it is published.","minItems":1,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}},"additionalProperties":false},"EditPublishedPostRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":63206,"description":"The new text. It replaces the text only; media and links stay. Each platform's `text.maxLength` applies."},"accountIds":{"description":"Accounts to edit the post on (`platformPosts[].accountId`). Default: every account where it is published.","minItems":1,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}},"required":["text"],"additionalProperties":false},"RetryPostRequest":{"type":"object","properties":{"accountIds":{"description":"Accounts to retry (`platformPosts[].accountId`). A published account whose `firstComment.status` is failed retries only the comment; other accounts publish again. Default: every failed account and every failed first comment.","minItems":1,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Account id"}}},"additionalProperties":false},"AnalyticsMetrics":{"type":"object","properties":{"views":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Times the content was shown or played. Null when the platform does not report it or has not yet."},"reach":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Unique accounts that saw the content. Null when the platform does not report it or has not yet."},"likes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Likes or reactions. Null when the platform does not report it or has not yet."},"comments":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Comments. Null when the platform does not report it or has not yet."},"shares":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Shares. Null when the platform does not report it or has not yet."},"saves":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Saves (Instagram, X bookmarks). Null when the platform does not report it or has not yet."},"quotes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Quote posts (Threads, Bluesky, X). Per post only; null in the overview sums. Null when the platform does not report it or has not yet."}},"required":["views","reach","likes","comments","shares","saves","quotes"]},"AnalyticsUnavailableAccount":{"type":"object","properties":{"accountId":{"type":"string"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"reason":{"type":"string","enum":["not_available_on_platform","opt_in_required","platform_disabled","page_not_selected","account_inactive"],"description":"`not_available_on_platform`: the platform has no analytics (Discord); Facebook, Instagram, Threads, TikTok, LinkedIn, Bluesky, X, YouTube, Pinterest and Telegram have them. `opt_in_required`: an X account whose analytics are off; X reads cost X units, turn them on with accounts_set_analytics. `platform_disabled`: LinkedIn, until Ampost's LinkedIn app is approved for the Community Management API. `page_not_selected`: the Facebook Page connection predates Page selection; reconnect it. `account_inactive`: the account is disconnected."}},"required":["accountId","platform","platformSetId","reason"]},"AnalyticsPlatformPost":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"accountId":{"type":"string"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"platformPostId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The post's id on the platform"},"publishedUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"contentType":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`text`, `image`, `carousel`, `album`, `video`, `reel` or `unknown`; null when not tracked"},"analyticsStatus":{"type":"string","enum":["available","pending","format_not_enabled","not_tracked","not_published","account_not_enabled","not_available_on_platform"],"description":"`available`: metrics were read. `pending`: tracked, not read yet (the first read follows within the hour). `format_not_enabled`: Ampost cannot read metrics for this format on this account (a media type it cannot classify, or the daily Facebook/Instagram check found the platform does not return them). `not_tracked`: published, but the platform gives no metrics for it (for example Instagram stories). `not_published`: this account did not publish the post. `account_not_enabled`: the account has no analytics (see analytics_overview `unavailableAccounts`). `not_available_on_platform`: the platform reports no per-post metrics (Telegram, Discord)."},"metrics":{"description":"Lifetime totals at `syncedAt`","$ref":"#/components/schemas/AnalyticsMetrics"},"syncedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"When Ampost last read these metrics from the platform"}},"required":["platform","accountId","platformSetId","platformPostId","publishedUrl","publishedAt","contentType","analyticsStatus","metrics","syncedAt"]},"AnalyticsPost":{"type":"object","properties":{"postId":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","queued","posting","published","partial","failed","discarded","deleted"],"description":"Post status. `deleted`: every account's post was deleted from its platform (posts_unpublish)."},"text":{"type":"string"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"platformPosts":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsPlatformPost"},"description":"One entry per account the post went to"}},"required":["postId","status","text","createdAt","platformPosts"]},"AnalyticsPostList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsPost"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"AnalyticsAccountSummary":{"type":"object","properties":{"accountId":{"type":"string"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"username":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts published in the range, also those made outside Ampost"},"followers":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Followers at the last daily snapshot before the range ends; null without a snapshot in the 48 hours before"},"followersChange":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Followers at the end minus at the start of the range; null without a snapshot within 48 hours of both ends"},"metrics":{"description":"Sums over the posts published in the range (lifetime totals of each post)","$ref":"#/components/schemas/AnalyticsMetrics"},"syncState":{"type":"string","enum":["up_to_date","syncing","stale","partial","reconnect_required","off"],"description":"`up_to_date`, `syncing` (first read running), `stale` (older than two hours), `partial` (last read incomplete), `reconnect_required` or `off` (X analytics not turned on; such accounts are listed under `unavailableAccounts` instead)"},"syncedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"When Ampost last read this account's analytics"},"nextSyncAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]}},"required":["accountId","platform","platformSetId","username","posts","followers","followersChange","metrics","syncState","syncedAt","nextSyncAt"]},"AnalyticsOverview":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"totals":{"type":"object","properties":{"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"followers":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Followers at the last daily snapshot before the range ends; null without a snapshot in the 48 hours before"},"followersChange":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Followers at the end minus at the start of the range; null without a snapshot within 48 hours of both ends"},"metrics":{"$ref":"#/components/schemas/AnalyticsMetrics"}},"required":["posts","followers","followersChange","metrics"],"description":"The accounts below added up"},"accounts":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsAccountSummary"}},"unavailableAccounts":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsUnavailableAccount"},"description":"Matching accounts without analytics, and why"}},"required":["from","to","totals","accounts","unavailableAccounts"]},"AnalyticsFollowerPoint":{"type":"object","properties":{"date":{"type":"string","description":"Snapshot day (UTC), YYYY-MM-DD"},"followers":{"anyOf":[{"type":"number"},{"type":"null"}]},"syncedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["date","followers","syncedAt"]},"AnalyticsFollowers":{"type":"object","properties":{"accountId":{"type":"string"},"platform":{"type":"string","enum":["instagram","facebook","linkedin","tiktok","threads","twitter","discord","telegram","bluesky","youtube","pinterest"],"description":"Social platform: instagram, facebook, linkedin, tiktok, threads, twitter, discord, telegram, bluesky, youtube, pinterest"},"platformSetId":{"anyOf":[{"type":"string"},{"type":"null"}]},"username":{"type":"string"},"followers":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Latest follower count before the range ends"},"syncedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"When that count was read"},"totalLikes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Likes across all the account's posts, latest reading (TikTok); null elsewhere"},"totalPosts":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Posts on the account, latest reading (TikTok and YouTube videos, Bluesky and X posts, Pinterest Pins); null elsewhere"},"history":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsFollowerPoint"},"description":"One snapshot per day in the range, oldest first"}},"required":["accountId","platform","platformSetId","username","followers","syncedAt","totalLikes","totalPosts","history"]},"AnalyticsFollowersList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsFollowers"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"CreateMediaUploadRequest":{"type":"object","properties":{"fileName":{"description":"File name for the direct upload, e.g. `launch.mp4`; it becomes the end of the file URL. Default `file`. Files uploaded on the page keep their own names.","type":"string","maxLength":200}},"additionalProperties":false},"MediaUploadLimits":{"type":"object","properties":{"maxFiles":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Most files the upload page accepts"},"maxSizeBytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Largest file, in bytes"},"mimeTypes":{"type":"array","items":{"type":"string"},"description":"Accepted MIME types. Per-platform limits are in platforms_list."}},"required":["maxFiles","maxSizeBytes","mimeTypes"],"additionalProperties":false},"MediaUploadCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","const":"pending"},"uploadPageUrl":{"type":"string","format":"uri","description":"Ampost page where the user picks files in a browser. Show it to the user; the part after `#` is a secret for this upload only."},"uploadUrl":{"type":"string","format":"uri","description":"Direct upload: send one file's bytes as the request body to this URL, for clients that can make HTTP requests."},"method":{"type":"string","const":"PUT","description":"HTTP method for `uploadUrl`"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Headers for `uploadUrl`. Also send `x-content-type` with the file's MIME type."},"limits":{"$ref":"#/components/schemas/MediaUploadLimits"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"expiresAt":{"type":"string","format":"date-time","description":"The page and `uploadUrl` stop accepting files at this time"}},"required":["id","status","uploadPageUrl","uploadUrl","method","headers","limits","createdAt","expiresAt"],"additionalProperties":false},"UploadedMedia":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"type":{"type":"string","enum":["image","video"],"description":"Media kind"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"durationSeconds":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["url","type","mimeType","sizeBytes","width","height","durationSeconds"],"additionalProperties":false,"description":"An uploaded file in the `media[]` item shape: pass it to posts_create as is (add `altText` if you like). Type, size, width, height and duration are read from the file itself; images are re-saved without metadata (EXIF, GPS), so the URL is not the one the file was uploaded to. A video duration the container does not state is null."},"MediaUpload":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["pending","completed","failed","expired"],"description":"`pending`: no files yet. `completed`: `files` are ready. `failed`: the direct upload's file was refused (see `error`); create a new upload. `expired`: the link ran out before an upload, or the unused files were deleted."},"files":{"type":"array","items":{"$ref":"#/components/schemas/UploadedMedia"},"description":"The uploaded files once the status is completed; otherwise empty"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"expiresAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why the file was refused (for example, its bytes are not the declared type); null unless the status is failed"}},"required":["id","status","files","createdAt","expiresAt","completedAt","error"],"additionalProperties":false},"QueueSlot":{"type":"object","properties":{"day":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"description":"Weekday"},"time":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"Wall-clock time in the queue's time zone, HH:MM (24-hour)"}},"required":["day","time"],"additionalProperties":false},"Queue":{"type":"object","properties":{"platformSetId":{"type":"string"},"timezone":{"type":"string","description":"IANA time zone of the slot times"},"slots":{"type":"array","items":{"$ref":"#/components/schemas/QueueSlot"},"description":"Weekly slots, sorted by weekday and time"},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"Null until the queue is first saved"}},"required":["platformSetId","timezone","slots","updatedAt"]},"UpdateQueueRequest":{"type":"object","properties":{"timezone":{"type":"string","description":"IANA time zone the slot times are in, for example Europe/Warsaw. Slots follow its daylight saving changes."},"slots":{"description":"Replaces every slot (max 100); duplicates are merged. An empty list turns the queue off.","maxItems":100,"type":"array","items":{"$ref":"#/components/schemas/QueueSlot"}}},"additionalProperties":false,"description":"Fields to change. Omitted fields keep their value; a new queue starts in UTC with no slots."},"QueuePreview":{"type":"object","properties":{"platformSetId":{"type":"string"},"timezone":{"type":"string"},"slots":{"type":"array","items":{"type":"object","properties":{"scheduledFor":{"type":"string","format":"date-time","description":"The slot's time"},"postId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The queued post in the slot; null when free"}},"required":["scheduledFor","postId"]}}},"required":["platformSetId","timezone","slots"]},"PlatformList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Platform"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"ImportPostsCsvRequest":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":4194304,"description":"The CSV text: a header row, then one post per row. Columns: `text`, `platforms`, `platformSetId`, `accountIds`, `scheduledFor`, `useQueue`, `linkUrl`, `firstComment`, `media` and `text_<platform>` (per-platform text, such as `text_linkedin`). Each row needs `platforms` (with an optional `platformSetId`; default: your default set) or `accountIds`. List cells separate items with spaces. Unknown columns are skipped with a warning."},"dryRun":{"default":false,"description":"Check every row like posts_create does without creating anything. `valid` rows would be created.","type":"boolean"}},"required":["csv"],"additionalProperties":false},"ImportRowResult":{"type":"object","properties":{"row":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Row number in the file; the header is row 1, as in a spreadsheet"},"status":{"type":"string","enum":["valid","created","error"],"description":"`valid`: the dry run found no error. `created`: the post was created. `error`: see `errors`; nothing was created."},"postId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The created post (`created` only)"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}],"description":"When the post publishes. For `useQueue` the queue slot it takes (a dry run shows the slot it would take); null for a draft."},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Error code, as posts_create answers it (`VALIDATION_FAILED`, `PLATFORM_NOT_CONNECTED`, ...)"},"message":{"type":"string"},"column":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The column the error is about, when it is one column"}},"required":["code","message","column"]}}},"required":["row","status","postId","scheduledFor","errors"]},"ImportPostsCsvResult":{"type":"object","properties":{"dryRun":{"type":"boolean"},"summary":{"type":"object","properties":{"rows":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Rows read, blank rows left out"},"valid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Rows the dry run found no error in"},"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts created"},"errors":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Rows with errors"}},"required":["rows","valid","created","errors"]},"warnings":{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"message":{"type":"string"}},"required":["column","message"]},"description":"Problems that did not stop the import, such as unknown columns"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ImportRowResult"},"description":"One result per row, in file order"}},"required":["dryRun","summary","warnings","rows"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"events":{"type":"array","items":{"type":"string","enum":["post.scheduled","post.unscheduled","post.discarded","post.published","post.partial","post.failed","post.platform.published","post.platform.failed","post.platform.deleted","post.platform.edited","account.connected","account.disconnected","account.needs_reconnect","analytics.synced"],"description":"An event type. See the Webhooks section of the docs for each event's `data`."}},"secret":{"description":"Signing secret (`whsec_...`). Verify `Ampost-Signature` with it. Only in the create response and in an update with `rotateSecret`: store it then. Lost it? Rotate it.","type":"string"},"secretPreview":{"type":"string","description":"`whsec_…` and the secret's last 4 characters, to tell secrets apart"},"enabled":{"type":"boolean","description":"False when you turned the webhook off, or Ampost did"},"disabledReason":{"anyOf":[{"type":"string","enum":["failing","key_revoked"]},{"type":"null"}],"description":"`failing`: turned off by Ampost after deliveries kept failing. Fix the receiver, then set `enabled` to true. `key_revoked`: turned off because the API key or app that created it (or last changed its URL or secret) was revoked, or the app lost `webhooks:write`. Only the account owner can turn it back on, in the Ampost dashboard; the API refuses with `WEBHOOK_KEY_REVOKED`."},"disabledAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"consecutiveFailures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Deliveries in a row that failed after all retries; a success resets it"},"lastDeliveryAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"lastSuccessAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","url","description","events","secretPreview","enabled","disabledReason","disabledAt","consecutiveFailures","lastDeliveryAt","lastSuccessAt","createdAt","updatedAt"]},"WebhookList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"CreateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri","description":"Public https URL that receives the events. Private, loopback, internal and Ampost's own hosts are rejected."},"events":{"minItems":1,"maxItems":14,"type":"array","items":{"type":"string","enum":["post.scheduled","post.unscheduled","post.discarded","post.published","post.partial","post.failed","post.platform.published","post.platform.failed","post.platform.deleted","post.platform.edited","account.connected","account.disconnected","account.needs_reconnect","analytics.synced"],"description":"An event type. See the Webhooks section of the docs for each event's `data`."},"description":"Events to send to this URL"},"description":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Your note for this webhook, at most 200 characters"}},"required":["url","events"],"additionalProperties":false},"UpdateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri","description":"Public https URL that receives the events. Private, loopback, internal and Ampost's own hosts are rejected."},"events":{"minItems":1,"maxItems":14,"type":"array","items":{"type":"string","enum":["post.scheduled","post.unscheduled","post.discarded","post.published","post.partial","post.failed","post.platform.published","post.platform.failed","post.platform.deleted","post.platform.edited","account.connected","account.disconnected","account.needs_reconnect","analytics.synced"],"description":"An event type. See the Webhooks section of the docs for each event's `data`."},"description":"Events to send to this URL"},"description":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Your note for this webhook, at most 200 characters"},"enabled":{"description":"Turn the webhook on or off. Turning it on clears `disabledReason` and the failure count.","type":"boolean"},"rotateSecret":{"description":"True: replace the signing secret. The old one stops working at once.","type":"boolean"}},"additionalProperties":false,"description":"Fields to change. Omitted fields keep their value."},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","description":"Delivery id, sent as `Ampost-Delivery-Id`"},"webhookId":{"type":"string"},"eventId":{"type":"string","description":"Event id, sent as `Ampost-Event-Id`. The same on retries and redeliveries: dedupe on it."},"eventType":{"anyOf":[{"type":"string","enum":["post.scheduled","post.unscheduled","post.discarded","post.published","post.partial","post.failed","post.platform.published","post.platform.failed","post.platform.deleted","post.platform.edited","account.connected","account.disconnected","account.needs_reconnect","analytics.synced"],"description":"An event type. See the Webhooks section of the docs for each event's `data`."},{"type":"string","const":"webhook.test"}]},"status":{"type":"string","enum":["pending","delivering","succeeded","failed"],"description":"`pending`: waiting for its first attempt or a retry (1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h after failures, 8 attempts in all). `delivering`: being sent. `succeeded`: your URL answered 2xx. `failed`: no attempts left."},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maxAttempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 for test events and redeliveries"},"nextAttemptAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"lastAttemptAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},{"type":"null"}]},"responseStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status of the last attempt; null when no response came"},"responseBody":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"First 1 KB of the last response body"},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"durationMs":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"redeliveryOf":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The delivery this one resent"},"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The JSON body sent: `{ id, type, createdAt, data }`"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","webhookId","eventId","eventType","status","attempts","maxAttempts","nextAttemptAt","lastAttemptAt","responseStatus","responseBody","error","durationMs","redeliveryOf","payload","createdAt"]},"WebhookDeliveryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","description":"Event id, also in `Ampost-Event-Id`. Retries and redeliveries keep it: dedupe on it."},"type":{"anyOf":[{"type":"string","enum":["post.scheduled","post.unscheduled","post.discarded","post.published","post.partial","post.failed","post.platform.published","post.platform.failed","post.platform.deleted","post.platform.edited","account.connected","account.disconnected","account.needs_reconnect","analytics.synced"],"description":"An event type. See the Webhooks section of the docs for each event's `data`."},{"type":"string","const":"webhook.test"}]},"createdAt":{"type":"string","format":"date-time","description":"When the event happened"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The event's data; see each event type"}},"required":["id","type","createdAt","data"]},"DocsSearchResult":{"type":"object","properties":{"id":{"type":"string","description":"Section id, e.g. `posts/posts_create`; the public docs MCP's `get_page` returns the whole section"},"title":{"type":"string"},"url":{"type":"string","description":"Where the section is on ampost.io (`/docs`, `/docs/mcp` or `/llms-full.txt`)"},"excerpt":{"type":"string","description":"The passage that matches the query best"}},"required":["id","title","url","excerpt"]},"DocsSearchResults":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DocsSearchResult"},"description":"Best match first"}},"required":["data"]},"FeedbackReceipt":{"type":"object","properties":{"id":{"type":"string","description":"Quote it if you contact support about this report"},"kind":{"type":"string","enum":["bug","suggestion"]},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"attached":{"type":"array","items":{"type":"string"},"description":"The context Ampost added to the report, e.g. `plan`, `accounts`, `request`, `error`, `screenshot`"}},"required":["id","kind","createdAt","attached"]}}}}