{"openapi":"3.0.0","paths":{"/public/v1/upload-link":{"post":{"description":"Mints a link the account holder can open in any browser, signed out, to drop images or videos straight into this workspace media library. Valid for two hours, takes several files. Read back what arrived with GET /upload-link/{id} and attach each file path to a post.","operationId":"createUploadLink","parameters":[],"responses":{"201":{"description":"A browser upload link for this workspace. Hand `url` to the person; read back what they dropped with GET /upload-link/{id}.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The link id, for GET /upload-link/{id}."},"url":{"type":"string","format":"uri","description":"The page to open. Works signed out."},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","url","expiresAt"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Create a browser upload link","tags":["Public API"]}},"/public/v1/upload-link/{id}":{"get":{"description":"The media items that arrived through an upload link so far, oldest first, with the hosted path to attach to a post. `status` is \"empty\" until the first file lands. Scoped to the caller workspace: an id from another workspace finds nothing.","operationId":"getUploadLinkFiles","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"What has arrived through the link so far, oldest first. Attach each `path` to a post. `status` is \"empty\" until the first file lands.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["empty","ready"]},"count":{"type":"integer"},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"The name the person gave the file."},"path":{"type":"string","format":"uri","description":"The hosted URL. This is the post attachment."},"type":{"type":"string","description":"\"image\" or \"video\"."}},"required":["id","name","path","type"]}}},"required":["id","status","count","files"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List the files uploaded through a link","tags":["Public API"]}},"/public/v1/upload":{"post":{"description":"Uploads an image or video (up to 1 GB) into the workspace media library and returns its id and hosted path. Identical bytes are deduplicated server-side, so re-uploading the same asset reuses one row.","operationId":"uploadMedia","parameters":[],"responses":{"201":{"description":"The stored media item. Attach `path` to a post.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"The stored file name."},"originalName":{"type":"string","nullable":true,"description":"The name the file was uploaded under, when one was sent."},"path":{"type":"string","description":"The hosted URL. THIS is what a post attachment takes, not the id.","example":"https://media.posty.hu/iRIB4vSHa0.jpg"},"thumbnail":{"type":"string","nullable":true},"alt":{"type":"string","nullable":true}},"required":["id","name","path"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Upload a media file","tags":["Public API"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"An image or a video, up to 1 GB."}},"required":["file"]}}}}}},"/public/v1/upload-from-url":{"post":{"description":"Fetches a public https URL and stores it in the media library, returning the same shape as /upload. The fetch is SSRF-guarded on every redirect hop: plain http, private, loopback and link-local addresses are refused.","operationId":"uploadMediaFromUrl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"A public https URL of an image or a video. Private, loopback and link-local addresses are refused."}},"required":["url"]}}}},"responses":{"201":{"description":"The stored media item. Attach `path` to a post.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"The stored file name."},"originalName":{"type":"string","nullable":true,"description":"The name the file was uploaded under, when one was sent."},"path":{"type":"string","description":"The hosted URL. THIS is what a post attachment takes, not the id.","example":"https://media.posty.hu/iRIB4vSHa0.jpg"},"thumbnail":{"type":"string","nullable":true},"alt":{"type":"string","nullable":true}},"required":["id","name","path"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Import media from a public URL","tags":["Public API"]}},"/public/v1/find-slot/{id}":{"get":{"description":"Returns the next publication time (ISO 8601, UTC) that fits the posting schedule of one channel. An unknown channel id answers 404.","operationId":"findNextSlot","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The next free publication time, in UTC.","content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string","format":"date-time"}},"required":["date"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Find the next free posting slot","tags":["Public API"]}},"/public/v1/posts":{"get":{"description":"Returns the posts in the requested window with their state, channel and publication time. This is the read half of the calendar.","operationId":"listPosts","parameters":[],"responses":{"200":{"description":"The posts whose publication time falls in the requested window. A key scoped to particular channels sees only those.","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"content":{"type":"string","description":"The post body, as HTML."},"publishDate":{"type":"string","format":"date-time","description":"When it publishes, in UTC."},"state":{"type":"string","enum":["QUEUE","PUBLISHED","ERROR","DRAFT"],"description":"QUEUE is scheduled and waiting; ERROR failed and will not retry itself."},"releaseURL":{"type":"string","nullable":true,"description":"The platform URL, once it has published."},"group":{"type":"string","description":"One editor session posting to several channels shares one group. Deleting by group removes all of them."}},"required":["id","publishDate","state"]}}},"required":["posts"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List posts in a date range","tags":["Public API"]},"post":{"description":"Creates a draft, schedules a post, or publishes immediately, on one or more channels. Sending an existing group id updates that post in place instead of creating a second one. No links on X: links are removed from X posts (every thread entry too) before they are saved, because X charges for every post with a link; a created post that lost links carries `removedLinks` and a `notices` sentence to show the user. TikTok accepts about 15 posts from one account in 24 hours; a post past that is saved with a `notices` sentence, because TikTok will probably refuse it. Each plan includes a monthly number of X posts (each thread entry and the thread finisher count as one); a write past it answers 402 with the limit, the use and the reset date, and drafts still work.","operationId":"createPost","parameters":[],"responses":{"201":{"description":"One entry per channel written. `postId` is what delete and status changes take. An empty array means nothing was created, which a caller should treat as a failure to investigate rather than a success.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"postId":{"type":"string"},"integration":{"type":"string","description":"The channel this row was written for."}},"required":["postId","integration"]}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Create or update a post","tags":["Public API"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["draft","schedule","now","update"],"description":"draft needs posts:draft; schedule, now and update need posts:publish."},"date":{"type":"string","format":"date-time","description":"When to publish, ISO 8601 in UTC."},"shortLink":{"type":"boolean","description":"Shorten the links in the content."},"tags":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}},"required":["value","label"]}},"inter":{"type":"integer","minimum":1,"maximum":365,"description":"Repeat every this many days. Omit for a one-off post."},"order":{"type":"string"},"creationMethod":{"type":"string","enum":["API","CLI"],"description":"Where the post came from. Defaults to API."},"posts":{"type":"array","items":{"type":"object","properties":{"integration":{"type":"object","properties":{"id":{"type":"string","description":"The channel id from GET /integrations."}},"required":["id"]},"value":{"type":"array","items":{"type":"object","properties":{"content":{"type":"string","description":"HTML. Wrap each line in <p>. Allowed tags: h1, h2, h3, u, strong, li, ul, p."},"id":{"type":"string"},"delay":{"type":"number","description":"Minutes to wait before this comment or thread entry."},"image":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The media id from /upload."},"path":{"type":"string","description":"The hosted URL from /upload or /upload-from-url. Must end in .png, .jpg, .jpeg, .gif, .webp or .mp4."},"alt":{"type":"string"},"thumbnail":{"type":"string","format":"uri"}},"required":["id","path"]}}},"required":["content","image"]},"minItems":1,"description":"The first entry is the post. The rest are a thread on X, Threads and Bluesky, and comments on LinkedIn and Facebook."},"group":{"type":"string","description":"An existing group id updates that post in place."},"settings":{"type":"object","additionalProperties":true,"description":"Provider settings. `__type` names the provider; GET /integration-settings/{id} returns the schema for one channel. Required unless type is draft."}},"required":["integration","value"]},"minItems":1,"description":"One entry per channel."}},"required":["type","date","shortLink","tags","posts"]}}}}}},"/public/v1/posts/{id}":{"delete":{"description":"Deletes this one post (one channel) with its thread or comment entries, and stops only its pending publication workflow. The other channels of the same group stay scheduled; use DELETE /posts/group/{group} to delete the whole group. Answers 404 for an unknown, already deleted or other workspace id. A post that already published on the platform is not removed from the platform.","operationId":"deletePost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted. The body is `{ \"error\": true }` for historical reasons and carries no meaning: the status code is the result. A published post cannot be removed from the platform this way.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"boolean"}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Delete one post","tags":["Public API"]}},"/public/v1/posts/group/{group}":{"delete":{"description":"Deletes the whole group: one editor session that went to several channels leaves one post per channel sharing a group, and this removes all of them at once and stops every workflow. To delete only one channel, use DELETE /posts/{id}.","operationId":"deletePostGroup","parameters":[{"name":"group","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted, across every channel of the group. The body is `{ \"error\": true }` and carries no meaning; the status code is the result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"boolean"}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Delete a whole group (every channel)","tags":["Public API"]}},"/public/v1/is-connected":{"get":{"description":"Answers 200 when the presented key or token resolves to a workspace. The cheapest call for a client to verify its configuration at startup.","operationId":"isConnected","parameters":[],"responses":{"200":{"description":"The credential resolves to a workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean","enum":[true]}},"required":["connected"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Check the credential","tags":["Public API"]}},"/public/v1/workspaces":{"get":{"description":"Returns every workspace this credential can act on, with the workspace this request acted on marked `current`. A key that spans several workspaces must send the chosen workspace id in the `showorg` header on every other route; this route works without it.","operationId":"listWorkspaces","parameters":[],"responses":{"200":{"description":"Every workspace this credential can act on. `current` marks the one this request acted on; a key that spans several must send the chosen id in the `showorg` header on every other route.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","description":"The credential owner's role in that workspace, e.g. SUPERADMIN or ADMIN."},"current":{"type":"boolean"}},"required":["id","name","role","current"]}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List workspaces","tags":["Public API"]}},"/public/v1/groups":{"get":{"description":"Returns the workspace customer groups, which are the buckets channels can be filed under.","operationId":"listGroups","parameters":[],"responses":{"200":{"description":"The workspace customer groups.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List customer groups","tags":["Public API"]}},"/public/v1/integrations":{"get":{"description":"Returns every connected channel with its id, name, @handle, platform and whether it is disabled or needs reconnecting. X channels also carry `xQuota` (used, limit, remaining and resetsAt for this month's X posts; when remaining is 0 only drafts can be saved). Channel ids from here are what every other route takes.","operationId":"listChannels","parameters":[{"name":"group","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Every connected channel. Skip the ones whose `disabled` is true: they cannot publish.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The channel id every other route takes."},"name":{"type":"string","description":"The account name as the user knows it."},"identifier":{"type":"string","description":"The platform: facebook, instagram, youtube, x, linkedin, …","example":"youtube"},"picture":{"type":"string","nullable":true},"disabled":{"type":"boolean","description":"A disabled channel cannot publish until it is switched on."},"profile":{"type":"string","nullable":true,"description":"The @handle. Quote it back to a user: it is what separates two same-named accounts."},"customer":{"type":"object","nullable":true,"description":"The customer group this channel is filed under, when any.","properties":{"id":{"type":"string"},"name":{"type":"string"}}}},"required":["id","name","identifier"]}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List connected channels","tags":["Public API"]}},"/public/v1/social/{integration}":{"get":{"description":"Returns the provider authorization URL a human must open to connect or refresh a channel. The consent step cannot be completed by an API client.","operationId":"startChannelConnect","parameters":[{"name":"integration","required":true,"in":"path","schema":{"type":"string"}},{"name":"refresh","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"The provider authorization URL a human must open. An API client cannot complete the consent step itself.","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Begin connecting a channel","tags":["Public API"]}},"/public/v1/notifications":{"get":{"description":"Returns the workspace notification feed, most recent first, paginated.","operationId":"listNotifications","parameters":[],"responses":{"200":{"description":"One page of the workspace notification feed.","content":{"application/json":{"schema":{"type":"object","properties":{"notifications":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"count":{"type":"integer"}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List workspace notifications","tags":["Public API"]}},"/public/v1/integration-settings/{id}":{"get":{"description":"Returns the validation rules, the character limit resolved for that specific account, and the settings schema a post to this channel must satisfy.","operationId":"getChannelSettings","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The rules a post to this channel must satisfy. `settings` is a JSON Schema whose shape differs per provider, which is why it is not described further here.","content":{"application/json":{"schema":{"type":"object","properties":{"output":{"type":"object","properties":{"rules":{"type":"string","description":"Human-readable constraints, e.g. \"YouTube must have one video attachment\"."},"maxLength":{"type":"integer","description":"The character limit resolved for THIS account, not for the platform in general."},"settings":{"type":"object","additionalProperties":true,"description":"JSON Schema for the per-channel settings object."},"tools":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Get one channel settings schema","tags":["Public API"]}},"/public/v1/posts/{id}/missing":{"get":{"description":"Returns the settings and content a post is still missing before it can publish, without attempting to publish it.","operationId":"getPostMissingContent","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"What the post still needs before it can publish. Shape follows the channel, so it is not narrowed here.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Report what a post still needs","tags":["Public API"]}},"/public/v1/posts/{id}/status":{"put":{"description":"Flips one post between DRAFT and QUEUE, starting or terminating its publication workflow to match.","operationId":"changePostStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","schedule"]}},"required":["status"]}}}},"responses":{"200":{"description":"The post after the change.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"content":{"type":"string","description":"The post body, as HTML."},"publishDate":{"type":"string","format":"date-time","description":"When it publishes, in UTC."},"state":{"type":"string","enum":["QUEUE","PUBLISHED","ERROR","DRAFT"],"description":"QUEUE is scheduled and waiting; ERROR failed and will not retry itself."},"releaseURL":{"type":"string","nullable":true,"description":"The platform URL, once it has published."},"group":{"type":"string","description":"One editor session posting to several channels shares one group. Deleting by group removes all of them."}},"required":["id","publishDate","state"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Move a post between draft and scheduled","tags":["Public API"]}},"/public/v1/posts/{id}/release-id":{"put":{"description":"Stores the platform post id and URL for a post published outside Postemi, so the calendar and analytics can find it.","operationId":"updateReleaseId","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The post after the platform id and URL were recorded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"content":{"type":"string","description":"The post body, as HTML."},"publishDate":{"type":"string","format":"date-time","description":"When it publishes, in UTC."},"state":{"type":"string","enum":["QUEUE","PUBLISHED","ERROR","DRAFT"],"description":"QUEUE is scheduled and waiting; ERROR failed and will not retry itself."},"releaseURL":{"type":"string","nullable":true,"description":"The platform URL, once it has published."},"group":{"type":"string","description":"One editor session posting to several channels shares one group. Deleting by group removes all of them."}},"required":["id","publishDate","state"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Record the platform release id","tags":["Public API"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"releaseId":{"type":"string","description":"The post id on the platform."}},"required":["releaseId"]}}}}}},"/public/v1/analytics/{integration}":{"get":{"description":"Returns the metrics the platform exposes for one connected channel over the requested period. Availability differs per platform.","operationId":"getChannelAnalytics","parameters":[{"name":"integration","required":true,"in":"path","schema":{"type":"string"}},{"name":"date","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"The metrics this platform exposes. Every platform reports a different set, so the entries are named but not enumerated: read `label` and `data` rather than expecting a fixed key.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"percentageChange":{"type":"number"},"data":{"type":"array","items":{"type":"object","properties":{"total":{"type":"string"},"date":{"type":"string"}}}}}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Read channel analytics","tags":["Public API"]}},"/public/v1/analytics/post/{postId}":{"get":{"description":"Returns the platform metrics for a single published post.","operationId":"getPostAnalytics","parameters":[{"name":"postId","required":true,"in":"path","schema":{"type":"string"}},{"name":"date","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"The platform metrics for one published post. Same per-platform variation as the channel analytics above.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Read one post analytics","tags":["Public API"]}},"/public/v1/integration-trigger/{id}":{"post":{"description":"Invokes a provider-specific helper on a connected channel, for example listing the boards, subreddits or pages a post can target.","operationId":"triggerChannelTool","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"Whatever the provider tool returns — a board list, a subreddit list, a page list. The shape belongs to the provider, so it is carried through untouched under `output`.","content":{"application/json":{"schema":{"type":"object","properties":{"output":{"additionalProperties":true,"type":"object"}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Call a channel-specific tool","tags":["Public API"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"methodName":{"type":"string","description":"The tool to run, as named in the channel settings schema (GET /integration-settings/{id})."},"data":{"type":"object","additionalProperties":{"type":"string"},"description":"The arguments the tool takes."}},"required":["methodName"]}}}}}},"/public/v1/plans":{"get":{"description":"The four Postemi plans (Basic, Pro, Creator, Team) with monthly and yearly prices in euro, Swiss francs or US dollars (see `localPrices`), the limits that matter (channels, posts per month, X posts per month, team seats, workspaces, API and MCP access, image editor, video templates), the free-trial rule and the tier the workspace is on now. A null limit means unlimited. `teamSeats` counts every person including the payer, so 1 means a single-user plan that cannot invite anyone. Answers for any valid credential, including one whose workspace has no plan with API access yet: this is the route that gets it one. Pass a plan `slug` as `tier` to POST /subscriptions/checkout.","operationId":"getPlans","parameters":[],"responses":{"200":{"description":"The four plans with prices in euro, Swiss francs or US dollars (see `localPrices`), the limits that matter, the trial rule and the tier the workspace is on now.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"currency":{"type":"string","example":"USD"},"pricesIncludeVat":{"type":"boolean"},"billing":{"type":"string"},"trial":{"type":"string"},"trialDays":{"type":"integer","example":7},"trialAvailableHere":{"type":"boolean"},"current":{"type":"object","properties":{"tier":{"type":"string","example":"FREE"},"plan":{"type":"string","example":"Free"},"slug":{"type":"string","nullable":true}},"required":["tier","plan"]},"plans":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string","example":"TEAM"},"plan":{"type":"string","example":"Pro"},"slug":{"type":"string","example":"pro","description":"Pass as `tier` to POST /subscriptions/checkout."},"monthly":{"type":"object","properties":{"amount":{"type":"integer","example":8990},"formatted":{"type":"string","example":"8 990 Ft"}},"required":["amount","formatted"]},"yearly":{"type":"object","properties":{"amount":{"type":"integer","example":89900},"formatted":{"type":"string","example":"89 900 Ft"},"savesPerYear":{"type":"integer"}},"required":["amount","formatted"]},"limits":{"type":"object","additionalProperties":true}},"required":["tier","plan","slug","monthly","yearly","limits"]}}},"required":["currency","trialDays","current","plans"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List plans","tags":["Public API"]}},"/public/v1/subscription":{"get":{"description":"The subscription governing the workspace: `state` (none, trialing, active, past_due, read_only or cancelled), the plan name, the period, when the current period ends, whether the credential owner is the payer, `xPosts` (the X posts used this billing month, the limit and when it resets; thread entries and the thread finisher count), and `pendingCheckout` when a checkout was started in the last 24 hours and not paid. Poll this after the person has paid: the state changes within seconds of the payment.","operationId":"getSubscription","parameters":[],"responses":{"200":{"description":"The subscription governing the workspace, and any checkout that has not been paid or expired.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"state":{"type":"string","enum":["none","trialing","active","past_due","read_only","cancelled"]},"tier":{"type":"string","nullable":true},"plan":{"type":"string","nullable":true},"period":{"type":"string","enum":["MONTHLY","YEARLY"],"nullable":true},"currentPeriodEnd":{"type":"string","format":"date-time","nullable":true},"cancelAt":{"type":"string","format":"date-time","nullable":true},"graceEndsAt":{"type":"string","format":"date-time","nullable":true},"payerIsCaller":{"type":"boolean"},"noPayerYet":{"type":"boolean"},"lifetime":{"type":"boolean"},"pendingCheckout":{"type":"object","nullable":true,"properties":{"checkoutId":{"type":"string"},"checkoutUrl":{"type":"string","format":"uri"},"tier":{"type":"string"},"plan":{"type":"string"},"period":{"type":"string","nullable":true},"startedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}},"apiAndMcpAccess":{"type":"boolean"}},"required":["state","payerIsCaller","apiAndMcpAccess"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Get the subscription","tags":["Public API"]}},"/public/v1/subscriptions/checkout":{"post":{"description":"Creates the same Stripe Managed Payments Checkout Session the Postemi app creates and returns its URL. Nothing is charged by this call: the PERSON opens `checkoutUrl` and pays with their own Link wallet or card. Do not pay with a one-time or agent-issued card; a Postemi subscription renews monthly or yearly and a one-time credential fails at the first renewal. Requires an OAuth token or a full-workspace API key (psty_sa_) whose owner pays for the workspace, or is a workspace owner when nobody pays yet; a scoped key is refused (403). Refused with 409 when the workspace already has a live subscription (plan changes are made in the portal, GET /subscription/portal). After the person says they have paid, confirm with GET /subscription. `apiAndMcpAccess` in the answer says whether the plan opens the rest of the API after the payment: it is false for Basic, and then `note` says what to tell the person before they pay. A key made by POST /signup/complete keeps working only on a plan with API access.","operationId":"createSubscriptionCheckout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSubscribeDto"}}}},"responses":{"201":{"description":"The Stripe Checkout link the PERSON opens to authorise the subscription. Nothing has been charged yet.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["requires_payment"]},"checkoutUrl":{"type":"string","format":"uri"},"checkoutId":{"type":"string","example":"cs_test_…"},"tier":{"type":"string","example":"TEAM"},"plan":{"type":"string","example":"Pro"},"period":{"type":"string","enum":["MONTHLY","YEARLY"]},"amount":{"type":"integer","description":"Forint, VAT included."},"currency":{"type":"string","example":"USD"},"trial":{"type":"boolean"},"trialDays":{"type":"integer"},"expiresAt":{"type":"string","format":"date-time"}},"required":["status","checkoutUrl","checkoutId","tier","plan","period","amount","currency","trial","expiresAt"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Start a subscription (Stripe Checkout link)","tags":["Public API"]}},"/public/v1/subscription/portal":{"get":{"description":"A short-lived link to the Stripe billing portal for the workspace, where the person changes plan, cancels, updates the card on file and downloads invoices. Same credential rule as POST /subscriptions/checkout: an OAuth token or a full-workspace key of the payer; a scoped key is refused. 404 when the workspace has no billing account yet.","operationId":"getSubscriptionPortal","parameters":[],"responses":{"200":{"description":"A short-lived link to the Stripe billing portal.","content":{"application/json":{"schema":{"type":"object","properties":{"portalUrl":{"type":"string","format":"uri"},"note":{"type":"string"}},"required":["portalUrl"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Billing portal link","tags":["Public API"]}},"/public/v1/fotoai/status":{"get":{"description":"Whether the key owner has connected a FotoAI account (fotoai.hu), as whom, and the FotoAI credit balance. When `connected` is false, send the person to `connectUrl` once.","operationId":"getFotoAiStatus","parameters":[],"responses":{"200":{"description":"The key owner's FotoAI connection. When `connected` is false, send the person to `connectUrl` once.","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean","description":"False when this Postemi has no FotoAI client registered."},"connected":{"type":"boolean"},"needsReconnect":{"type":"boolean","description":"FotoAI refused the stored grant; connect again at `connectUrl`."},"connectUrl":{"type":"string","format":"uri"},"email":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"tier":{"type":"string","nullable":true,"description":"The FotoAI plan."},"balanceCredits":{"type":"number","nullable":true},"balanceMillicredits":{"type":"integer","nullable":true},"topupUrl":{"type":"string","nullable":true}},"required":["configured","connected","connectUrl"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"FotoAI connection status","tags":["Public API"]}},"/public/v1/fotoai/models":{"get":{"description":"The FotoAI models the key owner can use, with their parameters (aspect, duration, …), input slots and prices in millicredits (1 credit = 1000). Filter with `category=image|video`.","operationId":"listFotoAiModels","parameters":[{"name":"category","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"FotoAI's catalogue as its partner API v1 returns it: `models[]` with `id`, `name`, `category`, `can_use`, `params[]` (key, default, options), `modes`, `price` (millicredits per config) and `catalog_version`.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"catalog_version":{"type":"string"},"models":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List FotoAI models","tags":["Public API"]}},"/public/v1/fotoai/quote":{"post":{"description":"The exact price in millicredits, the balance, and a `quote_id` valid for 10 minutes. Nothing is spent. `insufficient: true` comes with a `topup_url`.","operationId":"quoteFotoAi","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A model id from GET /fotoai/models.","example":"image.seedream-5-lite"},"prompt":{"type":"string","maxLength":8000},"mode":{"type":"string","description":"t2i, i2i, t2v, i2v … Optional; set from the inputs."},"params":{"type":"object","additionalProperties":true,"description":"Model parameters by key, e.g. { \"aspect\": \"4:5\", \"resolution\": \"2K\" } or { \"duration\": 5 } for video."},"style_id":{"type":"string","description":"A FotoAI style or pack id, instead of or beside `model`."}},"required":["model"]}}}},"responses":{"201":{"description":"The price. Pass `quote_id` (or `millicredits` as `max_millicredits`) to the generation.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"millicredits":{"type":"integer"},"credits":{"type":"number"},"quote_id":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"insufficient":{"type":"boolean"},"available_millicredits":{"type":"integer"},"topup_url":{"type":"string","description":"Only when `insufficient`."}}}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Price a FotoAI generation","tags":["Public API"]}},"/public/v1/fotoai/generations":{"post":{"description":"Spends the key owner's FotoAI credits. Pass the quoted price as `max_millicredits` (or the `quote_id`): FotoAI refuses with PRICE_CHANGED instead of charging more. Send an `idempotency_key` per attempt; a retry returns the same generation. The outputs are imported into this workspace's media library when the generation finishes. Poll GET /fotoai/generations/{id}.","operationId":"createFotoAiGeneration","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A model id from GET /fotoai/models.","example":"image.seedream-5-lite"},"prompt":{"type":"string","maxLength":8000},"mode":{"type":"string","description":"t2i, i2i, t2v, i2v … Optional; set from the inputs."},"params":{"type":"object","additionalProperties":true,"description":"Model parameters by key, e.g. { \"aspect\": \"4:5\", \"resolution\": \"2K\" } or { \"duration\": 5 } for video."},"style_id":{"type":"string","description":"A FotoAI style or pack id, instead of or beside `model`."},"max_millicredits":{"type":"integer","description":"The price ceiling, usually the quoted `millicredits`. FotoAI answers PRICE_CHANGED rather than charge more. This or `quote_id` is required."},"quote_id":{"type":"string","description":"A `quote_id` from /fotoai/quote (10 minutes)."},"idempotency_key":{"type":"string","description":"One per attempt. A retry with the same key returns the same generation."},"reference_media_ids":{"type":"array","maxItems":4,"items":{"type":"string"},"description":"Media ids of this workspace, sent to FotoAI as reference images."}},"required":["model"]}}}},"responses":{"201":{"description":"The generation started. Poll GET /fotoai/generations/{id}.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The generation id (a pack run's group id)."},"status":{"type":"string"},"estimated_seconds":{"type":"integer","nullable":true},"reserved_millicredits":{"type":"integer","nullable":true},"child_ids":{"type":"array","items":{"type":"string"}}},"required":["id","status"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Start a FotoAI generation","tags":["Public API"]},"get":{"description":"The key owner's recent FotoAI generations from every source, newest first, each marked `imported` when it is already in this workspace. Pass `next_cursor` back as `cursor`.","operationId":"listFotoAiGenerations","parameters":[{"name":"cursor","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Newest first. Pass `next_cursor` back as `cursor`.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"model":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"description":"web, partner:posty, api, …"},"created_at":{"type":"string","format":"date-time","nullable":true},"imported":{"type":"boolean","description":"Already in this workspace's media library."}}}},"next_cursor":{"type":"string","nullable":true}},"required":["data"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"List recent FotoAI generations","tags":["Public API"]}},"/public/v1/fotoai/generations/{id}":{"get":{"description":"Status and outputs. For a generation started through Postemi the outputs are imported into the media library once it completes, and `media` lists them: attach each `path` to a post.","operationId":"getFotoAiGeneration","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Status, and once completed the outputs saved in the media library. Attach each `media[].path` to a post.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FotoAiGeneration"}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Get a FotoAI generation","tags":["Public API"]}},"/public/v1/fotoai/generations/{id}/import":{"post":{"description":"Imports the outputs of any of the key owner's FotoAI generations (also ones made on fotoai.hu) into this workspace's media library. Importing twice returns the same media.","operationId":"importFotoAiGeneration","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"The same shape as GET /fotoai/generations/{id}, with the outputs imported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FotoAiGeneration"}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Import a FotoAI generation into the media library","tags":["Public API"]}},"/public/v1/status":{"get":{"description":"Returns the API version, the current server time, and absolute URLs for every machine-readable document Postemi publishes: the OpenAPI spec, the OAuth metadata, the MCP endpoint and the developer documentation. It also states the scopes that exist and how a human obtains a key. Apart from the two sign-up routes (POST /signup/start and /signup/complete), this is the only route that answers without a credential, and it reads no workspace data.","operationId":"getStatus","parameters":[],"responses":{"200":{"description":"The API version, the server clock, and where every machine-readable document lives.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string"},"status":{"type":"string","enum":["ok"]},"version":{"type":"string","example":"v1"},"time":{"type":"string","format":"date-time"},"documentation":{"type":"object","additionalProperties":true},"authentication":{"type":"object","additionalProperties":true},"mcp":{"type":"object","additionalProperties":true},"scopes":{"type":"object","additionalProperties":true},"rateLimits":{"type":"object","additionalProperties":true},"versioning":{"type":"object","additionalProperties":true}},"required":["name","status","version","time"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing, malformed, expired or unknown credential, or the workspace plan does not include API access. Permanent until the credential changes.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this key lacks the scope or the channel this route needs. The body names the missing scope and the key owner's role.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such object in this workspace. Also returned for an object that exists in another workspace, deliberately: an id is not a way to probe for it.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Service status and API discovery (no credential required)","tags":["Public API"],"security":[]}},"/public/v1/signup/start":{"post":{"description":"Sends a six-digit one-time code to the person's e-mail address. Ask the person to read the code to you, then call POST /signup/complete. The answer is the same 202 for every well-formed address, whether or not it already has an account; the code is valid for 10 minutes. A new code can be requested after 60 seconds, at most 5 an hour per address. 503 when the e-mail could not be sent. Accounts created this way have NO free trial: the next step after sign-up is POST /subscriptions/checkout.","operationId":"startSignup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSignupStartDto"}}}},"responses":{"202":{"description":"The code is on its way. The same answer for every well-formed address, whether or not it has an account.","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean","enum":[true]},"expiresInMinutes":{"type":"integer","example":10},"terms":{"type":"string","format":"uri","example":"https://postemi.com/terms"},"privacy":{"type":"string","format":"uri","example":"https://postemi.com/privacy"},"next":{"type":"string"}},"required":["sent","expiresInMinutes","terms","privacy","next"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"The e-mail with the code could not be sent. Retryable: try again in a few minutes. Never a statement about the address.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}}},"summary":"Start an account sign-up: e-mail a one-time code (no credential required)","tags":["Public API"],"security":[]}},"/public/v1/signup/complete":{"post":{"description":"Verifies the code and creates an activated account with one workspace owned by the person, and returns a full-workspace API key (psty_sa_) ONCE: store it, it cannot be shown again. `acceptTerms` must be the literal true, meaning you showed the person the terms (https://postemi.com/terms) and the privacy notice (https://postemi.com/privacy) and they agreed; the consent is recorded with the current versions. The workspace has NO free trial and no plan yet, so the key opens only GET /plans, GET /subscription and POST /subscriptions/checkout until the person pays, and after that only if the plan includes API access (not Basic); follow `next`. 400 for a wrong, expired or used code. 409 when the address already has a Postemi account: the person signs in instead (`postemi auth:login`, or connect over OAuth). 403 when registration is closed.","operationId":"completeSignup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSignupCompleteDto"}}}},"responses":{"201":{"description":"The account and its workspace exist, the person owns the workspace, and `apiKey` is its full-workspace key, shown only this once. No free trial: follow `next` to the checkout.","content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string"},"workspaceName":{"type":"string","example":"Anna Café"},"apiKey":{"type":"string","example":"psty_sa_…","description":"Full-workspace key. Send it as the Authorization header. Returned once and stored hashed."},"apiKeyName":{"type":"string","example":"Agent sign-up 2026-09-23"},"trial":{"type":"boolean","enum":[false]},"next":{"type":"array","items":{"type":"string"}}},"required":["workspaceId","workspaceName","apiKey","trial","next"]}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"400":{"description":"The request body or a parameter did not validate. Permanent: fix the request, do not retry unchanged.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Registration is closed for this address.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"409":{"description":"This e-mail address already has a Postemi account, so no new one was created. Only answered after a correct code. The person signs in instead (`postemi auth:login`, or OAuth).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}}},"429":{"description":"Rate limited. Retryable: wait for the number of seconds in `Retry-After`, or until the instant in `RateLimit-Reset`.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected failure on our side. Retryable with backoff.","headers":{"RateLimit-Limit":{"description":"Requests allowed in the current window for this route.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window. Self-throttle on this.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets. A delta, not a timestamp.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The quota and window, e.g. `60;w=3600`.","schema":{"type":"string"}},"Link":{"description":"RFC 8594 `rel=\"sunset\"` pointer to the deprecation policy. Present on every response; a `Sunset` header appears beside it only once a route is actually being retired.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"summary":"Complete the sign-up: create the account and get an API key (no credential required)","tags":["Public API"],"security":[]}}},"info":{"title":"Postemi API","description":"REST API for Postemi (postemi.com), the social media scheduler: schedule, preview, publish and delete posts across connected channels, upload media, and read analytics.\n\n## Authentication\nSend a per-workspace API key as the whole Authorization header (`Authorization: psty_...`), or an OAuth 2.1 + PKCE access token (`Authorization: Bearer pos_...`) minted for the resource `https://api.postemi.com/public/v1`. Keys are self-serve: sign up at https://postemi.com/app/signup, then Settings, Developers. No sales contact and no waiting list.\n\n## Versioning\nThe version is in the path: every route lives under `/public/v1`. A breaking change ships as `/public/v2`; `/public/v1` keeps its contract. Additive changes (a new optional field, a new route, a new enum value) ship inside v1, so a client must ignore fields it does not know.\n\n## Deprecation\nA route that is going away answers with `Deprecation: true` and a `Sunset` header carrying the RFC 9110 date after which it stops working, alongside a `Link` header with `rel=\"deprecation\"` pointing at the notes. A sunset date is never less than 180 days from the first `Deprecation` header on that route. Nothing is deprecated today.\n\n## Rate limits\nEvery response carries the IETF RateLimit headers (draft-ietf-httpapi-ratelimit-headers) `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` and `RateLimit-Policy` for the route you called. Each route has its own bucket, keyed to the API key. A 429 adds `Retry-After` in seconds. Self-throttle on `RateLimit-Remaining` rather than waiting for the 429.\n\n## Errors\nEvery failure answers with the `ApiError` schema. See the response descriptions on any operation for what each status means and whether retrying can help.","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://api.postemi.com","description":"Postemi API"}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"Authorization","description":"A Postemi API key, sent as the whole header value: `Authorization: psty_...`. Keys are minted per workspace and carry scopes."},"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://postemi.com/app/oauth/authorize","tokenUrl":"https://api.postemi.com/oauth/token","scopes":{"posts:read":"Read scheduled and published posts.","posts:draft":"Create and edit drafts. Cannot publish or schedule.","posts:publish":"Schedule and publish posts.","channels:read":"List connected channels and their settings.","channels:write":"Connect, edit and disconnect channels.","media:write":"Upload media.","analytics:read":"Read analytics.","mcp:read":"MCP endpoint only. Accepted for compatibility: MCP access is bounded by the signed-in person's workspace role, not by mcp:read or mcp:write. Not used by any REST route.","mcp:write":"MCP endpoint only. Accepted for compatibility: MCP access is bounded by the signed-in person's workspace role, not by mcp:read or mcp:write. Not used by any REST route."}}},"description":"OAuth 2.1 authorization code with PKCE (S256). Request the resource `https://api.postemi.com/public/v1` so the token is accepted here."}},"schemas":{"UploadDto":{"type":"object","properties":{}},"ChangePostStatusDto":{"type":"object","properties":{}},"AgentSubscribeDto":{"type":"object","properties":{"tier":{"type":"string","description":"The plan `slug` from GET /plans, exactly: basic, pro, creator or team.","enum":["basic","pro","creator","team"],"example":"pro"},"period":{"type":"string","description":"How often the plan renews.","enum":["monthly","yearly"],"example":"yearly"}},"required":["tier","period"]},"FotoAiQuoteDto":{"type":"object","properties":{}},"FotoAiGenerateDto":{"type":"object","properties":{}},"AgentSignupStartDto":{"type":"object","properties":{"email":{"type":"string","description":"The person's e-mail address. The code is sent here; the person reads it to the agent.","example":"anna@example.com"},"language":{"type":"string","description":"Language of the e-mail with the code, and of the account when it is created: hu (default), en, de or cs.","enum":["hu","en","de","cs"],"example":"hu"}},"required":["email"]},"AgentSignupCompleteDto":{"type":"object","properties":{"email":{"type":"string","description":"The same address the code was sent to.","example":"anna@example.com"},"code":{"type":"string","description":"The six-digit code from the e-mail. Valid for 10 minutes, 5 attempts.","example":"123456"},"acceptTerms":{"type":"boolean","description":"Must be the literal true. It states that the agent showed the person the terms (https://postemi.com/terms) and the privacy notice (https://postemi.com/privacy) and the person agreed to them. Recorded with the current versions and the time, as for a web registration.","enum":[true],"example":true},"workspaceName":{"type":"string","description":"Name of the new workspace. Defaults to the part of the address before the @.","example":"Anna Café"},"timezone":{"type":"string","description":"The person's IANA timezone, e.g. Europe/Budapest.","example":"Europe/Budapest"},"language":{"type":"string","description":"Language of the account: hu (default), en, de or cs.","enum":["hu","en","de","cs"],"example":"hu"}},"required":["email","code","acceptTerms"]},"ApiError":{"type":"object","additionalProperties":true,"properties":{"msg":{"type":"string","description":"Human-readable failure. Present on every error raised by Postemi itself (auth, scopes, quota, validation of a post body).","example":"This API key is missing the required permission: posts:publish"},"statusCode":{"type":"integer","description":"Present only on framework-level request-validation failures, where it repeats the HTTP status.","example":400},"message":{"type":"array","items":{"type":"string"},"description":"Present only on framework-level request-validation failures: one entry per field that failed.","example":["type must be one of the following values: draft, schedule, now"]},"error":{"type":"string","description":"Present only on framework-level failures: the status name.","example":"Bad Request"},"required":{"type":"array","items":{"type":"string"},"description":"On a 403 from the scope guard: the scopes the route needs.","example":["posts:publish"]},"granted":{"type":"array","items":{"type":"string"},"description":"On a 403 from the scope guard: the scopes this key actually holds.","example":["posts:read","posts:draft"]},"role":{"type":"string","description":"On a 403 from the scope guard: the key owner's current role in the workspace, which is the usual cause.","example":"VIEWER"}}},"FotoAiGeneration":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed","cancelled"]},"model":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true},"charged_millicredits":{"type":"integer","nullable":true,"description":"0 when it failed: nothing was charged."},"error":{"type":"object","properties":{"code":{"type":"string"}}},"outputs":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","description":"image or video"},"url":{"type":"string","nullable":true,"description":"FotoAI's URL. May expire within hours: post the media path instead."},"mime":{"type":"string","nullable":true},"width":{"type":"integer","nullable":true},"height":{"type":"integer","nullable":true}}}},"imported":{"type":"boolean"},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"path":{"type":"string","description":"The hosted URL in the media library. THIS is the post attachment."}},"required":["id","path"]}}},"required":["id","status","media"]}}},"externalDocs":{"description":"Developer documentation","url":"https://postemi.com/developers"},"security":[{"apiKey":[]},{"oauth2":[]}]}