From 5f3cfd6f5df70044b2adc9d56a9ae16902968d59 Mon Sep 17 00:00:00 2001 From: BSalaeddin <15094821+BSalaeddin@users.noreply.github.com> Date: Mon, 28 Sep 2026 13:59:58 +0000 Subject: [PATCH 1/3] chore: sync spec/v1.json from production --- spec/v1.json | 5204 +------------------------------------------------- 1 file changed, 1 insertion(+), 5203 deletions(-) diff --git a/spec/v1.json b/spec/v1.json index 0b4f866..80dafee 100644 --- a/spec/v1.json +++ b/spec/v1.json @@ -1,5203 +1 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Postify API", - "version": "1.0.0", - "description": "Postify's public REST API. Authenticate with an organization API key (minted in Settings → API keys) sent as `Authorization: Bearer postify_live_…` or `x-api-key`. Errors are RFC 9457 `application/problem+json` with a stable `code`; every response carries `Request-Id`; API-key responses carry IETF draft-11 rate-limit headers.", - "contact": { - "name": "Postify support", - "email": "support@usepostify.com" - } - }, - "servers": [ - { - "url": "https://app.usepostify.com", - "description": "Production" - } - ], - "tags": [ - { - "name": "Channels", - "description": "Connected social accounts (the publish targets)." - }, - { - "name": "Posts", - "description": "Create, schedule, publish, and inspect posts across channels." - }, - { - "name": "Media", - "description": "The media library: list assets and upload via presigned PUT." - }, - { - "name": "Analytics", - "description": "Workspace-level publishing and engagement summary." - }, - { - "name": "Usage", - "description": "Plan meters — including your api_requests allowance." - }, - { - "name": "Webhooks", - "description": "Outbound webhook endpoints: Standard-Webhooks-signed event deliveries with retries and a failure ladder." - } - ], - "paths": { - "/v1/analytics": { - "get": { - "operationId": "getAnalytics", - "summary": "Get workspace analytics", - "description": "Workspace-level publishing summary: post counts, delivery success, a 14-day publish timeline, and summed engagement across synced platforms.", - "tags": [ - "Analytics" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "analytics:read" - ], - "responses": { - "200": { - "description": "The analytics summary.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Analytics" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/channels": { - "get": { - "operationId": "listChannels", - "summary": "List channels", - "description": "Lists every social account connected to the organization, with connection health. Use a channel's `id` when creating post variants. Not paginated — the channel count is plan-bounded.", - "tags": [ - "Channels" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "channels:read" - ], - "responses": { - "200": { - "description": "The organization's connected channels.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChannelList" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/media": { - "get": { - "operationId": "listMedia", - "summary": "List media assets", - "description": "Lists the organization's media library, newest first, with cursor pagination. Use an asset's `url` as `media[].url` when creating posts.", - "tags": [ - "Media" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:read" - ], - "parameters": [ - { - "in": "query", - "name": "limit", - "schema": { - "default": 25, - "description": "Page size (1–100).", - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "description": "Page size (1–100)." - }, - { - "in": "query", - "name": "after", - "schema": { - "description": "Opaque cursor from a previous page's `next_cursor`.", - "type": "string" - }, - "description": "Opaque cursor from a previous page's `next_cursor`." - } - ], - "responses": { - "200": { - "description": "One page of media assets.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MediaList" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/media/uploads": { - "post": { - "operationId": "createMediaUpload", - "summary": "Start a media upload", - "description": "Issues a presigned upload ticket: PUT the raw file bytes to `upload_url` with the same `Content-Type`, then call POST /v1/media/uploads/{id}/complete. The asset kind (image/video/audio) is inferred from `content_type`.", - "tags": [ - "Media" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateUploadRequest" - } - } - } - }, - "responses": { - "201": { - "description": "The upload ticket.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateUploadResponse" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/media/uploads/{id}/complete": { - "post": { - "operationId": "completeMediaUpload", - "summary": "Complete a media upload", - "description": "Finalizes an uploaded asset after the PUT succeeds: probes the object, extracts a poster frame for videos, and marks it `ready`. Safe to retry — finalizing an already-ready asset is a no-op.", - "tags": [ - "Media" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Asset identifier." - }, - "required": true, - "description": "Asset identifier." - } - ], - "responses": { - "200": { - "description": "The finalized asset.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MediaAsset" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/posts": { - "get": { - "operationId": "listPosts", - "summary": "List posts", - "description": "Lists the organization's posts, newest first, with cursor pagination. Each post carries its per-channel variants and latest delivery outcomes.", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:read" - ], - "parameters": [ - { - "in": "query", - "name": "limit", - "schema": { - "default": 25, - "description": "Page size (1–100).", - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "description": "Page size (1–100)." - }, - { - "in": "query", - "name": "after", - "schema": { - "description": "Opaque cursor from a previous page's `next_cursor`.", - "type": "string" - }, - "description": "Opaque cursor from a previous page's `next_cursor`." - }, - { - "in": "query", - "name": "status", - "schema": { - "description": "Filter by lifecycle state.", - "type": "string", - "enum": [ - "draft", - "scheduled", - "publishing", - "published", - "failed", - "needs_approval" - ] - }, - "description": "Filter by lifecycle state." - } - ], - "responses": { - "200": { - "description": "One page of posts.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PostList" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - }, - "post": { - "operationId": "createPost", - "summary": "Create a post", - "description": "Creates a post with one variant per target channel. Exactly one mode is required: `draft: true` (save only), `scheduled_at` (future publish), or `publish_now: true` (immediate — requires the workspace's dangerous-operations toggle for API callers). Send an `Idempotency-Key` header to make retries safe.", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "parameters": [ - { - "in": "header", - "name": "Idempotency-Key", - "schema": { - "description": "Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`.", - "example": "9f2b6c1e-6a3d-4c1e-9d2f-0b1a2c3d4e5f", - "type": "string" - }, - "description": "Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`." - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreatePostRequest" - } - } - } - }, - "responses": { - "201": { - "description": "The created post.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - }, - "Idempotency-Replayed": { - "description": "`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.", - "schema": { - "description": "`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.", - "example": "true", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Post" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`idempotency_in_progress` — A request with this idempotency key is still in progress. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "422": { - "description": "`idempotency_key_reused` — Idempotency key reused with a different request body. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/posts/{id}": { - "get": { - "operationId": "getPost", - "summary": "Get a post", - "description": "Fetches one post with its variants and latest per-channel delivery outcomes. Poll this after publishing to track delivery.", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:read" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Post identifier." - }, - "required": true, - "description": "Post identifier." - } - ], - "responses": { - "200": { - "description": "The post.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Post" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - }, - "patch": { - "operationId": "reschedulePost", - "summary": "Reschedule a post", - "description": "Moves a draft, scheduled, or failed post to a new future publish time (drafts must already have variants). Published, publishing, and approval-pending posts cannot be rescheduled (409 `resource_conflict`).", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Post identifier." - }, - "required": true, - "description": "Post identifier." - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReschedulePostRequest" - } - } - } - }, - "responses": { - "200": { - "description": "The rescheduled post.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Post" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - }, - "delete": { - "operationId": "deletePost", - "summary": "Delete a post", - "description": "Deletes a post (it disappears from Postify; already-published platform content is not retracted). A post that is currently publishing cannot be deleted (409). Requires the workspace's dangerous-operations toggle.", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Post identifier." - }, - "required": true, - "description": "Post identifier." - } - ], - "responses": { - "200": { - "description": "Deletion confirmed.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeletePostResponse" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/posts/{id}/publish": { - "post": { - "operationId": "publishPost", - "summary": "Publish a post now", - "description": "Queues an immediate publish of a draft, scheduled, or failed post (202 — delivery continues in the background; poll GET /v1/posts/{id} for per-channel outcomes). Already-published posts return 409; a post already publishing is accepted as-is. Requires the workspace's dangerous-operations toggle.", - "tags": [ - "Posts" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "posts:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Post identifier." - }, - "required": true, - "description": "Post identifier." - } - ], - "responses": { - "202": { - "description": "Publish accepted.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PublishPostResponse" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/usage": { - "get": { - "operationId": "getUsage", - "summary": "Get plan usage", - "description": "The workspace's effective plan tier and every plan meter's consumption for the current period — including `api_requests`, the meter every /v1 call consumes.", - "tags": [ - "Usage" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "analytics:read" - ], - "responses": { - "200": { - "description": "Plan + meter consumption.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Usage" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/webhook-endpoints": { - "get": { - "operationId": "listWebhookEndpoints", - "summary": "List webhook endpoints", - "description": "Lists the organization's webhook endpoints with their subscription and failure-ladder state. Signing secrets are never returned here — they are shown once at creation and can be rolled in Settings → Webhooks.", - "tags": [ - "Webhooks" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "webhooks:read" - ], - "responses": { - "200": { - "description": "All webhook endpoints for the organization.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebhookEndpointList" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - }, - "post": { - "operationId": "createWebhookEndpoint", - "summary": "Create a webhook endpoint", - "description": "Registers an HTTPS endpoint for event deliveries. The URL is validated against SSRF at creation AND re-validated at every delivery (loopback, private-network, link-local, and cloud-metadata addresses are rejected — 400 `validation_failed`). The response includes the Standard-Webhooks signing secret exactly once. Endpoint creation counts against the plan's `integrations` quota.", - "tags": [ - "Webhooks" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "webhooks:write" - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWebhookEndpointRequest" - } - } - } - }, - "responses": { - "201": { - "description": "The created endpoint with its show-once signing secret.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebhookEndpointCreated" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/webhook-endpoints/{id}": { - "patch": { - "operationId": "updateWebhookEndpoint", - "summary": "Update a webhook endpoint", - "description": "Updates the URL (re-validated through the SSRF gauntlet), the event-type subscription list, and/or `enabled`. Setting `enabled: true` on an auto-disabled endpoint clears its failure ladder and resumes deliveries.", - "tags": [ - "Webhooks" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "webhooks:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Webhook endpoint id." - }, - "required": true, - "description": "Webhook endpoint id." - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" - } - } - } - }, - "responses": { - "200": { - "description": "The updated endpoint.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebhookEndpoint" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - }, - "delete": { - "operationId": "deleteWebhookEndpoint", - "summary": "Delete a webhook endpoint", - "description": "Removes the endpoint and its delivery history. Deliveries stop immediately; this cannot be undone.", - "tags": [ - "Webhooks" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "webhooks:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Webhook endpoint id." - }, - "required": true, - "description": "Webhook endpoint id." - } - ], - "responses": { - "200": { - "description": "Deletion confirmed.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteWebhookEndpointResponse" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - }, - "/v1/webhook-endpoints/{id}/test": { - "post": { - "operationId": "testWebhookEndpoint", - "summary": "Send a test delivery", - "description": "Sends a synthetic `webhook.test` event to the endpoint, signed exactly like a real delivery (Standard-Webhooks headers over the raw body). Use it to verify your signature handling before subscribing to real events. Disabled endpoints return 409 `resource_conflict`.", - "tags": [ - "Webhooks" - ], - "security": [ - { - "bearerApiKey": [] - }, - { - "headerApiKey": [] - } - ], - "x-scopes": [ - "webhooks:write" - ], - "parameters": [ - { - "in": "path", - "name": "id", - "schema": { - "type": "string", - "minLength": 1, - "description": "Webhook endpoint id." - }, - "required": true, - "description": "Webhook endpoint id." - } - ], - "responses": { - "200": { - "description": "The test delivery outcome.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - }, - "RateLimit-Policy": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "schema": { - "description": "IETF draft-11 quota policy for this API key's burst window.", - "example": "\"per-key-minute\";q=120;w=60", - "type": "string" - } - }, - "RateLimit": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "schema": { - "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", - "example": "\"per-key-minute\";r=73;t=38", - "type": "string" - } - }, - "X-RateLimit-Limit": { - "description": "Burst-window request limit (compatibility trio).", - "schema": { - "description": "Burst-window request limit (compatibility trio).", - "example": "120", - "type": "string" - } - }, - "X-RateLimit-Remaining": { - "description": "Requests left in the current burst window.", - "schema": { - "description": "Requests left in the current burst window.", - "example": "73", - "type": "string" - } - }, - "X-RateLimit-Reset": { - "description": "Unix epoch seconds when the burst window resets.", - "schema": { - "description": "Unix epoch seconds when the burst window resets.", - "example": "1800000038", - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestWebhookEndpointResult" - } - } - } - }, - "400": { - "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "401": { - "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "403": { - "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "404": { - "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "409": { - "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "429": { - "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - }, - "500": { - "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", - "headers": { - "Request-Id": { - "required": true, - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "schema": { - "type": "string", - "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", - "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" - } - } - }, - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "CreateUploadRequest": { - "type": "object", - "properties": { - "filename": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Filename including extension.", - "example": "launch-teaser.mp4" - }, - "content_type": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "description": "MIME type of the bytes you will upload.", - "example": "video/mp4" - }, - "size_bytes": { - "description": "Size in bytes, if known.", - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 2147483647 - } - }, - "required": [ - "filename", - "content_type" - ] - }, - "CreatePostRequest": { - "type": "object", - "properties": { - "variants": { - "minItems": 1, - "maxItems": 20, - "type": "array", - "items": { - "type": "object", - "properties": { - "channel_id": { - "type": "string", - "minLength": 1, - "description": "A connected channel's `id` (see /v1/channels)." - }, - "body": { - "type": "string", - "minLength": 1, - "maxLength": 63206, - "description": "The text to publish to this channel." - }, - "media": { - "description": "Media attachments for this channel.", - "maxItems": 20, - "type": "array", - "items": { - "$ref": "#/components/schemas/PostMediaItem" - } - } - }, - "required": [ - "channel_id", - "body" - ] - }, - "description": "One variant per target channel." - }, - "title": { - "description": "Internal title (not published).", - "anyOf": [ - { - "type": "string", - "maxLength": 300 - }, - { - "type": "null" - } - ] - }, - "body": { - "description": "Optional channel-agnostic base text.", - "anyOf": [ - { - "type": "string", - "maxLength": 63206 - }, - { - "type": "null" - } - ] - }, - "draft": { - "default": false, - "description": "Save as a draft (no scheduling, no publishing).", - "type": "boolean" - }, - "scheduled_at": { - "description": "Future publish time (ISO-8601). Mutually exclusive with `draft` and `publish_now`.", - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$" - }, - "publish_now": { - "default": false, - "description": "Publish immediately. Requires the workspace's dangerous-operations toggle for API callers.", - "type": "boolean" - } - }, - "required": [ - "variants" - ] - }, - "PostMediaItem": { - "type": "object", - "properties": { - "url": { - "type": "string", - "format": "uri", - "description": "Media URL. Use the `url` returned by /v1/media assets." - }, - "type": { - "type": "string", - "enum": [ - "image", - "video" - ], - "description": "Media kind." - }, - "alt": { - "description": "Accessibility alt text, where the platform supports it.", - "anyOf": [ - { - "type": "string", - "maxLength": 1000 - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "url", - "type" - ], - "description": "One media attachment." - }, - "ReschedulePostRequest": { - "type": "object", - "properties": { - "scheduled_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "description": "The new future publish time (ISO-8601)." - } - }, - "required": [ - "scheduled_at" - ] - }, - "CreateWebhookEndpointRequest": { - "type": "object", - "properties": { - "url": { - "type": "string", - "format": "uri", - "description": "HTTPS URL on the default port (443). Loopback, private, link-local, and cloud-metadata addresses are rejected — at creation AND at every delivery.", - "example": "https://api.example.com/postify/webhooks" - }, - "event_types": { - "minItems": 1, - "type": "array", - "items": { - "type": "string", - "enum": [ - "post.published", - "post.failed", - "channel.connected", - "channel.reauth_required", - "delivery.failed" - ] - }, - "description": "Event types to subscribe to (at least one)." - } - }, - "required": [ - "url", - "event_types" - ] - }, - "UpdateWebhookEndpointRequest": { - "type": "object", - "properties": { - "url": { - "description": "Replacement delivery URL — re-validated through the same SSRF gauntlet as creation.", - "type": "string", - "format": "uri" - }, - "event_types": { - "description": "Replacement event-type subscription list.", - "minItems": 1, - "type": "array", - "items": { - "type": "string", - "enum": [ - "post.published", - "post.failed", - "channel.connected", - "channel.reauth_required", - "delivery.failed" - ] - } - }, - "enabled": { - "description": "Enable or disable deliveries. Setting `true` on an auto-disabled endpoint clears its failure state and resumes deliveries.", - "type": "boolean" - } - }, - "description": "Partial update — at least one field is required." - }, - "Analytics": { - "type": "object", - "properties": { - "totals": { - "type": "object", - "properties": { - "posts": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "All posts in the workspace." - }, - "published": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Posts in `published` state." - }, - "scheduled": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Posts in `scheduled` state." - }, - "failed": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Posts in `failed` state." - }, - "channels": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Connected channels." - } - }, - "required": [ - "posts", - "published", - "scheduled", - "failed", - "channels" - ], - "additionalProperties": false, - "description": "Workspace-wide counts." - }, - "delivery": { - "type": "object", - "properties": { - "attempts": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Per-channel delivery attempts recorded." - }, - "success_rate": { - "anyOf": [ - { - "type": "number", - "minimum": 0, - "maximum": 1 - }, - { - "type": "null" - } - ], - "description": "Of the SETTLED attempts (acked/indexed vs failed/dlq), the fraction that succeeded. In-flight attempts are excluded; null when nothing has settled yet." - } - }, - "required": [ - "attempts", - "success_rate" - ], - "additionalProperties": false, - "description": "Delivery pipeline health." - }, - "timeline": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnalyticsTimelinePoint" - }, - "description": "Publishes per UTC day over the last 14 days." - }, - "engagement": { - "type": "object", - "properties": { - "impressions": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "likes": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "comments": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "shares": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "clicks": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - } - }, - "required": [ - "impressions", - "likes", - "comments", - "shares", - "clicks" - ], - "additionalProperties": false, - "description": "Summed platform engagement across synced posts. Zeros when metrics have not synced yet." - } - }, - "required": [ - "totals", - "delivery", - "timeline", - "engagement" - ], - "additionalProperties": false, - "description": "Workspace analytics summary." - }, - "AnalyticsTimelinePoint": { - "type": "object", - "properties": { - "date": { - "type": "string", - "description": "UTC calendar day (YYYY-MM-DD).", - "example": "2026-07-18" - }, - "published": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Posts published that day." - } - }, - "required": [ - "date", - "published" - ], - "additionalProperties": false - }, - "Problem": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "URI identifying the problem class; resolves to a documentation page.", - "example": "https://usepostify.com/docs/api/problems/rate-limited" - }, - "title": { - "type": "string", - "description": "Short human-readable summary of the problem class." - }, - "status": { - "type": "integer", - "minimum": 400, - "maximum": 599, - "description": "HTTP status code, duplicated from the response line." - }, - "detail": { - "description": "Human-readable explanation specific to this occurrence. Never parse it.", - "type": "string" - }, - "code": { - "type": "string", - "enum": [ - "invalid_request", - "validation_failed", - "authentication_required", - "invalid_api_key", - "insufficient_scope", - "feature_not_enabled", - "dangerous_ops_disabled", - "resource_not_found", - "resource_conflict", - "idempotency_in_progress", - "idempotency_key_reused", - "rate_limited", - "quota_exhausted", - "internal_error" - ], - "description": "Finite stable machine-readable code — the value SDKs branch on. New codes may appear over time; treat unknown values as a generic error." - }, - "request_id": { - "type": "string", - "description": "Request correlation id, identical to the Request-Id response header. Quote it in support requests.", - "example": "req_9f2c1e4ab8d64f0e" - }, - "errors": { - "description": "Field-level validation errors (validation_failed only).", - "type": "array", - "items": { - "$ref": "#/components/schemas/ProblemFieldError" - } - } - }, - "required": [ - "type", - "title", - "status", - "code", - "request_id" - ], - "additionalProperties": false, - "description": "RFC 9457 problem document — every non-2xx /v1 response has this shape with Content-Type application/problem+json." - }, - "ProblemFieldError": { - "type": "object", - "properties": { - "pointer": { - "type": "string", - "description": "JSON Pointer to the offending field, e.g. \"/scheduled_at\"." - }, - "code": { - "type": "string", - "description": "Stable machine-readable field-level code." - }, - "message": { - "type": "string", - "description": "Human-readable explanation." - } - }, - "required": [ - "pointer", - "code", - "message" - ], - "additionalProperties": false - }, - "ChannelList": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Channel" - } - } - }, - "required": [ - "data" - ], - "additionalProperties": false, - "description": "All connected channels for the organization. Not paginated: the channel count is plan-bounded (max 50)." - }, - "Channel": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Stable channel identifier. Use it in post variants.", - "example": "cmc1x2y3z0001abcd" - }, - "platform": { - "type": "string", - "enum": [ - "x", - "linkedin", - "facebook", - "instagram", - "threads", - "tiktok", - "pinterest", - "youtube", - "bluesky", - "reddit" - ], - "description": "Social platform this channel publishes to." - }, - "handle": { - "type": "string", - "description": "Account handle or display name, e.g. \"@postifyhq\"." - }, - "avatar_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Profile image URL, if the platform provides one." - }, - "followers": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "Follower count at last sync, if available." - }, - "status": { - "type": "string", - "enum": [ - "live", - "reauth_required", - "rate_limited", - "disabled" - ], - "description": "Connection health. Only `live` channels can publish; `reauth_required` needs the owner to reconnect in the app." - }, - "last_sync_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When channel metadata was last refreshed (ISO-8601 UTC)." - }, - "last_error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Most recent connection error, if any." - }, - "created_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the channel was connected (ISO-8601 UTC)." - } - }, - "required": [ - "id", - "platform", - "handle", - "avatar_url", - "followers", - "status", - "last_sync_at", - "last_error", - "created_at" - ], - "additionalProperties": false, - "description": "A connected social account." - }, - "MediaList": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MediaAsset" - } - }, - "has_more": { - "type": "boolean", - "description": "True when another page exists after `next_cursor`." - }, - "next_cursor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected." - } - }, - "required": [ - "data", - "has_more", - "next_cursor" - ], - "additionalProperties": false, - "description": "One page of assets, newest first." - }, - "MediaAsset": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Stable asset identifier." - }, - "filename": { - "type": "string", - "description": "Original filename." - }, - "content_type": { - "type": "string", - "description": "MIME type." - }, - "kind": { - "type": "string", - "enum": [ - "image", - "video", - "audio", - "raw" - ], - "description": "Asset kind." - }, - "status": { - "type": "string", - "enum": [ - "pending", - "ready", - "failed" - ], - "description": "`pending` until the upload is completed; only `ready` assets should be attached to posts." - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Durable URL for the asset — use this as `media[].url` when creating posts. Null until the upload completes." - }, - "size_bytes": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "Size in bytes." - }, - "width": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "Pixel width, when known." - }, - "height": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "Pixel height, when known." - }, - "duration_sec": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "Duration in seconds for audio/video, when known." - }, - "created_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the asset was created (ISO-8601 UTC)." - } - }, - "required": [ - "id", - "filename", - "content_type", - "kind", - "status", - "url", - "size_bytes", - "width", - "height", - "duration_sec", - "created_at" - ], - "additionalProperties": false, - "description": "A media library asset." - }, - "CreateUploadResponse": { - "type": "object", - "properties": { - "asset_id": { - "type": "string", - "description": "The pending asset — complete it after the PUT succeeds." - }, - "upload_url": { - "type": "string", - "description": "Presigned URL. PUT the raw bytes here with the same Content-Type." - }, - "method": { - "type": "string", - "const": "PUT", - "description": "HTTP method to use." - }, - "expires_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the presigned URL stops working (ISO-8601 UTC)." - } - }, - "required": [ - "asset_id", - "upload_url", - "method", - "expires_at" - ], - "additionalProperties": false, - "description": "Upload ticket: PUT the bytes to `upload_url`, then POST /v1/media/uploads/{id}/complete." - }, - "PostList": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Post" - } - }, - "has_more": { - "type": "boolean", - "description": "True when another page exists after `next_cursor`." - }, - "next_cursor": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected." - } - }, - "required": [ - "data", - "has_more", - "next_cursor" - ], - "additionalProperties": false, - "description": "One page of posts, newest first." - }, - "Post": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Stable post identifier.", - "example": "cmc1x2y3z0001abcd" - }, - "status": { - "type": "string", - "enum": [ - "draft", - "scheduled", - "publishing", - "published", - "failed", - "needs_approval" - ], - "description": "Lifecycle state. Consult `deliveries` for per-channel outcomes — a `published` post can still contain failed channels (partial delivery)." - }, - "type": { - "type": "string", - "enum": [ - "single", - "thread", - "carousel", - "long" - ], - "description": "Post format." - }, - "title": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Internal title (not published to platforms)." - }, - "body": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Channel-agnostic base text the variants derive from." - }, - "scheduled_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When the post is scheduled to publish (ISO-8601 UTC)." - }, - "published_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When the post finished publishing (ISO-8601 UTC)." - }, - "created_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the post was created (ISO-8601 UTC)." - }, - "variants": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PostVariant" - }, - "description": "Per-channel variants." - }, - "deliveries": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Delivery" - }, - "description": "Latest delivery outcome per channel. Empty until a publish is attempted." - } - }, - "required": [ - "id", - "status", - "type", - "title", - "body", - "scheduled_at", - "published_at", - "created_at", - "variants", - "deliveries" - ], - "additionalProperties": false, - "description": "A post across one or more channels." - }, - "PostVariant": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Variant identifier." - }, - "channel_id": { - "type": "string", - "description": "The channel this variant publishes to (see /v1/channels)." - }, - "body": { - "type": "string", - "description": "The text published to the channel." - }, - "media": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PostMediaItemOutput" - }, - "description": "Media attached to this variant." - } - }, - "required": [ - "id", - "channel_id", - "body", - "media" - ], - "additionalProperties": false, - "description": "Per-channel tailoring of a post." - }, - "Delivery": { - "type": "object", - "properties": { - "channel_id": { - "type": "string", - "description": "Channel this delivery targets." - }, - "stage": { - "type": "string", - "enum": [ - "queued", - "signed", - "sent", - "acked", - "indexed", - "failed", - "dlq" - ], - "description": "Latest delivery stage. `indexed`/`acked` are success; `failed`/`dlq` are terminal failures; anything else is in flight." - }, - "external_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The platform's id for the published item, once known." - }, - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Most recent delivery error, if any." - } - }, - "required": [ - "channel_id", - "stage", - "external_id", - "error" - ], - "additionalProperties": false, - "description": "Per-channel delivery outcome of a publish." - }, - "DeletePostResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "deleted": { - "type": "boolean", - "const": true - } - }, - "required": [ - "id", - "deleted" - ], - "additionalProperties": false - }, - "PublishPostResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "draft", - "scheduled", - "publishing", - "published", - "failed", - "needs_approval" - ], - "description": "State after acceptance. Poll GET /v1/posts/{id} for per-channel `deliveries`." - } - }, - "required": [ - "id", - "status" - ], - "additionalProperties": false, - "description": "Publish accepted — delivery continues in the background." - }, - "Usage": { - "type": "object", - "properties": { - "plan": { - "type": "string", - "description": "The workspace's effective plan tier.", - "example": "team" - }, - "meters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UsageMeter" - }, - "description": "All plan meters for the workspace." - } - }, - "required": [ - "plan", - "meters" - ], - "additionalProperties": false, - "description": "Plan + meter consumption." - }, - "UsageMeter": { - "type": "object", - "properties": { - "key": { - "type": "string", - "enum": [ - "posts_per_month", - "channels", - "team_members", - "ai_credits", - "transcription_minutes", - "integrations", - "api_requests" - ], - "description": "Meter name." - }, - "used": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Consumed in the current period." - }, - "limit": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "Plan ceiling for the period. Null means unlimited." - }, - "remaining": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "`limit - used`, floored at 0. Null when unlimited." - }, - "period_starts_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "Current metering period start (ISO-8601 UTC)." - }, - "period_ends_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When the meter resets (ISO-8601 UTC). Null when the period is open-ended." - } - }, - "required": [ - "key", - "used", - "limit", - "remaining", - "period_starts_at", - "period_ends_at" - ], - "additionalProperties": false, - "description": "One plan meter." - }, - "WebhookEndpointList": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WebhookEndpoint" - } - } - }, - "required": [ - "data" - ], - "additionalProperties": false, - "description": "All webhook endpoints for the organization. Not paginated — the endpoint count is plan-bounded by the `integrations` quota." - }, - "WebhookEndpoint": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Stable webhook endpoint identifier.", - "example": "cmc9x2y3z0001abcd" - }, - "url": { - "type": "string", - "description": "HTTPS delivery URL. Private/internal addresses are rejected." - }, - "event_types": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "post.published", - "post.failed", - "channel.connected", - "channel.reauth_required", - "delivery.failed" - ] - }, - "description": "Event types this endpoint subscribes to." - }, - "enabled": { - "type": "boolean", - "description": "Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts." - }, - "auto_disabled_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`." - }, - "consecutive_failures": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20." - }, - "created_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the endpoint was created (ISO-8601 UTC)." - } - }, - "required": [ - "id", - "url", - "event_types", - "enabled", - "auto_disabled_at", - "consecutive_failures", - "created_at" - ], - "additionalProperties": false, - "description": "An outbound webhook endpoint (subscriber)." - }, - "WebhookEndpointCreated": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Stable webhook endpoint identifier.", - "example": "cmc9x2y3z0001abcd" - }, - "url": { - "type": "string", - "description": "HTTPS delivery URL. Private/internal addresses are rejected." - }, - "event_types": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "post.published", - "post.failed", - "channel.connected", - "channel.reauth_required", - "delivery.failed" - ] - }, - "description": "Event types this endpoint subscribes to." - }, - "enabled": { - "type": "boolean", - "description": "Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts." - }, - "auto_disabled_at": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ], - "description": "When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`." - }, - "consecutive_failures": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991, - "description": "Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20." - }, - "created_at": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", - "description": "When the endpoint was created (ISO-8601 UTC)." - }, - "signing_secret": { - "type": "string", - "description": "Standard-Webhooks signing secret (`whsec_` + base64). Store it now — over the API it is shown only in this response. A workspace owner/admin can re-reveal or roll it in Settings → Webhooks." - } - }, - "required": [ - "id", - "url", - "event_types", - "enabled", - "auto_disabled_at", - "consecutive_failures", - "created_at", - "signing_secret" - ], - "additionalProperties": false, - "description": "The created endpoint plus its show-once signing secret. Verify deliveries with any Standard Webhooks library." - }, - "DeleteWebhookEndpointResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "deleted": { - "type": "boolean", - "const": true - } - }, - "required": [ - "id", - "deleted" - ], - "additionalProperties": false - }, - "TestWebhookEndpointResult": { - "type": "object", - "properties": { - "delivery_id": { - "type": "string", - "description": "The recorded delivery attempt." - }, - "succeeded": { - "type": "boolean", - "description": "Whether the endpoint returned a 2xx." - }, - "http_code": { - "anyOf": [ - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ], - "description": "HTTP status returned by the endpoint, or null when the request never completed (timeout, TLS failure, blocked egress)." - }, - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Transport-level failure detail when no HTTP response exists." - } - }, - "required": [ - "delivery_id", - "succeeded", - "http_code", - "error" - ], - "additionalProperties": false, - "description": "Outcome of a synthetic `webhook.test` delivery, signed exactly like a real event." - }, - "PostMediaItemOutput": { - "type": "object", - "properties": { - "url": { - "type": "string", - "format": "uri", - "description": "Media URL. Use the `url` returned by /v1/media assets." - }, - "type": { - "type": "string", - "enum": [ - "image", - "video" - ], - "description": "Media kind." - }, - "alt": { - "description": "Accessibility alt text, where the platform supports it.", - "anyOf": [ - { - "type": "string", - "maxLength": 1000 - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "url", - "type" - ], - "additionalProperties": false, - "description": "One media attachment." - } - }, - "securitySchemes": { - "bearerApiKey": { - "type": "http", - "scheme": "bearer", - "description": "Organization API key as a Bearer token (`postify_live_…`)." - }, - "headerApiKey": { - "type": "apiKey", - "in": "header", - "name": "x-api-key", - "description": "Organization API key in the `x-api-key` header." - } - } - } -} +{"openapi":"3.1.0","info":{"title":"Postify API","version":"1.0.0","description":"Postify's public REST API. Authenticate with an organization API key (minted in Settings → API keys) sent as `Authorization: Bearer postify_live_…` or `x-api-key`. Errors are RFC 9457 `application/problem+json` with a stable `code`; every response carries `Request-Id`; API-key responses carry IETF draft-11 rate-limit headers.","contact":{"name":"Postify support","email":"support@usepostify.com"}},"servers":[{"url":"https://app.usepostify.com","description":"Production"}],"tags":[{"name":"Channels","description":"Connected social accounts (the publish targets)."},{"name":"Posts","description":"Create, schedule, publish, and inspect posts across channels."},{"name":"Media","description":"The media library: list assets and upload via presigned PUT."},{"name":"Analytics","description":"Workspace-level publishing and engagement summary."},{"name":"Usage","description":"Plan meters — including your api_requests allowance."},{"name":"Webhooks","description":"Outbound webhook endpoints: Standard-Webhooks-signed event deliveries with retries and a failure ladder."}],"paths":{"/v1/analytics":{"get":{"operationId":"getAnalytics","summary":"Get workspace analytics","description":"Workspace-level publishing summary: post counts, delivery success, a 14-day publish timeline, and summed engagement across synced platforms.","tags":["Analytics"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["analytics:read"],"responses":{"200":{"description":"The analytics summary.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Analytics"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels":{"get":{"operationId":"listChannels","summary":"List channels","description":"Lists every social account connected to the organization, with connection health. Use a channel's `id` when creating post variants. Not paginated — the channel count is plan-bounded.","tags":["Channels"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["channels:read"],"responses":{"200":{"description":"The organization's connected channels.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelList"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media":{"get":{"operationId":"listMedia","summary":"List media assets","description":"Lists the organization's media library, newest first, with cursor pagination. Use an asset's `url` as `media[].url` when creating posts.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"query","name":"limit","schema":{"default":25,"description":"Page size (1–100).","type":"integer","minimum":1,"maximum":100},"description":"Page size (1–100)."},{"in":"query","name":"after","schema":{"description":"Opaque cursor from a previous page's `next_cursor`.","type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."}],"responses":{"200":{"description":"One page of media assets.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media/uploads":{"post":{"operationId":"createMediaUpload","summary":"Start a media upload","description":"Issues a presigned upload ticket: PUT the raw file bytes to `upload_url` with the same `Content-Type`, then call POST /v1/media/uploads/{id}/complete. The asset kind (image/video/audio) is inferred from `content_type`.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"}}}},"responses":{"201":{"description":"The upload ticket.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media/uploads/{id}/complete":{"post":{"operationId":"completeMediaUpload","summary":"Complete a media upload","description":"Finalizes an uploaded asset after the PUT succeeds: probes the object, extracts a poster frame for videos, and marks it `ready`. Safe to retry — finalizing an already-ready asset is a no-op.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Asset identifier."},"required":true,"description":"Asset identifier."}],"responses":{"200":{"description":"The finalized asset.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts":{"get":{"operationId":"listPosts","summary":"List posts","description":"Lists the organization's posts, newest first, with cursor pagination. Each post carries its per-channel variants and latest delivery outcomes.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"query","name":"limit","schema":{"default":25,"description":"Page size (1–100).","type":"integer","minimum":1,"maximum":100},"description":"Page size (1–100)."},{"in":"query","name":"after","schema":{"description":"Opaque cursor from a previous page's `next_cursor`.","type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"status","schema":{"description":"Filter by lifecycle state.","type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"]},"description":"Filter by lifecycle state."}],"responses":{"200":{"description":"One page of posts.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createPost","summary":"Create a post","description":"Creates a post with one variant per target channel. Exactly one mode is required: `draft: true` (save only), `scheduled_at` (future publish), or `publish_now: true` (immediate — requires the workspace's dangerous-operations toggle for API callers). Send an `Idempotency-Key` header to make retries safe.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"header","name":"Idempotency-Key","schema":{"description":"Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`.","example":"9f2b6c1e-6a3d-4c1e-9d2f-0b1a2c3d4e5f","type":"string"},"description":"Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"}}}},"responses":{"201":{"description":"The created post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}},"Idempotency-Replayed":{"description":"`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.","schema":{"description":"`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.","example":"true","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`idempotency_in_progress` — A request with this idempotency key is still in progress. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"`idempotency_key_reused` — Idempotency key reused with a different request body. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts/{id}":{"get":{"operationId":"getPost","summary":"Get a post","description":"Fetches one post with its variants and latest per-channel delivery outcomes. Poll this after publishing to track delivery.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"200":{"description":"The post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"reschedulePost","summary":"Reschedule a post","description":"Moves a draft, scheduled, or failed post to a new future publish time (drafts must already have variants). Published, publishing, and approval-pending posts cannot be rescheduled (409 `resource_conflict`).","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReschedulePostRequest"}}}},"responses":{"200":{"description":"The rescheduled post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deletePost","summary":"Delete a post","description":"Deletes a post (it disappears from Postify; already-published platform content is not retracted). A post that is currently publishing cannot be deleted (409). Requires the workspace's dangerous-operations toggle.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"200":{"description":"Deletion confirmed.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePostResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts/{id}/publish":{"post":{"operationId":"publishPost","summary":"Publish a post now","description":"Queues an immediate publish of a draft, scheduled, or failed post (202 — delivery continues in the background; poll GET /v1/posts/{id} for per-channel outcomes). Already-published posts return 409; a post already publishing is accepted as-is. Requires the workspace's dangerous-operations toggle.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"202":{"description":"Publish accepted.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPostResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/usage":{"get":{"operationId":"getUsage","summary":"Get plan usage","description":"The workspace's effective plan tier and every plan meter's consumption for the current period — including `api_requests`, the meter every /v1 call consumes.","tags":["Usage"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["analytics:read"],"responses":{"200":{"description":"Plan + meter consumption.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints":{"get":{"operationId":"listWebhookEndpoints","summary":"List webhook endpoints","description":"Lists the organization's webhook endpoints with their subscription and failure-ladder state. Signing secrets are never returned here — they are shown once at creation and can be rolled in Settings → Webhooks.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:read"],"responses":{"200":{"description":"All webhook endpoints for the organization.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createWebhookEndpoint","summary":"Create a webhook endpoint","description":"Registers an HTTPS endpoint for event deliveries. The URL is validated against SSRF at creation AND re-validated at every delivery (loopback, private-network, link-local, and cloud-metadata addresses are rejected — 400 `validation_failed`). The response includes the Standard-Webhooks signing secret exactly once. Endpoint creation counts against the plan's `integrations` quota.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"}}}},"responses":{"201":{"description":"The created endpoint with its show-once signing secret.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints/{id}":{"patch":{"operationId":"updateWebhookEndpoint","summary":"Update a webhook endpoint","description":"Updates the URL (re-validated through the SSRF gauntlet), the event-type subscription list, and/or `enabled`. Setting `enabled: true` on an auto-disabled endpoint clears its failure ladder and resumes deliveries.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointRequest"}}}},"responses":{"200":{"description":"The updated endpoint.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteWebhookEndpoint","summary":"Delete a webhook endpoint","description":"Removes the endpoint and its delivery history. Deliveries stop immediately; this cannot be undone.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"responses":{"200":{"description":"Deletion confirmed.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWebhookEndpointResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints/{id}/test":{"post":{"operationId":"testWebhookEndpoint","summary":"Send a test delivery","description":"Sends a synthetic `webhook.test` event to the endpoint, signed exactly like a real delivery (Standard-Webhooks headers over the raw body). Use it to verify your signature handling before subscribing to real events. Disabled endpoints return 409 `resource_conflict`.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"responses":{"200":{"description":"The test delivery outcome.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestWebhookEndpointResult"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"CreateUploadRequest":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":256,"description":"Filename including extension.","example":"launch-teaser.mp4"},"content_type":{"type":"string","minLength":1,"maxLength":128,"description":"MIME type of the bytes you will upload.","example":"video/mp4"},"size_bytes":{"description":"Size in bytes, if known.","type":"integer","exclusiveMinimum":0,"maximum":2147483647}},"required":["filename","content_type"]},"CreatePostRequest":{"type":"object","properties":{"variants":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"channel_id":{"type":"string","minLength":1,"description":"A connected channel's `id` (see /v1/channels)."},"body":{"type":"string","minLength":1,"maxLength":63206,"description":"The text to publish to this channel."},"media":{"description":"Media attachments for this channel.","maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/PostMediaItem"}}},"required":["channel_id","body"]},"description":"One variant per target channel."},"title":{"description":"Internal title (not published).","anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"body":{"description":"Optional channel-agnostic base text.","anyOf":[{"type":"string","maxLength":63206},{"type":"null"}]},"draft":{"default":false,"description":"Save as a draft (no scheduling, no publishing).","type":"boolean"},"scheduled_at":{"description":"Future publish time (ISO-8601). Mutually exclusive with `draft` and `publish_now`.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"publish_now":{"default":false,"description":"Publish immediately. Requires the workspace's dangerous-operations toggle for API callers.","type":"boolean"}},"required":["variants"]},"PostMediaItem":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Media URL. Use the `url` returned by /v1/media assets."},"type":{"type":"string","enum":["image","video"],"description":"Media kind."},"alt":{"description":"Accessibility alt text, where the platform supports it.","anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]}},"required":["url","type"],"description":"One media attachment."},"ReschedulePostRequest":{"type":"object","properties":{"scheduled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"The new future publish time (ISO-8601)."}},"required":["scheduled_at"]},"CreateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL on the default port (443). Loopback, private, link-local, and cloud-metadata addresses are rejected — at creation AND at every delivery.","example":"https://api.example.com/postify/webhooks"},"event_types":{"minItems":1,"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types to subscribe to (at least one)."}},"required":["url","event_types"]},"UpdateWebhookEndpointRequest":{"type":"object","properties":{"url":{"description":"Replacement delivery URL — re-validated through the same SSRF gauntlet as creation.","type":"string","format":"uri"},"event_types":{"description":"Replacement event-type subscription list.","minItems":1,"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]}},"enabled":{"description":"Enable or disable deliveries. Setting `true` on an auto-disabled endpoint clears its failure state and resumes deliveries.","type":"boolean"}},"description":"Partial update — at least one field is required."},"Analytics":{"type":"object","properties":{"totals":{"type":"object","properties":{"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"All posts in the workspace."},"published":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `published` state."},"scheduled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `scheduled` state."},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `failed` state."},"channels":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Connected channels."}},"required":["posts","published","scheduled","failed","channels"],"additionalProperties":false,"description":"Workspace-wide counts."},"delivery":{"type":"object","properties":{"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Per-channel delivery attempts recorded."},"success_rate":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}],"description":"Of the SETTLED attempts (acked/indexed vs failed/dlq), the fraction that succeeded. In-flight attempts are excluded; null when nothing has settled yet."}},"required":["attempts","success_rate"],"additionalProperties":false,"description":"Delivery pipeline health."},"timeline":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsTimelinePoint"},"description":"Publishes per UTC day over the last 14 days."},"engagement":{"type":"object","properties":{"impressions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"comments":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"shares":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["impressions","likes","comments","shares","clicks"],"additionalProperties":false,"description":"Summed platform engagement across synced posts. Zeros when metrics have not synced yet."}},"required":["totals","delivery","timeline","engagement"],"additionalProperties":false,"description":"Workspace analytics summary."},"AnalyticsTimelinePoint":{"type":"object","properties":{"date":{"type":"string","description":"UTC calendar day (YYYY-MM-DD).","example":"2026-07-18"},"published":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts published that day."}},"required":["date","published"],"additionalProperties":false},"Problem":{"type":"object","properties":{"type":{"type":"string","description":"URI identifying the problem class; resolves to a documentation page.","example":"https://usepostify.com/docs/api/problems/rate-limited"},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code, duplicated from the response line."},"detail":{"description":"Human-readable explanation specific to this occurrence. Never parse it.","type":"string"},"code":{"type":"string","enum":["invalid_request","validation_failed","authentication_required","invalid_api_key","insufficient_scope","feature_not_enabled","dangerous_ops_disabled","resource_not_found","resource_conflict","idempotency_in_progress","idempotency_key_reused","rate_limited","quota_exhausted","internal_error"],"description":"Finite stable machine-readable code — the value SDKs branch on. New codes may appear over time; treat unknown values as a generic error."},"request_id":{"type":"string","description":"Request correlation id, identical to the Request-Id response header. Quote it in support requests.","example":"req_9f2c1e4ab8d64f0e"},"errors":{"description":"Field-level validation errors (validation_failed only).","type":"array","items":{"$ref":"#/components/schemas/ProblemFieldError"}}},"required":["type","title","status","code","request_id"],"additionalProperties":false,"description":"RFC 9457 problem document — every non-2xx /v1 response has this shape with Content-Type application/problem+json."},"ProblemFieldError":{"type":"object","properties":{"pointer":{"type":"string","description":"JSON Pointer to the offending field, e.g. \"/scheduled_at\"."},"code":{"type":"string","description":"Stable machine-readable field-level code."},"message":{"type":"string","description":"Human-readable explanation."}},"required":["pointer","code","message"],"additionalProperties":false},"ChannelList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}},"required":["data"],"additionalProperties":false,"description":"All connected channels for the organization. Not paginated: the channel count is plan-bounded (max 50)."},"Channel":{"type":"object","properties":{"id":{"type":"string","description":"Stable channel identifier. Use it in post variants.","example":"cmc1x2y3z0001abcd"},"platform":{"type":"string","enum":["x","linkedin","facebook","instagram","threads","tiktok","pinterest","youtube","bluesky","reddit","mastodon","telegram","discord"],"description":"Social platform this channel publishes to."},"handle":{"type":"string","description":"Account handle or display name, e.g. \"@postifyhq\"."},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Profile image URL, if the platform provides one."},"followers":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Follower count at last sync, if available."},"status":{"type":"string","enum":["live","reauth_required","rate_limited","disabled"],"description":"Connection health. Only `live` channels can publish; `reauth_required` needs the owner to reconnect in the app."},"last_sync_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When channel metadata was last refreshed (ISO-8601 UTC)."},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Most recent connection error, if any."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the channel was connected (ISO-8601 UTC)."}},"required":["id","platform","handle","avatar_url","followers","status","last_sync_at","last_error","created_at"],"additionalProperties":false,"description":"A connected social account."},"MediaList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MediaAsset"}},"has_more":{"type":"boolean","description":"True when another page exists after `next_cursor`."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected."}},"required":["data","has_more","next_cursor"],"additionalProperties":false,"description":"One page of assets, newest first."},"MediaAsset":{"type":"object","properties":{"id":{"type":"string","description":"Stable asset identifier."},"filename":{"type":"string","description":"Original filename."},"content_type":{"type":"string","description":"MIME type."},"kind":{"type":"string","enum":["image","video","audio","raw"],"description":"Asset kind."},"status":{"type":"string","enum":["pending","ready","failed"],"description":"`pending` until the upload is completed; only `ready` assets should be attached to posts."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Durable URL for the asset — use this as `media[].url` when creating posts. Null until the upload completes."},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Size in bytes."},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixel width, when known."},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixel height, when known."},"duration_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Duration in seconds for audio/video, when known."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the asset was created (ISO-8601 UTC)."}},"required":["id","filename","content_type","kind","status","url","size_bytes","width","height","duration_sec","created_at"],"additionalProperties":false,"description":"A media library asset."},"CreateUploadResponse":{"type":"object","properties":{"asset_id":{"type":"string","description":"The pending asset — complete it after the PUT succeeds."},"upload_url":{"type":"string","description":"Presigned URL. PUT the raw bytes here with the same Content-Type."},"method":{"type":"string","const":"PUT","description":"HTTP method to use."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the presigned URL stops working (ISO-8601 UTC)."}},"required":["asset_id","upload_url","method","expires_at"],"additionalProperties":false,"description":"Upload ticket: PUT the bytes to `upload_url`, then POST /v1/media/uploads/{id}/complete."},"PostList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"has_more":{"type":"boolean","description":"True when another page exists after `next_cursor`."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected."}},"required":["data","has_more","next_cursor"],"additionalProperties":false,"description":"One page of posts, newest first."},"Post":{"type":"object","properties":{"id":{"type":"string","description":"Stable post identifier.","example":"cmc1x2y3z0001abcd"},"status":{"type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"],"description":"Lifecycle state. Consult `deliveries` for per-channel outcomes — a `published` post can still contain failed channels (partial delivery)."},"type":{"type":"string","enum":["single","thread","carousel","long"],"description":"Post format."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Internal title (not published to platforms)."},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Channel-agnostic base text the variants derive from."},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the post is scheduled to publish (ISO-8601 UTC)."},"published_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the post finished publishing (ISO-8601 UTC)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the post was created (ISO-8601 UTC)."},"variants":{"type":"array","items":{"$ref":"#/components/schemas/PostVariant"},"description":"Per-channel variants."},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"},"description":"Latest delivery outcome per channel. Empty until a publish is attempted."}},"required":["id","status","type","title","body","scheduled_at","published_at","created_at","variants","deliveries"],"additionalProperties":false,"description":"A post across one or more channels."},"PostVariant":{"type":"object","properties":{"id":{"type":"string","description":"Variant identifier."},"channel_id":{"type":"string","description":"The channel this variant publishes to (see /v1/channels)."},"body":{"type":"string","description":"The text published to the channel."},"media":{"type":"array","items":{"$ref":"#/components/schemas/PostMediaItemOutput"},"description":"Media attached to this variant."}},"required":["id","channel_id","body","media"],"additionalProperties":false,"description":"Per-channel tailoring of a post."},"Delivery":{"type":"object","properties":{"channel_id":{"type":"string","description":"Channel this delivery targets."},"stage":{"type":"string","enum":["queued","signed","sent","acked","indexed","failed","dlq"],"description":"Latest delivery stage. `indexed`/`acked` are success; `failed`/`dlq` are terminal failures; anything else is in flight."},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The platform's id for the published item, once known."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why the latest delivery failed, as a sentence you can show your users. Present only when `stage` is `failed` or `dlq`; otherwise null."}},"required":["channel_id","stage","external_id","error"],"additionalProperties":false,"description":"Per-channel delivery outcome of a publish."},"DeletePostResponse":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false},"PublishPostResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"],"description":"State after acceptance. Poll GET /v1/posts/{id} for per-channel `deliveries`."}},"required":["id","status"],"additionalProperties":false,"description":"Publish accepted — delivery continues in the background."},"Usage":{"type":"object","properties":{"plan":{"type":"string","description":"The workspace's effective plan tier.","example":"team"},"meters":{"type":"array","items":{"$ref":"#/components/schemas/UsageMeter"},"description":"All plan meters for the workspace."}},"required":["plan","meters"],"additionalProperties":false,"description":"Plan + meter consumption."},"UsageMeter":{"type":"object","properties":{"key":{"type":"string","enum":["posts_per_month","channels","team_members","ai_credits","transcription_minutes","integrations","api_requests"],"description":"Meter name."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consumed in the current period."},"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Plan ceiling for the period. Null means unlimited."},"remaining":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"`limit - used`, floored at 0. Null when unlimited."},"period_starts_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"Current metering period start (ISO-8601 UTC)."},"period_ends_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the meter resets (ISO-8601 UTC). Null when the period is open-ended."}},"required":["key","used","limit","remaining","period_starts_at","period_ends_at"],"additionalProperties":false,"description":"One plan meter."},"WebhookEndpointList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["data"],"additionalProperties":false,"description":"All webhook endpoints for the organization. Not paginated — the endpoint count is plan-bounded by the `integrations` quota."},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","description":"Stable webhook endpoint identifier.","example":"cmc9x2y3z0001abcd"},"url":{"type":"string","description":"HTTPS delivery URL. Private/internal addresses are rejected."},"event_types":{"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types this endpoint subscribes to."},"enabled":{"type":"boolean","description":"Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts."},"auto_disabled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`."},"consecutive_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the endpoint was created (ISO-8601 UTC)."}},"required":["id","url","event_types","enabled","auto_disabled_at","consecutive_failures","created_at"],"additionalProperties":false,"description":"An outbound webhook endpoint (subscriber)."},"WebhookEndpointCreated":{"type":"object","properties":{"id":{"type":"string","description":"Stable webhook endpoint identifier.","example":"cmc9x2y3z0001abcd"},"url":{"type":"string","description":"HTTPS delivery URL. Private/internal addresses are rejected."},"event_types":{"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types this endpoint subscribes to."},"enabled":{"type":"boolean","description":"Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts."},"auto_disabled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`."},"consecutive_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the endpoint was created (ISO-8601 UTC)."},"signing_secret":{"type":"string","description":"Standard-Webhooks signing secret (`whsec_` + base64). Store it now — over the API it is shown only in this response. A workspace owner/admin can re-reveal or roll it in Settings → Webhooks."}},"required":["id","url","event_types","enabled","auto_disabled_at","consecutive_failures","created_at","signing_secret"],"additionalProperties":false,"description":"The created endpoint plus its show-once signing secret. Verify deliveries with any Standard Webhooks library."},"DeleteWebhookEndpointResponse":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false},"TestWebhookEndpointResult":{"type":"object","properties":{"delivery_id":{"type":"string","description":"The recorded delivery attempt."},"succeeded":{"type":"boolean","description":"Whether the endpoint returned a 2xx."},"http_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status returned by the endpoint, or null when the request never completed (timeout, TLS failure, blocked egress)."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Transport-level failure detail when no HTTP response exists."}},"required":["delivery_id","succeeded","http_code","error"],"additionalProperties":false,"description":"Outcome of a synthetic `webhook.test` delivery, signed exactly like a real event."},"PostMediaItemOutput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Media URL. Use the `url` returned by /v1/media assets."},"type":{"type":"string","enum":["image","video"],"description":"Media kind."},"alt":{"description":"Accessibility alt text, where the platform supports it.","anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]}},"required":["url","type"],"additionalProperties":false,"description":"One media attachment."}},"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","description":"Organization API key as a Bearer token (`postify_live_…`)."},"headerApiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Organization API key in the `x-api-key` header."}}}} \ No newline at end of file From 25b4a09184a05928ddd20cae858e80cb29f094ca Mon Sep 17 00:00:00 2001 From: AminDhouib Date: Tue, 20 Oct 2026 00:31:36 -0400 Subject: [PATCH 2/3] chore: sync spec/v1.json from production and add mastodon, telegram, discord platforms --- spec/v1.json | 5207 ++++++++++++++++++++++++++++++++++++- src/postify/models.py | 6 + tests/unit/test_models.py | 4 +- 3 files changed, 5214 insertions(+), 3 deletions(-) diff --git a/spec/v1.json b/spec/v1.json index 80dafee..414cf61 100644 --- a/spec/v1.json +++ b/spec/v1.json @@ -1 +1,5206 @@ -{"openapi":"3.1.0","info":{"title":"Postify API","version":"1.0.0","description":"Postify's public REST API. Authenticate with an organization API key (minted in Settings → API keys) sent as `Authorization: Bearer postify_live_…` or `x-api-key`. Errors are RFC 9457 `application/problem+json` with a stable `code`; every response carries `Request-Id`; API-key responses carry IETF draft-11 rate-limit headers.","contact":{"name":"Postify support","email":"support@usepostify.com"}},"servers":[{"url":"https://app.usepostify.com","description":"Production"}],"tags":[{"name":"Channels","description":"Connected social accounts (the publish targets)."},{"name":"Posts","description":"Create, schedule, publish, and inspect posts across channels."},{"name":"Media","description":"The media library: list assets and upload via presigned PUT."},{"name":"Analytics","description":"Workspace-level publishing and engagement summary."},{"name":"Usage","description":"Plan meters — including your api_requests allowance."},{"name":"Webhooks","description":"Outbound webhook endpoints: Standard-Webhooks-signed event deliveries with retries and a failure ladder."}],"paths":{"/v1/analytics":{"get":{"operationId":"getAnalytics","summary":"Get workspace analytics","description":"Workspace-level publishing summary: post counts, delivery success, a 14-day publish timeline, and summed engagement across synced platforms.","tags":["Analytics"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["analytics:read"],"responses":{"200":{"description":"The analytics summary.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Analytics"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/channels":{"get":{"operationId":"listChannels","summary":"List channels","description":"Lists every social account connected to the organization, with connection health. Use a channel's `id` when creating post variants. Not paginated — the channel count is plan-bounded.","tags":["Channels"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["channels:read"],"responses":{"200":{"description":"The organization's connected channels.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelList"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media":{"get":{"operationId":"listMedia","summary":"List media assets","description":"Lists the organization's media library, newest first, with cursor pagination. Use an asset's `url` as `media[].url` when creating posts.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"query","name":"limit","schema":{"default":25,"description":"Page size (1–100).","type":"integer","minimum":1,"maximum":100},"description":"Page size (1–100)."},{"in":"query","name":"after","schema":{"description":"Opaque cursor from a previous page's `next_cursor`.","type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."}],"responses":{"200":{"description":"One page of media assets.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media/uploads":{"post":{"operationId":"createMediaUpload","summary":"Start a media upload","description":"Issues a presigned upload ticket: PUT the raw file bytes to `upload_url` with the same `Content-Type`, then call POST /v1/media/uploads/{id}/complete. The asset kind (image/video/audio) is inferred from `content_type`.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"}}}},"responses":{"201":{"description":"The upload ticket.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/media/uploads/{id}/complete":{"post":{"operationId":"completeMediaUpload","summary":"Complete a media upload","description":"Finalizes an uploaded asset after the PUT succeeds: probes the object, extracts a poster frame for videos, and marks it `ready`. Safe to retry — finalizing an already-ready asset is a no-op.","tags":["Media"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Asset identifier."},"required":true,"description":"Asset identifier."}],"responses":{"200":{"description":"The finalized asset.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts":{"get":{"operationId":"listPosts","summary":"List posts","description":"Lists the organization's posts, newest first, with cursor pagination. Each post carries its per-channel variants and latest delivery outcomes.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"query","name":"limit","schema":{"default":25,"description":"Page size (1–100).","type":"integer","minimum":1,"maximum":100},"description":"Page size (1–100)."},{"in":"query","name":"after","schema":{"description":"Opaque cursor from a previous page's `next_cursor`.","type":"string"},"description":"Opaque cursor from a previous page's `next_cursor`."},{"in":"query","name":"status","schema":{"description":"Filter by lifecycle state.","type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"]},"description":"Filter by lifecycle state."}],"responses":{"200":{"description":"One page of posts.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createPost","summary":"Create a post","description":"Creates a post with one variant per target channel. Exactly one mode is required: `draft: true` (save only), `scheduled_at` (future publish), or `publish_now: true` (immediate — requires the workspace's dangerous-operations toggle for API callers). Send an `Idempotency-Key` header to make retries safe.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"header","name":"Idempotency-Key","schema":{"description":"Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`.","example":"9f2b6c1e-6a3d-4c1e-9d2f-0b1a2c3d4e5f","type":"string"},"description":"Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"}}}},"responses":{"201":{"description":"The created post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}},"Idempotency-Replayed":{"description":"`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.","schema":{"description":"`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.","example":"true","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`idempotency_in_progress` — A request with this idempotency key is still in progress. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"`idempotency_key_reused` — Idempotency key reused with a different request body. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts/{id}":{"get":{"operationId":"getPost","summary":"Get a post","description":"Fetches one post with its variants and latest per-channel delivery outcomes. Poll this after publishing to track delivery.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:read"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"200":{"description":"The post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"reschedulePost","summary":"Reschedule a post","description":"Moves a draft, scheduled, or failed post to a new future publish time (drafts must already have variants). Published, publishing, and approval-pending posts cannot be rescheduled (409 `resource_conflict`).","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReschedulePostRequest"}}}},"responses":{"200":{"description":"The rescheduled post.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deletePost","summary":"Delete a post","description":"Deletes a post (it disappears from Postify; already-published platform content is not retracted). A post that is currently publishing cannot be deleted (409). Requires the workspace's dangerous-operations toggle.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"200":{"description":"Deletion confirmed.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePostResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/posts/{id}/publish":{"post":{"operationId":"publishPost","summary":"Publish a post now","description":"Queues an immediate publish of a draft, scheduled, or failed post (202 — delivery continues in the background; poll GET /v1/posts/{id} for per-channel outcomes). Already-published posts return 409; a post already publishing is accepted as-is. Requires the workspace's dangerous-operations toggle.","tags":["Posts"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["posts:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Post identifier."},"required":true,"description":"Post identifier."}],"responses":{"202":{"description":"Publish accepted.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPostResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/usage":{"get":{"operationId":"getUsage","summary":"Get plan usage","description":"The workspace's effective plan tier and every plan meter's consumption for the current period — including `api_requests`, the meter every /v1 call consumes.","tags":["Usage"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["analytics:read"],"responses":{"200":{"description":"Plan + meter consumption.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints":{"get":{"operationId":"listWebhookEndpoints","summary":"List webhook endpoints","description":"Lists the organization's webhook endpoints with their subscription and failure-ladder state. Signing secrets are never returned here — they are shown once at creation and can be rolled in Settings → Webhooks.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:read"],"responses":{"200":{"description":"All webhook endpoints for the organization.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createWebhookEndpoint","summary":"Create a webhook endpoint","description":"Registers an HTTPS endpoint for event deliveries. The URL is validated against SSRF at creation AND re-validated at every delivery (loopback, private-network, link-local, and cloud-metadata addresses are rejected — 400 `validation_failed`). The response includes the Standard-Webhooks signing secret exactly once. Endpoint creation counts against the plan's `integrations` quota.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"}}}},"responses":{"201":{"description":"The created endpoint with its show-once signing secret.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints/{id}":{"patch":{"operationId":"updateWebhookEndpoint","summary":"Update a webhook endpoint","description":"Updates the URL (re-validated through the SSRF gauntlet), the event-type subscription list, and/or `enabled`. Setting `enabled: true` on an auto-disabled endpoint clears its failure ladder and resumes deliveries.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointRequest"}}}},"responses":{"200":{"description":"The updated endpoint.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteWebhookEndpoint","summary":"Delete a webhook endpoint","description":"Removes the endpoint and its delivery history. Deliveries stop immediately; this cannot be undone.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"responses":{"200":{"description":"Deletion confirmed.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteWebhookEndpointResponse"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhook-endpoints/{id}/test":{"post":{"operationId":"testWebhookEndpoint","summary":"Send a test delivery","description":"Sends a synthetic `webhook.test` event to the endpoint, signed exactly like a real delivery (Standard-Webhooks headers over the raw body). Use it to verify your signature handling before subscribing to real events. Disabled endpoints return 409 `resource_conflict`.","tags":["Webhooks"],"security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-scopes":["webhooks:write"],"parameters":[{"in":"path","name":"id","schema":{"type":"string","minLength":1,"description":"Webhook endpoint id."},"required":true,"description":"Webhook endpoint id."}],"responses":{"200":{"description":"The test delivery outcome.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}},"RateLimit-Policy":{"description":"IETF draft-11 quota policy for this API key's burst window.","schema":{"description":"IETF draft-11 quota policy for this API key's burst window.","example":"\"per-key-minute\";q=120;w=60","type":"string"}},"RateLimit":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","schema":{"description":"IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.","example":"\"per-key-minute\";r=73;t=38","type":"string"}},"X-RateLimit-Limit":{"description":"Burst-window request limit (compatibility trio).","schema":{"description":"Burst-window request limit (compatibility trio).","example":"120","type":"string"}},"X-RateLimit-Remaining":{"description":"Requests left in the current burst window.","schema":{"description":"Requests left in the current burst window.","example":"73","type":"string"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds when the burst window resets.","schema":{"description":"Unix epoch seconds when the burst window resets.","example":"1800000038","type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestWebhookEndpointResult"}}}},"400":{"description":"`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.","headers":{"Request-Id":{"required":true,"description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","schema":{"type":"string","description":"Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.","example":"req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"CreateUploadRequest":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":256,"description":"Filename including extension.","example":"launch-teaser.mp4"},"content_type":{"type":"string","minLength":1,"maxLength":128,"description":"MIME type of the bytes you will upload.","example":"video/mp4"},"size_bytes":{"description":"Size in bytes, if known.","type":"integer","exclusiveMinimum":0,"maximum":2147483647}},"required":["filename","content_type"]},"CreatePostRequest":{"type":"object","properties":{"variants":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"channel_id":{"type":"string","minLength":1,"description":"A connected channel's `id` (see /v1/channels)."},"body":{"type":"string","minLength":1,"maxLength":63206,"description":"The text to publish to this channel."},"media":{"description":"Media attachments for this channel.","maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/PostMediaItem"}}},"required":["channel_id","body"]},"description":"One variant per target channel."},"title":{"description":"Internal title (not published).","anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"body":{"description":"Optional channel-agnostic base text.","anyOf":[{"type":"string","maxLength":63206},{"type":"null"}]},"draft":{"default":false,"description":"Save as a draft (no scheduling, no publishing).","type":"boolean"},"scheduled_at":{"description":"Future publish time (ISO-8601). Mutually exclusive with `draft` and `publish_now`.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"publish_now":{"default":false,"description":"Publish immediately. Requires the workspace's dangerous-operations toggle for API callers.","type":"boolean"}},"required":["variants"]},"PostMediaItem":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Media URL. Use the `url` returned by /v1/media assets."},"type":{"type":"string","enum":["image","video"],"description":"Media kind."},"alt":{"description":"Accessibility alt text, where the platform supports it.","anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]}},"required":["url","type"],"description":"One media attachment."},"ReschedulePostRequest":{"type":"object","properties":{"scheduled_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"The new future publish time (ISO-8601)."}},"required":["scheduled_at"]},"CreateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL on the default port (443). Loopback, private, link-local, and cloud-metadata addresses are rejected — at creation AND at every delivery.","example":"https://api.example.com/postify/webhooks"},"event_types":{"minItems":1,"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types to subscribe to (at least one)."}},"required":["url","event_types"]},"UpdateWebhookEndpointRequest":{"type":"object","properties":{"url":{"description":"Replacement delivery URL — re-validated through the same SSRF gauntlet as creation.","type":"string","format":"uri"},"event_types":{"description":"Replacement event-type subscription list.","minItems":1,"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]}},"enabled":{"description":"Enable or disable deliveries. Setting `true` on an auto-disabled endpoint clears its failure state and resumes deliveries.","type":"boolean"}},"description":"Partial update — at least one field is required."},"Analytics":{"type":"object","properties":{"totals":{"type":"object","properties":{"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"All posts in the workspace."},"published":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `published` state."},"scheduled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `scheduled` state."},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts in `failed` state."},"channels":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Connected channels."}},"required":["posts","published","scheduled","failed","channels"],"additionalProperties":false,"description":"Workspace-wide counts."},"delivery":{"type":"object","properties":{"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Per-channel delivery attempts recorded."},"success_rate":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}],"description":"Of the SETTLED attempts (acked/indexed vs failed/dlq), the fraction that succeeded. In-flight attempts are excluded; null when nothing has settled yet."}},"required":["attempts","success_rate"],"additionalProperties":false,"description":"Delivery pipeline health."},"timeline":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsTimelinePoint"},"description":"Publishes per UTC day over the last 14 days."},"engagement":{"type":"object","properties":{"impressions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"comments":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"shares":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"clicks":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["impressions","likes","comments","shares","clicks"],"additionalProperties":false,"description":"Summed platform engagement across synced posts. Zeros when metrics have not synced yet."}},"required":["totals","delivery","timeline","engagement"],"additionalProperties":false,"description":"Workspace analytics summary."},"AnalyticsTimelinePoint":{"type":"object","properties":{"date":{"type":"string","description":"UTC calendar day (YYYY-MM-DD).","example":"2026-07-18"},"published":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts published that day."}},"required":["date","published"],"additionalProperties":false},"Problem":{"type":"object","properties":{"type":{"type":"string","description":"URI identifying the problem class; resolves to a documentation page.","example":"https://usepostify.com/docs/api/problems/rate-limited"},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code, duplicated from the response line."},"detail":{"description":"Human-readable explanation specific to this occurrence. Never parse it.","type":"string"},"code":{"type":"string","enum":["invalid_request","validation_failed","authentication_required","invalid_api_key","insufficient_scope","feature_not_enabled","dangerous_ops_disabled","resource_not_found","resource_conflict","idempotency_in_progress","idempotency_key_reused","rate_limited","quota_exhausted","internal_error"],"description":"Finite stable machine-readable code — the value SDKs branch on. New codes may appear over time; treat unknown values as a generic error."},"request_id":{"type":"string","description":"Request correlation id, identical to the Request-Id response header. Quote it in support requests.","example":"req_9f2c1e4ab8d64f0e"},"errors":{"description":"Field-level validation errors (validation_failed only).","type":"array","items":{"$ref":"#/components/schemas/ProblemFieldError"}}},"required":["type","title","status","code","request_id"],"additionalProperties":false,"description":"RFC 9457 problem document — every non-2xx /v1 response has this shape with Content-Type application/problem+json."},"ProblemFieldError":{"type":"object","properties":{"pointer":{"type":"string","description":"JSON Pointer to the offending field, e.g. \"/scheduled_at\"."},"code":{"type":"string","description":"Stable machine-readable field-level code."},"message":{"type":"string","description":"Human-readable explanation."}},"required":["pointer","code","message"],"additionalProperties":false},"ChannelList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}},"required":["data"],"additionalProperties":false,"description":"All connected channels for the organization. Not paginated: the channel count is plan-bounded (max 50)."},"Channel":{"type":"object","properties":{"id":{"type":"string","description":"Stable channel identifier. Use it in post variants.","example":"cmc1x2y3z0001abcd"},"platform":{"type":"string","enum":["x","linkedin","facebook","instagram","threads","tiktok","pinterest","youtube","bluesky","reddit","mastodon","telegram","discord"],"description":"Social platform this channel publishes to."},"handle":{"type":"string","description":"Account handle or display name, e.g. \"@postifyhq\"."},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Profile image URL, if the platform provides one."},"followers":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Follower count at last sync, if available."},"status":{"type":"string","enum":["live","reauth_required","rate_limited","disabled"],"description":"Connection health. Only `live` channels can publish; `reauth_required` needs the owner to reconnect in the app."},"last_sync_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When channel metadata was last refreshed (ISO-8601 UTC)."},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Most recent connection error, if any."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the channel was connected (ISO-8601 UTC)."}},"required":["id","platform","handle","avatar_url","followers","status","last_sync_at","last_error","created_at"],"additionalProperties":false,"description":"A connected social account."},"MediaList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MediaAsset"}},"has_more":{"type":"boolean","description":"True when another page exists after `next_cursor`."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected."}},"required":["data","has_more","next_cursor"],"additionalProperties":false,"description":"One page of assets, newest first."},"MediaAsset":{"type":"object","properties":{"id":{"type":"string","description":"Stable asset identifier."},"filename":{"type":"string","description":"Original filename."},"content_type":{"type":"string","description":"MIME type."},"kind":{"type":"string","enum":["image","video","audio","raw"],"description":"Asset kind."},"status":{"type":"string","enum":["pending","ready","failed"],"description":"`pending` until the upload is completed; only `ready` assets should be attached to posts."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Durable URL for the asset — use this as `media[].url` when creating posts. Null until the upload completes."},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Size in bytes."},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixel width, when known."},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixel height, when known."},"duration_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Duration in seconds for audio/video, when known."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the asset was created (ISO-8601 UTC)."}},"required":["id","filename","content_type","kind","status","url","size_bytes","width","height","duration_sec","created_at"],"additionalProperties":false,"description":"A media library asset."},"CreateUploadResponse":{"type":"object","properties":{"asset_id":{"type":"string","description":"The pending asset — complete it after the PUT succeeds."},"upload_url":{"type":"string","description":"Presigned URL. PUT the raw bytes here with the same Content-Type."},"method":{"type":"string","const":"PUT","description":"HTTP method to use."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the presigned URL stops working (ISO-8601 UTC)."}},"required":["asset_id","upload_url","method","expires_at"],"additionalProperties":false,"description":"Upload ticket: PUT the bytes to `upload_url`, then POST /v1/media/uploads/{id}/complete."},"PostList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"has_more":{"type":"boolean","description":"True when another page exists after `next_cursor`."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected."}},"required":["data","has_more","next_cursor"],"additionalProperties":false,"description":"One page of posts, newest first."},"Post":{"type":"object","properties":{"id":{"type":"string","description":"Stable post identifier.","example":"cmc1x2y3z0001abcd"},"status":{"type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"],"description":"Lifecycle state. Consult `deliveries` for per-channel outcomes — a `published` post can still contain failed channels (partial delivery)."},"type":{"type":"string","enum":["single","thread","carousel","long"],"description":"Post format."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Internal title (not published to platforms)."},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Channel-agnostic base text the variants derive from."},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the post is scheduled to publish (ISO-8601 UTC)."},"published_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the post finished publishing (ISO-8601 UTC)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the post was created (ISO-8601 UTC)."},"variants":{"type":"array","items":{"$ref":"#/components/schemas/PostVariant"},"description":"Per-channel variants."},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"},"description":"Latest delivery outcome per channel. Empty until a publish is attempted."}},"required":["id","status","type","title","body","scheduled_at","published_at","created_at","variants","deliveries"],"additionalProperties":false,"description":"A post across one or more channels."},"PostVariant":{"type":"object","properties":{"id":{"type":"string","description":"Variant identifier."},"channel_id":{"type":"string","description":"The channel this variant publishes to (see /v1/channels)."},"body":{"type":"string","description":"The text published to the channel."},"media":{"type":"array","items":{"$ref":"#/components/schemas/PostMediaItemOutput"},"description":"Media attached to this variant."}},"required":["id","channel_id","body","media"],"additionalProperties":false,"description":"Per-channel tailoring of a post."},"Delivery":{"type":"object","properties":{"channel_id":{"type":"string","description":"Channel this delivery targets."},"stage":{"type":"string","enum":["queued","signed","sent","acked","indexed","failed","dlq"],"description":"Latest delivery stage. `indexed`/`acked` are success; `failed`/`dlq` are terminal failures; anything else is in flight."},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The platform's id for the published item, once known."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why the latest delivery failed, as a sentence you can show your users. Present only when `stage` is `failed` or `dlq`; otherwise null."}},"required":["channel_id","stage","external_id","error"],"additionalProperties":false,"description":"Per-channel delivery outcome of a publish."},"DeletePostResponse":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false},"PublishPostResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","publishing","published","failed","needs_approval"],"description":"State after acceptance. Poll GET /v1/posts/{id} for per-channel `deliveries`."}},"required":["id","status"],"additionalProperties":false,"description":"Publish accepted — delivery continues in the background."},"Usage":{"type":"object","properties":{"plan":{"type":"string","description":"The workspace's effective plan tier.","example":"team"},"meters":{"type":"array","items":{"$ref":"#/components/schemas/UsageMeter"},"description":"All plan meters for the workspace."}},"required":["plan","meters"],"additionalProperties":false,"description":"Plan + meter consumption."},"UsageMeter":{"type":"object","properties":{"key":{"type":"string","enum":["posts_per_month","channels","team_members","ai_credits","transcription_minutes","integrations","api_requests"],"description":"Meter name."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consumed in the current period."},"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Plan ceiling for the period. Null means unlimited."},"remaining":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"`limit - used`, floored at 0. Null when unlimited."},"period_starts_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"Current metering period start (ISO-8601 UTC)."},"period_ends_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the meter resets (ISO-8601 UTC). Null when the period is open-ended."}},"required":["key","used","limit","remaining","period_starts_at","period_ends_at"],"additionalProperties":false,"description":"One plan meter."},"WebhookEndpointList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["data"],"additionalProperties":false,"description":"All webhook endpoints for the organization. Not paginated — the endpoint count is plan-bounded by the `integrations` quota."},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","description":"Stable webhook endpoint identifier.","example":"cmc9x2y3z0001abcd"},"url":{"type":"string","description":"HTTPS delivery URL. Private/internal addresses are rejected."},"event_types":{"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types this endpoint subscribes to."},"enabled":{"type":"boolean","description":"Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts."},"auto_disabled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`."},"consecutive_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the endpoint was created (ISO-8601 UTC)."}},"required":["id","url","event_types","enabled","auto_disabled_at","consecutive_failures","created_at"],"additionalProperties":false,"description":"An outbound webhook endpoint (subscriber)."},"WebhookEndpointCreated":{"type":"object","properties":{"id":{"type":"string","description":"Stable webhook endpoint identifier.","example":"cmc9x2y3z0001abcd"},"url":{"type":"string","description":"HTTPS delivery URL. Private/internal addresses are rejected."},"event_types":{"type":"array","items":{"type":"string","enum":["post.published","post.failed","channel.connected","channel.reauth_required","delivery.failed"]},"description":"Event types this endpoint subscribes to."},"enabled":{"type":"boolean","description":"Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts."},"auto_disabled_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}],"description":"When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`."},"consecutive_failures":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","description":"When the endpoint was created (ISO-8601 UTC)."},"signing_secret":{"type":"string","description":"Standard-Webhooks signing secret (`whsec_` + base64). Store it now — over the API it is shown only in this response. A workspace owner/admin can re-reveal or roll it in Settings → Webhooks."}},"required":["id","url","event_types","enabled","auto_disabled_at","consecutive_failures","created_at","signing_secret"],"additionalProperties":false,"description":"The created endpoint plus its show-once signing secret. Verify deliveries with any Standard Webhooks library."},"DeleteWebhookEndpointResponse":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false},"TestWebhookEndpointResult":{"type":"object","properties":{"delivery_id":{"type":"string","description":"The recorded delivery attempt."},"succeeded":{"type":"boolean","description":"Whether the endpoint returned a 2xx."},"http_code":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"HTTP status returned by the endpoint, or null when the request never completed (timeout, TLS failure, blocked egress)."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Transport-level failure detail when no HTTP response exists."}},"required":["delivery_id","succeeded","http_code","error"],"additionalProperties":false,"description":"Outcome of a synthetic `webhook.test` delivery, signed exactly like a real event."},"PostMediaItemOutput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Media URL. Use the `url` returned by /v1/media assets."},"type":{"type":"string","enum":["image","video"],"description":"Media kind."},"alt":{"description":"Accessibility alt text, where the platform supports it.","anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]}},"required":["url","type"],"additionalProperties":false,"description":"One media attachment."}},"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","description":"Organization API key as a Bearer token (`postify_live_…`)."},"headerApiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Organization API key in the `x-api-key` header."}}}} \ No newline at end of file +{ + "openapi": "3.1.0", + "info": { + "title": "Postify API", + "version": "1.0.0", + "description": "Postify's public REST API. Authenticate with an organization API key (minted in Settings → API keys) sent as `Authorization: Bearer postify_live_…` or `x-api-key`. Errors are RFC 9457 `application/problem+json` with a stable `code`; every response carries `Request-Id`; API-key responses carry IETF draft-11 rate-limit headers.", + "contact": { + "name": "Postify support", + "email": "support@usepostify.com" + } + }, + "servers": [ + { + "url": "https://app.usepostify.com", + "description": "Production" + } + ], + "tags": [ + { + "name": "Channels", + "description": "Connected social accounts (the publish targets)." + }, + { + "name": "Posts", + "description": "Create, schedule, publish, and inspect posts across channels." + }, + { + "name": "Media", + "description": "The media library: list assets and upload via presigned PUT." + }, + { + "name": "Analytics", + "description": "Workspace-level publishing and engagement summary." + }, + { + "name": "Usage", + "description": "Plan meters — including your api_requests allowance." + }, + { + "name": "Webhooks", + "description": "Outbound webhook endpoints: Standard-Webhooks-signed event deliveries with retries and a failure ladder." + } + ], + "paths": { + "/v1/analytics": { + "get": { + "operationId": "getAnalytics", + "summary": "Get workspace analytics", + "description": "Workspace-level publishing summary: post counts, delivery success, a 14-day publish timeline, and summed engagement across synced platforms.", + "tags": [ + "Analytics" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "analytics:read" + ], + "responses": { + "200": { + "description": "The analytics summary.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/channels": { + "get": { + "operationId": "listChannels", + "summary": "List channels", + "description": "Lists every social account connected to the organization, with connection health. Use a channel's `id` when creating post variants. Not paginated — the channel count is plan-bounded.", + "tags": [ + "Channels" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "channels:read" + ], + "responses": { + "200": { + "description": "The organization's connected channels.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChannelList" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/media": { + "get": { + "operationId": "listMedia", + "summary": "List media assets", + "description": "Lists the organization's media library, newest first, with cursor pagination. Use an asset's `url` as `media[].url` when creating posts.", + "tags": [ + "Media" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:read" + ], + "parameters": [ + { + "in": "query", + "name": "limit", + "schema": { + "default": 25, + "description": "Page size (1–100).", + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "description": "Page size (1–100)." + }, + { + "in": "query", + "name": "after", + "schema": { + "description": "Opaque cursor from a previous page's `next_cursor`.", + "type": "string" + }, + "description": "Opaque cursor from a previous page's `next_cursor`." + } + ], + "responses": { + "200": { + "description": "One page of media assets.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaList" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/media/uploads": { + "post": { + "operationId": "createMediaUpload", + "summary": "Start a media upload", + "description": "Issues a presigned upload ticket: PUT the raw file bytes to `upload_url` with the same `Content-Type`, then call POST /v1/media/uploads/{id}/complete. The asset kind (image/video/audio) is inferred from `content_type`.", + "tags": [ + "Media" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateUploadRequest" + } + } + } + }, + "responses": { + "201": { + "description": "The upload ticket.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateUploadResponse" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/media/uploads/{id}/complete": { + "post": { + "operationId": "completeMediaUpload", + "summary": "Complete a media upload", + "description": "Finalizes an uploaded asset after the PUT succeeds: probes the object, extracts a poster frame for videos, and marks it `ready`. Safe to retry — finalizing an already-ready asset is a no-op.", + "tags": [ + "Media" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Asset identifier." + }, + "required": true, + "description": "Asset identifier." + } + ], + "responses": { + "200": { + "description": "The finalized asset.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaAsset" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/posts": { + "get": { + "operationId": "listPosts", + "summary": "List posts", + "description": "Lists the organization's posts, newest first, with cursor pagination. Each post carries its per-channel variants and latest delivery outcomes.", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:read" + ], + "parameters": [ + { + "in": "query", + "name": "limit", + "schema": { + "default": 25, + "description": "Page size (1–100).", + "type": "integer", + "minimum": 1, + "maximum": 100 + }, + "description": "Page size (1–100)." + }, + { + "in": "query", + "name": "after", + "schema": { + "description": "Opaque cursor from a previous page's `next_cursor`.", + "type": "string" + }, + "description": "Opaque cursor from a previous page's `next_cursor`." + }, + { + "in": "query", + "name": "status", + "schema": { + "description": "Filter by lifecycle state.", + "type": "string", + "enum": [ + "draft", + "scheduled", + "publishing", + "published", + "failed", + "needs_approval" + ] + }, + "description": "Filter by lifecycle state." + } + ], + "responses": { + "200": { + "description": "One page of posts.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PostList" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "post": { + "operationId": "createPost", + "summary": "Create a post", + "description": "Creates a post with one variant per target channel. Exactly one mode is required: `draft: true` (save only), `scheduled_at` (future publish), or `publish_now: true` (immediate — requires the workspace's dangerous-operations toggle for API callers). Send an `Idempotency-Key` header to make retries safe.", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "parameters": [ + { + "in": "header", + "name": "Idempotency-Key", + "schema": { + "description": "Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`.", + "example": "9f2b6c1e-6a3d-4c1e-9d2f-0b1a2c3d4e5f", + "type": "string" + }, + "description": "Client-chosen key (1–255 printable ASCII chars, e.g. a UUID) making this POST safely retryable: within 24h, the same key + same body replays the original response with `Idempotency-Replayed: true`; the same key with a DIFFERENT body is rejected with 422 `idempotency_key_reused`." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreatePostRequest" + } + } + } + }, + "responses": { + "201": { + "description": "The created post.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + }, + "Idempotency-Replayed": { + "description": "`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.", + "schema": { + "description": "`true` when this response was replayed verbatim from the idempotency ledger instead of re-executing the request.", + "example": "true", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Post" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`idempotency_in_progress` — A request with this idempotency key is still in progress. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "422": { + "description": "`idempotency_key_reused` — Idempotency key reused with a different request body. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/posts/{id}": { + "get": { + "operationId": "getPost", + "summary": "Get a post", + "description": "Fetches one post with its variants and latest per-channel delivery outcomes. Poll this after publishing to track delivery.", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:read" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Post identifier." + }, + "required": true, + "description": "Post identifier." + } + ], + "responses": { + "200": { + "description": "The post.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Post" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "patch": { + "operationId": "reschedulePost", + "summary": "Reschedule a post", + "description": "Moves a draft, scheduled, or failed post to a new future publish time (drafts must already have variants). Published, publishing, and approval-pending posts cannot be rescheduled (409 `resource_conflict`).", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Post identifier." + }, + "required": true, + "description": "Post identifier." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReschedulePostRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The rescheduled post.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Post" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "delete": { + "operationId": "deletePost", + "summary": "Delete a post", + "description": "Deletes a post (it disappears from Postify; already-published platform content is not retracted). A post that is currently publishing cannot be deleted (409). Requires the workspace's dangerous-operations toggle.", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Post identifier." + }, + "required": true, + "description": "Post identifier." + } + ], + "responses": { + "200": { + "description": "Deletion confirmed.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeletePostResponse" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/posts/{id}/publish": { + "post": { + "operationId": "publishPost", + "summary": "Publish a post now", + "description": "Queues an immediate publish of a draft, scheduled, or failed post (202 — delivery continues in the background; poll GET /v1/posts/{id} for per-channel outcomes). Already-published posts return 409; a post already publishing is accepted as-is. Requires the workspace's dangerous-operations toggle.", + "tags": [ + "Posts" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "posts:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Post identifier." + }, + "required": true, + "description": "Post identifier." + } + ], + "responses": { + "202": { + "description": "Publish accepted.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishPostResponse" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan; `dangerous_ops_disabled` — Dangerous AI operations are disabled for this workspace. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/usage": { + "get": { + "operationId": "getUsage", + "summary": "Get plan usage", + "description": "The workspace's effective plan tier and every plan meter's consumption for the current period — including `api_requests`, the meter every /v1 call consumes.", + "tags": [ + "Usage" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "analytics:read" + ], + "responses": { + "200": { + "description": "Plan + meter consumption.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Usage" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/webhook-endpoints": { + "get": { + "operationId": "listWebhookEndpoints", + "summary": "List webhook endpoints", + "description": "Lists the organization's webhook endpoints with their subscription and failure-ladder state. Signing secrets are never returned here — they are shown once at creation and can be rolled in Settings → Webhooks.", + "tags": [ + "Webhooks" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "webhooks:read" + ], + "responses": { + "200": { + "description": "All webhook endpoints for the organization.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebhookEndpointList" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "post": { + "operationId": "createWebhookEndpoint", + "summary": "Create a webhook endpoint", + "description": "Registers an HTTPS endpoint for event deliveries. The URL is validated against SSRF at creation AND re-validated at every delivery (loopback, private-network, link-local, and cloud-metadata addresses are rejected — 400 `validation_failed`). The response includes the Standard-Webhooks signing secret exactly once. Endpoint creation counts against the plan's `integrations` quota.", + "tags": [ + "Webhooks" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "webhooks:write" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWebhookEndpointRequest" + } + } + } + }, + "responses": { + "201": { + "description": "The created endpoint with its show-once signing secret.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebhookEndpointCreated" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/webhook-endpoints/{id}": { + "patch": { + "operationId": "updateWebhookEndpoint", + "summary": "Update a webhook endpoint", + "description": "Updates the URL (re-validated through the SSRF gauntlet), the event-type subscription list, and/or `enabled`. Setting `enabled: true` on an auto-disabled endpoint clears its failure ladder and resumes deliveries.", + "tags": [ + "Webhooks" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "webhooks:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Webhook endpoint id." + }, + "required": true, + "description": "Webhook endpoint id." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The updated endpoint.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebhookEndpoint" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "delete": { + "operationId": "deleteWebhookEndpoint", + "summary": "Delete a webhook endpoint", + "description": "Removes the endpoint and its delivery history. Deliveries stop immediately; this cannot be undone.", + "tags": [ + "Webhooks" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "webhooks:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Webhook endpoint id." + }, + "required": true, + "description": "Webhook endpoint id." + } + ], + "responses": { + "200": { + "description": "Deletion confirmed.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteWebhookEndpointResponse" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + }, + "/v1/webhook-endpoints/{id}/test": { + "post": { + "operationId": "testWebhookEndpoint", + "summary": "Send a test delivery", + "description": "Sends a synthetic `webhook.test` event to the endpoint, signed exactly like a real delivery (Standard-Webhooks headers over the raw body). Use it to verify your signature handling before subscribing to real events. Disabled endpoints return 409 `resource_conflict`.", + "tags": [ + "Webhooks" + ], + "security": [ + { + "bearerApiKey": [] + }, + { + "headerApiKey": [] + } + ], + "x-scopes": [ + "webhooks:write" + ], + "parameters": [ + { + "in": "path", + "name": "id", + "schema": { + "type": "string", + "minLength": 1, + "description": "Webhook endpoint id." + }, + "required": true, + "description": "Webhook endpoint id." + } + ], + "responses": { + "200": { + "description": "The test delivery outcome.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + }, + "RateLimit-Policy": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "schema": { + "description": "IETF draft-11 quota policy for this API key's burst window.", + "example": "\"per-key-minute\";q=120;w=60", + "type": "string" + } + }, + "RateLimit": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "schema": { + "description": "IETF draft-11 current window state (r = remaining, t = seconds until reset). Omitted when the window state was not observable on this request — never invented.", + "example": "\"per-key-minute\";r=73;t=38", + "type": "string" + } + }, + "X-RateLimit-Limit": { + "description": "Burst-window request limit (compatibility trio).", + "schema": { + "description": "Burst-window request limit (compatibility trio).", + "example": "120", + "type": "string" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current burst window.", + "schema": { + "description": "Requests left in the current burst window.", + "example": "73", + "type": "string" + } + }, + "X-RateLimit-Reset": { + "description": "Unix epoch seconds when the burst window resets.", + "schema": { + "description": "Unix epoch seconds when the burst window resets.", + "example": "1800000038", + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestWebhookEndpointResult" + } + } + } + }, + "400": { + "description": "`invalid_request` — Invalid request; `validation_failed` — Request validation failed. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "401": { + "description": "`authentication_required` — Authentication required; `invalid_api_key` — Invalid API key. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "403": { + "description": "`insufficient_scope` — API credential lacks the required scope; `feature_not_enabled` — Feature not available on the current plan. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "404": { + "description": "`resource_not_found` — Resource not found. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "409": { + "description": "`resource_conflict` — Resource state conflicts with the request. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "429": { + "description": "`rate_limited` — Rate limit exceeded; `quota_exhausted` — Plan quota exhausted for this billing period. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "500": { + "description": "`internal_error` — Internal server error. RFC 9457 problem body; `code` is the machine-readable discriminant.", + "headers": { + "Request-Id": { + "required": true, + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "schema": { + "type": "string", + "description": "Correlation id for this request — echoes a valid inbound `x-request-id`, otherwise a server-minted `req_…` id. Quote it when contacting support.", + "example": "req_6f1f8a2b40d34cd2a6f1e2c9b8d7a601" + } + } + }, + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "CreateUploadRequest": { + "type": "object", + "properties": { + "filename": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Filename including extension.", + "example": "launch-teaser.mp4" + }, + "content_type": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "MIME type of the bytes you will upload.", + "example": "video/mp4" + }, + "size_bytes": { + "description": "Size in bytes, if known.", + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 2147483647 + } + }, + "required": [ + "filename", + "content_type" + ] + }, + "CreatePostRequest": { + "type": "object", + "properties": { + "variants": { + "minItems": 1, + "maxItems": 20, + "type": "array", + "items": { + "type": "object", + "properties": { + "channel_id": { + "type": "string", + "minLength": 1, + "description": "A connected channel's `id` (see /v1/channels)." + }, + "body": { + "type": "string", + "minLength": 1, + "maxLength": 63206, + "description": "The text to publish to this channel." + }, + "media": { + "description": "Media attachments for this channel.", + "maxItems": 20, + "type": "array", + "items": { + "$ref": "#/components/schemas/PostMediaItem" + } + } + }, + "required": [ + "channel_id", + "body" + ] + }, + "description": "One variant per target channel." + }, + "title": { + "description": "Internal title (not published).", + "anyOf": [ + { + "type": "string", + "maxLength": 300 + }, + { + "type": "null" + } + ] + }, + "body": { + "description": "Optional channel-agnostic base text.", + "anyOf": [ + { + "type": "string", + "maxLength": 63206 + }, + { + "type": "null" + } + ] + }, + "draft": { + "default": false, + "description": "Save as a draft (no scheduling, no publishing).", + "type": "boolean" + }, + "scheduled_at": { + "description": "Future publish time (ISO-8601). Mutually exclusive with `draft` and `publish_now`.", + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$" + }, + "publish_now": { + "default": false, + "description": "Publish immediately. Requires the workspace's dangerous-operations toggle for API callers.", + "type": "boolean" + } + }, + "required": [ + "variants" + ] + }, + "PostMediaItem": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Media URL. Use the `url` returned by /v1/media assets." + }, + "type": { + "type": "string", + "enum": [ + "image", + "video" + ], + "description": "Media kind." + }, + "alt": { + "description": "Accessibility alt text, where the platform supports it.", + "anyOf": [ + { + "type": "string", + "maxLength": 1000 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "url", + "type" + ], + "description": "One media attachment." + }, + "ReschedulePostRequest": { + "type": "object", + "properties": { + "scheduled_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "description": "The new future publish time (ISO-8601)." + } + }, + "required": [ + "scheduled_at" + ] + }, + "CreateWebhookEndpointRequest": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "HTTPS URL on the default port (443). Loopback, private, link-local, and cloud-metadata addresses are rejected — at creation AND at every delivery.", + "example": "https://api.example.com/postify/webhooks" + }, + "event_types": { + "minItems": 1, + "type": "array", + "items": { + "type": "string", + "enum": [ + "post.published", + "post.failed", + "channel.connected", + "channel.reauth_required", + "delivery.failed" + ] + }, + "description": "Event types to subscribe to (at least one)." + } + }, + "required": [ + "url", + "event_types" + ] + }, + "UpdateWebhookEndpointRequest": { + "type": "object", + "properties": { + "url": { + "description": "Replacement delivery URL — re-validated through the same SSRF gauntlet as creation.", + "type": "string", + "format": "uri" + }, + "event_types": { + "description": "Replacement event-type subscription list.", + "minItems": 1, + "type": "array", + "items": { + "type": "string", + "enum": [ + "post.published", + "post.failed", + "channel.connected", + "channel.reauth_required", + "delivery.failed" + ] + } + }, + "enabled": { + "description": "Enable or disable deliveries. Setting `true` on an auto-disabled endpoint clears its failure state and resumes deliveries.", + "type": "boolean" + } + }, + "description": "Partial update — at least one field is required." + }, + "Analytics": { + "type": "object", + "properties": { + "totals": { + "type": "object", + "properties": { + "posts": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "All posts in the workspace." + }, + "published": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Posts in `published` state." + }, + "scheduled": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Posts in `scheduled` state." + }, + "failed": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Posts in `failed` state." + }, + "channels": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Connected channels." + } + }, + "required": [ + "posts", + "published", + "scheduled", + "failed", + "channels" + ], + "additionalProperties": false, + "description": "Workspace-wide counts." + }, + "delivery": { + "type": "object", + "properties": { + "attempts": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Per-channel delivery attempts recorded." + }, + "success_rate": { + "anyOf": [ + { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + { + "type": "null" + } + ], + "description": "Of the SETTLED attempts (acked/indexed vs failed/dlq), the fraction that succeeded. In-flight attempts are excluded; null when nothing has settled yet." + } + }, + "required": [ + "attempts", + "success_rate" + ], + "additionalProperties": false, + "description": "Delivery pipeline health." + }, + "timeline": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsTimelinePoint" + }, + "description": "Publishes per UTC day over the last 14 days." + }, + "engagement": { + "type": "object", + "properties": { + "impressions": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "likes": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "comments": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "shares": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "clicks": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": [ + "impressions", + "likes", + "comments", + "shares", + "clicks" + ], + "additionalProperties": false, + "description": "Summed platform engagement across synced posts. Zeros when metrics have not synced yet." + } + }, + "required": [ + "totals", + "delivery", + "timeline", + "engagement" + ], + "additionalProperties": false, + "description": "Workspace analytics summary." + }, + "AnalyticsTimelinePoint": { + "type": "object", + "properties": { + "date": { + "type": "string", + "description": "UTC calendar day (YYYY-MM-DD).", + "example": "2026-07-18" + }, + "published": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Posts published that day." + } + }, + "required": [ + "date", + "published" + ], + "additionalProperties": false + }, + "Problem": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "URI identifying the problem class; resolves to a documentation page.", + "example": "https://usepostify.com/docs/api/problems/rate-limited" + }, + "title": { + "type": "string", + "description": "Short human-readable summary of the problem class." + }, + "status": { + "type": "integer", + "minimum": 400, + "maximum": 599, + "description": "HTTP status code, duplicated from the response line." + }, + "detail": { + "description": "Human-readable explanation specific to this occurrence. Never parse it.", + "type": "string" + }, + "code": { + "type": "string", + "enum": [ + "invalid_request", + "validation_failed", + "authentication_required", + "invalid_api_key", + "insufficient_scope", + "feature_not_enabled", + "dangerous_ops_disabled", + "resource_not_found", + "resource_conflict", + "idempotency_in_progress", + "idempotency_key_reused", + "rate_limited", + "quota_exhausted", + "internal_error" + ], + "description": "Finite stable machine-readable code — the value SDKs branch on. New codes may appear over time; treat unknown values as a generic error." + }, + "request_id": { + "type": "string", + "description": "Request correlation id, identical to the Request-Id response header. Quote it in support requests.", + "example": "req_9f2c1e4ab8d64f0e" + }, + "errors": { + "description": "Field-level validation errors (validation_failed only).", + "type": "array", + "items": { + "$ref": "#/components/schemas/ProblemFieldError" + } + } + }, + "required": [ + "type", + "title", + "status", + "code", + "request_id" + ], + "additionalProperties": false, + "description": "RFC 9457 problem document — every non-2xx /v1 response has this shape with Content-Type application/problem+json." + }, + "ProblemFieldError": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "description": "JSON Pointer to the offending field, e.g. \"/scheduled_at\"." + }, + "code": { + "type": "string", + "description": "Stable machine-readable field-level code." + }, + "message": { + "type": "string", + "description": "Human-readable explanation." + } + }, + "required": [ + "pointer", + "code", + "message" + ], + "additionalProperties": false + }, + "ChannelList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Channel" + } + } + }, + "required": [ + "data" + ], + "additionalProperties": false, + "description": "All connected channels for the organization. Not paginated: the channel count is plan-bounded (max 50)." + }, + "Channel": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable channel identifier. Use it in post variants.", + "example": "cmc1x2y3z0001abcd" + }, + "platform": { + "type": "string", + "enum": [ + "x", + "linkedin", + "facebook", + "instagram", + "threads", + "tiktok", + "pinterest", + "youtube", + "bluesky", + "reddit", + "mastodon", + "telegram", + "discord" + ], + "description": "Social platform this channel publishes to." + }, + "handle": { + "type": "string", + "description": "Account handle or display name, e.g. \"@postifyhq\"." + }, + "avatar_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Profile image URL, if the platform provides one." + }, + "followers": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "Follower count at last sync, if available." + }, + "status": { + "type": "string", + "enum": [ + "live", + "reauth_required", + "rate_limited", + "disabled" + ], + "description": "Connection health. Only `live` channels can publish; `reauth_required` needs the owner to reconnect in the app." + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When channel metadata was last refreshed (ISO-8601 UTC)." + }, + "last_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Most recent connection error, if any." + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the channel was connected (ISO-8601 UTC)." + } + }, + "required": [ + "id", + "platform", + "handle", + "avatar_url", + "followers", + "status", + "last_sync_at", + "last_error", + "created_at" + ], + "additionalProperties": false, + "description": "A connected social account." + }, + "MediaList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MediaAsset" + } + }, + "has_more": { + "type": "boolean", + "description": "True when another page exists after `next_cursor`." + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected." + } + }, + "required": [ + "data", + "has_more", + "next_cursor" + ], + "additionalProperties": false, + "description": "One page of assets, newest first." + }, + "MediaAsset": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable asset identifier." + }, + "filename": { + "type": "string", + "description": "Original filename." + }, + "content_type": { + "type": "string", + "description": "MIME type." + }, + "kind": { + "type": "string", + "enum": [ + "image", + "video", + "audio", + "raw" + ], + "description": "Asset kind." + }, + "status": { + "type": "string", + "enum": [ + "pending", + "ready", + "failed" + ], + "description": "`pending` until the upload is completed; only `ready` assets should be attached to posts." + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Durable URL for the asset — use this as `media[].url` when creating posts. Null until the upload completes." + }, + "size_bytes": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "Size in bytes." + }, + "width": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "Pixel width, when known." + }, + "height": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "Pixel height, when known." + }, + "duration_sec": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Duration in seconds for audio/video, when known." + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the asset was created (ISO-8601 UTC)." + } + }, + "required": [ + "id", + "filename", + "content_type", + "kind", + "status", + "url", + "size_bytes", + "width", + "height", + "duration_sec", + "created_at" + ], + "additionalProperties": false, + "description": "A media library asset." + }, + "CreateUploadResponse": { + "type": "object", + "properties": { + "asset_id": { + "type": "string", + "description": "The pending asset — complete it after the PUT succeeds." + }, + "upload_url": { + "type": "string", + "description": "Presigned URL. PUT the raw bytes here with the same Content-Type." + }, + "method": { + "type": "string", + "const": "PUT", + "description": "HTTP method to use." + }, + "expires_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the presigned URL stops working (ISO-8601 UTC)." + } + }, + "required": [ + "asset_id", + "upload_url", + "method", + "expires_at" + ], + "additionalProperties": false, + "description": "Upload ticket: PUT the bytes to `upload_url`, then POST /v1/media/uploads/{id}/complete." + }, + "PostList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Post" + } + }, + "has_more": { + "type": "boolean", + "description": "True when another page exists after `next_cursor`." + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor for the next page — pass as `after`. Reusing a cursor with a different query is rejected." + } + }, + "required": [ + "data", + "has_more", + "next_cursor" + ], + "additionalProperties": false, + "description": "One page of posts, newest first." + }, + "Post": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable post identifier.", + "example": "cmc1x2y3z0001abcd" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "scheduled", + "publishing", + "published", + "failed", + "needs_approval" + ], + "description": "Lifecycle state. Consult `deliveries` for per-channel outcomes — a `published` post can still contain failed channels (partial delivery)." + }, + "type": { + "type": "string", + "enum": [ + "single", + "thread", + "carousel", + "long" + ], + "description": "Post format." + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Internal title (not published to platforms)." + }, + "body": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Channel-agnostic base text the variants derive from." + }, + "scheduled_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When the post is scheduled to publish (ISO-8601 UTC)." + }, + "published_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When the post finished publishing (ISO-8601 UTC)." + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the post was created (ISO-8601 UTC)." + }, + "variants": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostVariant" + }, + "description": "Per-channel variants." + }, + "deliveries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Delivery" + }, + "description": "Latest delivery outcome per channel. Empty until a publish is attempted." + } + }, + "required": [ + "id", + "status", + "type", + "title", + "body", + "scheduled_at", + "published_at", + "created_at", + "variants", + "deliveries" + ], + "additionalProperties": false, + "description": "A post across one or more channels." + }, + "PostVariant": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Variant identifier." + }, + "channel_id": { + "type": "string", + "description": "The channel this variant publishes to (see /v1/channels)." + }, + "body": { + "type": "string", + "description": "The text published to the channel." + }, + "media": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostMediaItemOutput" + }, + "description": "Media attached to this variant." + } + }, + "required": [ + "id", + "channel_id", + "body", + "media" + ], + "additionalProperties": false, + "description": "Per-channel tailoring of a post." + }, + "Delivery": { + "type": "object", + "properties": { + "channel_id": { + "type": "string", + "description": "Channel this delivery targets." + }, + "stage": { + "type": "string", + "enum": [ + "queued", + "signed", + "sent", + "acked", + "indexed", + "failed", + "dlq" + ], + "description": "Latest delivery stage. `indexed`/`acked` are success; `failed`/`dlq` are terminal failures; anything else is in flight." + }, + "external_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The platform's id for the published item, once known." + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Why the latest delivery failed, as a sentence you can show your users. Present only when `stage` is `failed` or `dlq`; otherwise null." + } + }, + "required": [ + "channel_id", + "stage", + "external_id", + "error" + ], + "additionalProperties": false, + "description": "Per-channel delivery outcome of a publish." + }, + "DeletePostResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "deleted": { + "type": "boolean", + "const": true + } + }, + "required": [ + "id", + "deleted" + ], + "additionalProperties": false + }, + "PublishPostResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "scheduled", + "publishing", + "published", + "failed", + "needs_approval" + ], + "description": "State after acceptance. Poll GET /v1/posts/{id} for per-channel `deliveries`." + } + }, + "required": [ + "id", + "status" + ], + "additionalProperties": false, + "description": "Publish accepted — delivery continues in the background." + }, + "Usage": { + "type": "object", + "properties": { + "plan": { + "type": "string", + "description": "The workspace's effective plan tier.", + "example": "team" + }, + "meters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UsageMeter" + }, + "description": "All plan meters for the workspace." + } + }, + "required": [ + "plan", + "meters" + ], + "additionalProperties": false, + "description": "Plan + meter consumption." + }, + "UsageMeter": { + "type": "object", + "properties": { + "key": { + "type": "string", + "enum": [ + "posts_per_month", + "channels", + "team_members", + "ai_credits", + "transcription_minutes", + "integrations", + "api_requests" + ], + "description": "Meter name." + }, + "used": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Consumed in the current period." + }, + "limit": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "Plan ceiling for the period. Null means unlimited." + }, + "remaining": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "`limit - used`, floored at 0. Null when unlimited." + }, + "period_starts_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "Current metering period start (ISO-8601 UTC)." + }, + "period_ends_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When the meter resets (ISO-8601 UTC). Null when the period is open-ended." + } + }, + "required": [ + "key", + "used", + "limit", + "remaining", + "period_starts_at", + "period_ends_at" + ], + "additionalProperties": false, + "description": "One plan meter." + }, + "WebhookEndpointList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebhookEndpoint" + } + } + }, + "required": [ + "data" + ], + "additionalProperties": false, + "description": "All webhook endpoints for the organization. Not paginated — the endpoint count is plan-bounded by the `integrations` quota." + }, + "WebhookEndpoint": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable webhook endpoint identifier.", + "example": "cmc9x2y3z0001abcd" + }, + "url": { + "type": "string", + "description": "HTTPS delivery URL. Private/internal addresses are rejected." + }, + "event_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "post.published", + "post.failed", + "channel.connected", + "channel.reauth_required", + "delivery.failed" + ] + }, + "description": "Event types this endpoint subscribes to." + }, + "enabled": { + "type": "boolean", + "description": "Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts." + }, + "auto_disabled_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`." + }, + "consecutive_failures": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20." + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the endpoint was created (ISO-8601 UTC)." + } + }, + "required": [ + "id", + "url", + "event_types", + "enabled", + "auto_disabled_at", + "consecutive_failures", + "created_at" + ], + "additionalProperties": false, + "description": "An outbound webhook endpoint (subscriber)." + }, + "WebhookEndpointCreated": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable webhook endpoint identifier.", + "example": "cmc9x2y3z0001abcd" + }, + "url": { + "type": "string", + "description": "HTTPS delivery URL. Private/internal addresses are rejected." + }, + "event_types": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "post.published", + "post.failed", + "channel.connected", + "channel.reauth_required", + "delivery.failed" + ] + }, + "description": "Event types this endpoint subscribes to." + }, + "enabled": { + "type": "boolean", + "description": "Disabled endpoints receive no deliveries. Set automatically to `false` after 20 consecutive failed delivery attempts." + }, + "auto_disabled_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ], + "description": "When the failure ladder auto-disabled this endpoint (ISO-8601 UTC), or null. Re-enable via PATCH `enabled: true`." + }, + "consecutive_failures": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991, + "description": "Consecutive failed delivery attempts. Any successful (2xx) delivery resets it to 0. Warning emails fire at 5/10/15; the endpoint auto-disables at 20." + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", + "description": "When the endpoint was created (ISO-8601 UTC)." + }, + "signing_secret": { + "type": "string", + "description": "Standard-Webhooks signing secret (`whsec_` + base64). Store it now — over the API it is shown only in this response. A workspace owner/admin can re-reveal or roll it in Settings → Webhooks." + } + }, + "required": [ + "id", + "url", + "event_types", + "enabled", + "auto_disabled_at", + "consecutive_failures", + "created_at", + "signing_secret" + ], + "additionalProperties": false, + "description": "The created endpoint plus its show-once signing secret. Verify deliveries with any Standard Webhooks library." + }, + "DeleteWebhookEndpointResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "deleted": { + "type": "boolean", + "const": true + } + }, + "required": [ + "id", + "deleted" + ], + "additionalProperties": false + }, + "TestWebhookEndpointResult": { + "type": "object", + "properties": { + "delivery_id": { + "type": "string", + "description": "The recorded delivery attempt." + }, + "succeeded": { + "type": "boolean", + "description": "Whether the endpoint returned a 2xx." + }, + "http_code": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ], + "description": "HTTP status returned by the endpoint, or null when the request never completed (timeout, TLS failure, blocked egress)." + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Transport-level failure detail when no HTTP response exists." + } + }, + "required": [ + "delivery_id", + "succeeded", + "http_code", + "error" + ], + "additionalProperties": false, + "description": "Outcome of a synthetic `webhook.test` delivery, signed exactly like a real event." + }, + "PostMediaItemOutput": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Media URL. Use the `url` returned by /v1/media assets." + }, + "type": { + "type": "string", + "enum": [ + "image", + "video" + ], + "description": "Media kind." + }, + "alt": { + "description": "Accessibility alt text, where the platform supports it.", + "anyOf": [ + { + "type": "string", + "maxLength": 1000 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "url", + "type" + ], + "additionalProperties": false, + "description": "One media attachment." + } + }, + "securitySchemes": { + "bearerApiKey": { + "type": "http", + "scheme": "bearer", + "description": "Organization API key as a Bearer token (`postify_live_…`)." + }, + "headerApiKey": { + "type": "apiKey", + "in": "header", + "name": "x-api-key", + "description": "Organization API key in the `x-api-key` header." + } + } + } +} diff --git a/src/postify/models.py b/src/postify/models.py index da682d7..fcc212d 100644 --- a/src/postify/models.py +++ b/src/postify/models.py @@ -83,6 +83,9 @@ "youtube", "bluesky", "reddit", + "mastodon", + "telegram", + "discord", ) Platform = Union[ Literal[ @@ -96,6 +99,9 @@ "youtube", "bluesky", "reddit", + "mastodon", + "telegram", + "discord", ], str, ] diff --git a/tests/unit/test_models.py b/tests/unit/test_models.py index 896fccf..f69b711 100644 --- a/tests/unit/test_models.py +++ b/tests/unit/test_models.py @@ -147,7 +147,7 @@ def test_an_unknown_platform_or_status_does_not_raise() -> None: channel = models.Channel.model_validate( { "id": "chn_1", - "platform": "mastodon", # not in this SDK's PLATFORMS tuple + "platform": "friendster", # not in this SDK's PLATFORMS tuple "handle": "@acme", "avatar_url": None, "followers": None, @@ -157,7 +157,7 @@ def test_an_unknown_platform_or_status_does_not_raise() -> None: "created_at": "2026-08-05T12:00:00.000Z", } ) - assert channel.platform == "mastodon" + assert channel.platform == "friendster" assert channel.status == "quarantined" From 022279debb5a03a7f9b8df8e4ad7aca18ba187a4 Mon Sep 17 00:00:00 2001 From: AminDhouib Date: Tue, 20 Oct 2026 02:03:01 -0400 Subject: [PATCH 3/3] chore: keep the vendored spec pretty-printed and log the new platforms sync-spec.sh now re-serialises the fetched spec the way spec/v1.json is committed (2-space indent, UTF-8, trailing newline). Production serves it minified, so every weekly drift PR used to rewrite the whole file onto one line and hide the real change. Run against the live spec it reproduces the committed file byte for byte. Add the CHANGELOG entry for mastodon, telegram and discord. --- CHANGELOG.md | 5 +++++ scripts/sync-spec.sh | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 081845d..f3e3746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- `mastodon`, `telegram` and `discord` in `PLATFORMS` and the `Platform` type, + matching the `/v1` spec's `Channel.platform` enum. + ### Changed - The PyPI distribution name is now `postify-sdk` (was `postify`), matching the diff --git a/scripts/sync-spec.sh b/scripts/sync-spec.sh index 4b82bde..18d19c3 100644 --- a/scripts/sync-spec.sh +++ b/scripts/sync-spec.sh @@ -18,14 +18,26 @@ url="${POSTIFY_SPEC_URL:-https://app.usepostify.com/v1/openapi.json}" if [[ -n "${POSTIFY_SPEC_SOURCE:-}" ]]; then echo "Vendoring spec from ${POSTIFY_SPEC_SOURCE}" - cp "${POSTIFY_SPEC_SOURCE}" "${dest}" + cp "${POSTIFY_SPEC_SOURCE}" "${dest}.tmp" else echo "Fetching spec from ${url}" curl -fsSL "${url}" -o "${dest}.tmp" - python -c "import json,sys; json.load(open(sys.argv[1]))" "${dest}.tmp" - mv "${dest}.tmp" "${dest}" fi +# Production serves the spec minified. Re-serialise it the way spec/v1.json is +# committed (2-space indent, UTF-8, trailing newline) so a drift PR shows only +# the real change instead of rewriting all 5,000+ lines onto one. +python - "${dest}.tmp" "${dest}" <<'PY' +import json, sys + +with open(sys.argv[1], encoding="utf-8") as src: + doc = json.load(src) +with open(sys.argv[2], "w", encoding="utf-8", newline="\n") as out: + json.dump(doc, out, indent=2, ensure_ascii=False) + out.write("\n") +PY +rm -f "${dest}.tmp" + ops=$(python - "$dest" <<'PY' import json, sys