{"openapi":"3.1.0","info":{"title":"PostGate API","version":"1.0.0","description":"Postproxy-compatible, multi-tenant social publishing infrastructure.\nAll `/api` operations require a PostGate API key. Test keys use the\nsandbox adapter and never publish to a real social network.\n\nAccount timezone: GET/PATCH `/api/account/settings` configures the workspace IANA timezone\n(UTC until configured). Authenticated JSON responses present operational timestamps as ISO 8601\nwith the account UTC offset and send `X-PostGate-Timezone`. Object responses also include\n`time_context: {timezone, now}`. The instant is unchanged; clients must honor the offset.\nUser payloads, signed webhooks, Unix timestamps and date-only analytics buckets retain their\noriginal representation. Daily analytics buckets remain UTC.\nA timezone explicitly set on a post, profile group or recurring schedule overrides the account\nscheduling default. Existing schedules keep their saved zone when the account timezone changes.\nOffset-free scheduled_at inputs are interpreted in the explicit timezone or account timezone;\nexplicit offsets always identify the instant. Ambiguous/nonexistent local times are rejected.\n","contact":{"name":"PostGate support"}},"servers":[{"url":"https://postgate.studio"}],"tags":[{"name":"Account","description":"Workspace preferences shared by the dashboard and API/MCP credentials."},{"name":"Posts","description":"Create, schedule, inspect, publish, and delete unified posts."},{"name":"Analytics","description":"Read normalized daily growth timelines and period comparisons."},{"name":"Media","description":"Ingest and inspect media used by posts."},{"name":"Profiles","description":"Connect and manage social-network identities."},{"name":"Profile groups","description":"Group profiles into tenant-scoped publishing contexts."},{"name":"Engagement","description":"Read and respond to comments and direct messages."},{"name":"Comment automations","description":"Comment-to-DM: automatically send a private reply when a comment matches. Gated by a per-workspace engagement rollout while the required Instagram permissions are in Meta App Review — see the 403 response on every operation in this tag."},{"name":"Webhooks","description":"Manage signed outbound event subscriptions."},{"name":"Schedules","description":"Define recurring and queued publishing schedules."},{"name":"Platform","description":"Inspect provider capabilities and quota estimates."},{"name":"Environments","description":"Configure isolated customer environments and provider credentials."},{"name":"API keys","description":"Create, list, and revoke scoped server credentials."},{"name":"Instagram automations","description":"Versioned guided Instagram flows, inbox, compliance checks and connected-system results. New definitions default to drafts; publication is explicit. Test mode never calls Instagram Send API."}],"security":[{"bearerAuth":[]}],"paths":{"/api/account/settings":{"get":{"tags":["Account"],"operationId":"getAccountSettings","summary":"Read the account timezone","responses":{"200":{"description":"Workspace timezone. Requires read scope.","content":{"application/json":{"schema":{"type":"object","required":["timezone"],"properties":{"timezone":{"type":"string","example":"America/Sao_Paulo"}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Account"],"operationId":"updateAccountSettings","summary":"Update the account timezone","description":"Requires an organization-scoped full API key. Shared by all account members and API/MCP credentials. Existing schedules keep their saved timezone.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["timezone"],"properties":{"timezone":{"type":"string","description":"Valid IANA zone.","example":"America/Sao_Paulo"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Updated workspace timezone.","content":{"application/json":{"schema":{"type":"object","required":["timezone"],"properties":{"timezone":{"type":"string","example":"America/Sao_Paulo"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts":{"get":{"tags":["Posts"],"operationId":"listPosts","parameters":[{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"},{"in":"query","name":"status","schema":{"$ref":"#/components/schemas/PostStatus"}},{"in":"query","name":"profile_id","schema":{"type":"string"}},{"in":"query","name":"source","description":"Filter by created_via, e.g. source=imported for historical backfilled posts.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated posts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Posts"],"operationId":"createPost","parameters":[{"$ref":"#/components/parameters/ProfileGroupId"},{"in":"header","name":"Idempotency-Key","description":"Reusing a key with the same request returns the original post for 72 hours.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreatePostMultipart"}}}},"responses":{"201":{"description":"Post accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}":{"parameters":[{"$ref":"#/components/parameters/Id"}],"get":{"tags":["Posts"],"operationId":"getPost","responses":{"200":{"description":"Post and per-platform targets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Posts"],"operationId":"updatePost","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostRequest"}}}},"description":"Draft, pending_approval and scheduled posts accept any field. A published or partial post accepts a body-only edit when every live target is a Facebook feed post: the text is changed on Facebook first, then here. Anything else returns 409.","responses":{"200":{"description":"Updated post","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Posts"],"operationId":"deletePost","description":"Deletes the post in PostGate. With delete_on_platform=true it first deletes every live target on the network; that is supported only for Facebook feed posts and Reels, and any other live target returns 409 before anything is deleted.","parameters":[{"name":"delete_on_platform","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"}}],"responses":{"204":{"description":"Post deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/publish":{"post":{"tags":["Posts"],"operationId":"publishDraft","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"202":{"description":"Draft queued for immediate publishing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Post"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/logs":{"get":{"tags":["Posts"],"operationId":"getPostLogs","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Sanitized delivery timeline","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryAttemptList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/stats":{"get":{"tags":["Posts"],"operationId":"getPostStats","description":"Stored hourly snapshots. Pinterest never appears here — its metrics are read live through `/api/posts/{id}/live-stats`.","parameters":[{"in":"query","name":"post_ids","description":"Comma-separated post IDs","schema":{"type":"string"}},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Append-only analytics snapshots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/live-stats":{"get":{"tags":["Analytics"],"operationId":"getPostLiveStats","summary":"Read provider metrics that PostGate does not store","description":"Fetches Pinterest Pin analytics live for each published Pinterest target of this post. Nothing is persisted, so every call hits Pinterest. Targets that cannot be read are listed under `errors` instead of failing the request. Requires the `analytics` plan feature.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Live provider metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"target_id":{"type":"string"},"post_id":{"type":"string"},"platform":{"type":"string","example":"pinterest"},"captured_at":{"type":"string","format":"date-time"},"live":{"type":"boolean"},"metrics":{"type":"object","properties":{"impressions":{"type":"integer"},"saved":{"type":"integer"},"clicks":{"type":"integer"},"engagements":{"type":"integer"}}}}}},"errors":{"type":"array","items":{"type":"object","properties":{"target_id":{"type":"string"},"error":{"type":"string"}}}}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/analytics/timeseries":{"get":{"tags":["Analytics"],"operationId":"getAnalyticsTimeseries","description":"Returns daily metric increases by platform and profile group, plus an equally sized previous-period comparison. Requires the `analytics` plan feature; plans without it receive 403.","parameters":[{"in":"query","name":"from","schema":{"type":"string","format":"date"}},{"in":"query","name":"to","schema":{"type":"string","format":"date"}},{"in":"query","name":"platform","schema":{"type":"string"}},{"in":"query","name":"profile_id","schema":{"type":"string"}},{"in":"query","name":"profile_group_id","schema":{"type":"string"}},{"in":"query","name":"compare","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Daily received-growth timeline and period comparison.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsTimeseries"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media":{"post":{"tags":["Media"],"operationId":"createMedia","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/CreateMediaFromUrl"},{"$ref":"#/components/schemas/CreateMultipartMediaUpload"}]}},"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Multipart upload reservation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"202":{"description":"Media queued for validation and transformation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media/{id}":{"get":{"tags":["Media"],"operationId":"getMedia","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Media ingest state and probe data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media/{id}/complete":{"post":{"tags":["Media"],"operationId":"completeMultipartMediaUpload","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteMultipartMediaUpload"}}}},"responses":{"202":{"description":"Multipart media assembled and queued for validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media/{id}/upload":{"delete":{"tags":["Media"],"operationId":"abortMultipartMediaUpload","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"204":{"description":"Pending multipart upload aborted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media/upload-links":{"post":{"tags":["Media"],"operationId":"createMediaUploadLink","description":"Creates a browser page, valid for 60 minutes, where a person uploads up to 20 files from their own device. For AI assistants that cannot read local files. Uploading publishes nothing.","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"profile_group_id":{"type":"string","description":"Needed only when an organization-scoped key's workspace has several profile groups."}}}}}},"responses":{"201":{"description":"Upload link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadLink"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/media/upload-links/{token}":{"get":{"tags":["Media"],"operationId":"getMediaUploadLink","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Files uploaded through the link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadLinkStatus"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profile-groups":{"get":{"tags":["Profile groups"],"operationId":"listProfileGroups","responses":{"200":{"description":"Profile groups","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileGroupList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Profile groups"],"operationId":"createProfileGroup","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProfileGroupRequest"}}}},"responses":{"201":{"description":"Profile group created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileGroup"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profile-groups/{id}/best-times":{"get":{"tags":["Profile groups"],"operationId":"getProfileGroupBestTimes","summary":"Weekday and hour buckets ranked by engagement of the group's published posts.","parameters":[{"$ref":"#/components/parameters/Id"},{"name":"days","in":"query","schema":{"type":"integer","minimum":7,"maximum":365,"default":90}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":10,"default":3}},{"name":"timezone","in":"query","schema":{"type":"string"},"description":"IANA zone for the buckets; defaults to the group timezone."}],"responses":{"200":{"description":"Best posting times","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BestTimes"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profile-groups/{id}":{"delete":{"tags":["Profile groups"],"operationId":"deleteProfileGroup","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"204":{"description":"Profile group deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles":{"get":{"tags":["Profiles"],"operationId":"listProfiles","parameters":[{"$ref":"#/components/parameters/ProfileGroupId"},{"in":"query","name":"platform","schema":{"$ref":"#/components/schemas/Platform"}}],"responses":{"200":{"description":"Connected profiles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/integrations/linkedin":{"get":{"tags":["Profiles"],"operationId":"getLinkedInConnectionOptions","summary":"Inspect LinkedIn connection availability","description":"Workspace-scoped local configuration, not proof of LinkedIn approval. Development Page connections require the workspace allowlist; Standard connections require separately configured Community Management credentials. No credentials are returned.","responses":{"200":{"description":"Available LinkedIn connection types and configured scope","content":{"application/json":{"schema":{"type":"object","required":["member_available","pages_available","pages_access","page_scopes","features"],"properties":{"member_available":{"type":"boolean"},"pages_available":{"type":"boolean"},"pages_access":{"type":"string","enum":["disabled","development","standard"]},"page_scopes":{"type":"array","items":{"type":"string"}},"features":{"type":"object","additionalProperties":{"type":"boolean"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/connect":{"post":{"tags":["Profiles"],"operationId":"createConnectUrl","description":"Returns a hosted connection link valid for 15 minutes. On plans with white_label, the link is served from the environment's custom domain once its TLS is active, and credential pages (Bluesky, Telegram) show the workspace name, logo and color instead of PostGate. OAuth providers still show the provider consent screen of the app that owns the credentials.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConnectRequest"}}}},"responses":{"200":{"description":"Expiring hosted connection URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectUrl"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/connect-links":{"get":{"tags":["Profiles"],"operationId":"listConnectLinks","summary":"List shareable connection links","description":"Links created for this workspace (or for the key's profile group), newest first, with every account connected through each one.","parameters":[{"in":"query","name":"profile_group_id","schema":{"type":"string"}}],"responses":{"200":{"description":"Connection links","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectLink"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Profiles"],"operationId":"createConnectLink","summary":"Create a shareable connection link","description":"Returns a URL you can send to a client (for example, an agency's customer). Whoever opens it sees the selected networks and connects each one on the provider's own page, without a PostGate login; the accounts are added to `profile_group_id` and recorded under `connections`. The link stays valid for any number of connections until `expires_at` or until it is revoked. On plans with white_label it is served from the environment's active custom domain with the workspace branding.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["platforms"],"properties":{"platforms":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/Platform"}},"profile_group_id":{"type":"string","description":"Required for organization-scoped keys."},"label":{"type":"string","maxLength":120,"description":"Private note shown only in your workspace."},"expires_in_hours":{"type":"integer","minimum":1,"maximum":720,"default":168}}}}}},"responses":{"201":{"description":"Connection link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLink"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/connect-links/{id}":{"get":{"tags":["Profiles"],"operationId":"getConnectLink","summary":"Get a connection link and its progress","description":"Poll this to follow a link you sent: `status` says whether the client connected every selected network (`completed`), only some (`partial`), none yet (`pending`), or whether the link stopped working first (`expired`, `revoked`). Each connection also fires the `profile.connected` webhook with `connect_link_id`.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Connection link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLink"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Profiles"],"operationId":"revokeConnectLink","summary":"Revoke a connection link","description":"The URL stops working immediately, including for a client already on a provider consent screen. Accounts already connected stay connected.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Link revoked"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/connect-origins":{"get":{"tags":["Profiles"],"operationId":"listConnectOrigins","summary":"Origins this workspace may use as `return_url`","description":"The hosted connection flow only redirects back to an origin registered here (or to a PostGate-owned baseline origin, returned under `meta.built_in`). Requires an organization-scoped key.","responses":{"200":{"description":"Allowed return origins","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"origin":{"type":"string","format":"uri","example":"https://app.example.com"},"label":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","properties":{"built_in":{"type":"array","items":{"type":"string"}},"limit":{"type":"integer","example":25}}}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Profiles"],"operationId":"allowConnectOrigin","summary":"Allow an origin to receive the connection redirect","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["origin"],"properties":{"origin":{"type":"string","format":"uri","description":"Full origin or any URL on it. HTTPS is required outside loopback.","example":"https://app.example.com"},"label":{"type":"string","maxLength":80,"example":"Production SaaS"}}}}}},"responses":{"201":{"description":"Origin allowed","content":{"application/json":{"schema":{"type":"object","properties":{"origin":{"type":"string"},"label":{"type":["string","null"]}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Profiles"],"operationId":"revokeConnectOrigin","parameters":[{"in":"query","name":"origin","required":true,"schema":{"type":"string","format":"uri"}}],"responses":{"204":{"description":"Origin revoked"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}":{"parameters":[{"$ref":"#/components/parameters/Id"}],"get":{"tags":["Profiles"],"operationId":"getProfile","responses":{"200":{"description":"Profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Profiles"],"operationId":"deleteProfile","description":"Disconnects a connected profile (revokes provider credentials where supported) and stops future deliveries. Calling this again on a profile that is already disconnected removes it from `GET /api/profiles` instead — reconnecting the same provider account (`POST /api/profiles/connect`) makes it visible again. Publication history for the profile (post_targets, permalinks, analytics) is never deleted.","responses":{"204":{"description":"Profile disconnected, or removed from listings if already disconnected"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/import":{"post":{"tags":["Profiles"],"operationId":"importProfilePosts","summary":"Backfill posts already published on the connected account","description":"Queues an asynchronous job that lists posts already published on the provider account (before this connection, or by another tool) and creates them as posts with created_via=imported. Also triggered automatically after a successful connection. See GET /api/platforms for which providers support features.import; unsupported providers return a platform_not_configured error. Media is never downloaded — only lightweight metadata is stored.","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string","format":"date-time","description":"Defaults to 90 days ago."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Defaults to 100."}},"additionalProperties":false}}}},"responses":{"202":{"description":"Import job queued","content":{"application/json":{"schema":{"type":"object","required":["job_id","status"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"job_id":{"type":"string"},"status":{"type":"string","enum":["queued"]}},"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/refresh-avatar":{"post":{"tags":["Profiles"],"operationId":"refreshProfileAvatar","summary":"Re-sync the profile photo from the provider","description":"Queues a job that copies the connected account's current profile photo into PostGate storage. The profile must be connected and its platform must expose a photo.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"202":{"description":"Avatar sync queued","content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"status":{"type":"string","enum":["queued"]}},"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/health":{"get":{"tags":["Profiles"],"operationId":"getProfileHealth","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Connection and token health","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileHealth"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/boards":{"get":{"tags":["Profiles"],"operationId":"listProfileBoards","summary":"List the Pinterest boards of a connected profile","description":"Reads the boards of a connected Pinterest account live from the provider so your product can render a board picker instead of asking the user to paste a board ID. The result feeds post.options.pinterest.board_id, which Pinterest requires on every Pin. Boards are not stored by PostGate and the access token is never exposed. Only Pinterest profiles are supported; other platforms return platform_not_configured. A connection authorized in Sandbox, or authorized before the boards:read permission was requested, must be reconnected before boards can be read.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Boards available on the connected Pinterest account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/stats":{"get":{"tags":["Profiles"],"operationId":"getProfileStats","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Profile analytics snapshots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/insights":{"get":{"tags":["Analytics"],"operationId":"getAccountInsights","summary":"Account-level period totals read live from the provider","description":"Instagram, Facebook Page and Threads profiles. Totals cover all content on the account, including posts not published through PostGate, so they differ from the tracked-post series. Values the provider does not report are null, never zero. Unique reach is only native for Instagram; it is never summed from daily values. Facebook ranges are limited to 93 days. Cached for five minutes. Requires the `analytics` plan feature.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"from","description":"Inclusive UTC date; defaults to 27 days before `to`.","schema":{"type":"string","format":"date"}},{"in":"query","name":"to","description":"Inclusive UTC date; defaults to today.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Account insights","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInsights"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/audience":{"get":{"tags":["Analytics"],"operationId":"getAudienceInsights","summary":"Follower demographics, engaged-audience demographics and online hours","description":"Instagram (follower and engaged demographics plus average followers online per hour over the last 30 days) and Threads (follower demographics). Each breakdown lists at most 45 values. Instagram and Threads omit demographics below 100 followers (or 100 engagements in the timeframe), reported as null. Cached for one hour. Requires the `analytics` plan feature.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"timeframe","description":"Instagram only; Threads always reports current followers.","schema":{"type":"string","enum":["this_week","this_month","last_30_days","last_90_days"],"default":"last_30_days"}}],"responses":{"200":{"description":"Audience insights","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceInsights"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/comments":{"get":{"tags":["Engagement"],"operationId":"listComments","description":"Alias of GET /api/inbox/comments?post_id={id}, oldest first.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"profile_id","schema":{"type":"string"}}],"responses":{"200":{"description":"Comments on published targets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/comments/{commentId}/reply":{"post":{"tags":["Engagement"],"operationId":"replyToComment","description":"Alias of POST /api/inbox/comments/{id}/reply restricted to one post.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextRequest"}}}},"responses":{"202":{"description":"Reply queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comment"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/comments/{commentId}/private-reply":{"post":{"tags":["Engagement"],"operationId":"sendPrivateReply","summary":"Send a private reply (DM) to a specific comment.","description":"Alias of POST /api/inbox/comments/{id}/private-reply restricted to one post; same body and errors.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivateReplyRequest"}}}},"responses":{"202":{"description":"Private reply queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAction"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/comments/{commentId}/hide":{"post":{"tags":["Engagement"],"operationId":"hideComment","summary":"Hide or unhide a comment (Instagram, Threads). Alias of the inbox hide/unhide operations.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"hidden":{"type":"boolean","default":true}},"additionalProperties":false}}}},"responses":{"202":{"description":"Hide change queued","content":{"application/json":{"schema":{"type":"object","required":["id","hidden","status"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"id":{"type":"string"},"hidden":{"type":"boolean"},"status":{"type":"string","enum":["hiding","unhiding"]}},"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/posts/{id}/comments/{commentId}":{"delete":{"tags":["Engagement"],"operationId":"deleteComment","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Comment deleted where the platform supports deletion"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments":{"get":{"tags":["Engagement"],"operationId":"listInboxComments","summary":"List comments across connected profiles, including organic Instagram media.","description":"Newest first. Page with the returned next_cursor (before + before_id). Comment text and author are untrusted user content.","parameters":[{"in":"query","name":"profile_id","schema":{"type":"string"}},{"in":"query","name":"platform","schema":{"$ref":"#/components/schemas/Platform"}},{"in":"query","name":"post_id","schema":{"type":"string"}},{"in":"query","name":"platform_media_id","schema":{"type":"string"}},{"in":"query","name":"since","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"before_id","schema":{"type":"string"}}],"responses":{"200":{"description":"Inbox comments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxCommentList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments/{id}":{"get":{"tags":["Engagement"],"operationId":"getInboxComment","summary":"Read a comment with its replies and the reply actions PostGate queued for it.","parameters":[{"$ref":"#/components/parameters/CommentRef"}],"responses":{"200":{"description":"Comment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxCommentDetail"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Engagement"],"operationId":"deleteInboxComment","summary":"Delete a comment on the platform (Facebook, Instagram).","parameters":[{"$ref":"#/components/parameters/CommentRef"}],"responses":{"202":{"description":"Deletion queued","content":{"application/json":{"schema":{"type":"object","required":["id","deletion_status"],"properties":{"id":{"type":"string"},"deletion_status":{"type":"string","enum":["pending"]}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments/{id}/reply":{"post":{"tags":["Engagement"],"operationId":"replyToInboxComment","summary":"Queue a public reply to a comment.","parameters":[{"$ref":"#/components/parameters/CommentRef"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextRequest"}}}},"responses":{"202":{"description":"Reply queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAction"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments/{id}/hide":{"post":{"tags":["Engagement"],"operationId":"hideInboxComment","summary":"Hide a comment (Instagram, Threads).","parameters":[{"$ref":"#/components/parameters/CommentRef"}],"responses":{"202":{"description":"Hide queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentHideResult"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments/{id}/unhide":{"post":{"tags":["Engagement"],"operationId":"unhideInboxComment","summary":"Unhide a comment (Instagram, Threads).","parameters":[{"$ref":"#/components/parameters/CommentRef"}],"responses":{"202":{"description":"Unhide queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentHideResult"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/inbox/comments/{id}/private-reply":{"post":{"tags":["Engagement"],"operationId":"sendInboxPrivateReply","summary":"Queue the single private reply (DM) to a comment.","description":"One private reply per comment, within seven days of the verified comment timestamp; it does not open a messaging window. Errors use error.details.reason: 409 private_reply_consumed and 409 private_reply_expired are final (retryable false). 502 with details.outcome unknown means an earlier attempt timed out at the provider and may have been delivered — do not resend. Unsupported platforms return 409 comment_action_unsupported.","parameters":[{"$ref":"#/components/parameters/CommentRef"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivateReplyRequest"}}}},"responses":{"202":{"description":"Private reply queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAction"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations":{"get":{"tags":["Engagement"],"operationId":"listConversations","parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"profile_id","schema":{"type":"string"}},{"in":"query","name":"owner","schema":{"type":"string","enum":["automation","human","external"]}}],"responses":{"200":{"description":"Direct-message conversations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/messages":{"parameters":[{"$ref":"#/components/parameters/Id"}],"get":{"tags":["Engagement"],"operationId":"listMessages","responses":{"200":{"description":"Conversation messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageList"}}}},"default":{"$ref":"#/components/responses/Error"}},"parameters":[{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"updated_after","description":"Incremental changes, including status changes and deleted historical messages. Use sync_cursor.at from the previous response.","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"after_id","description":"Use sync_cursor.id while has_more is true to paginate changes sharing a timestamp.","schema":{"type":"string","maxLength":128}}]},"post":{"tags":["Engagement"],"operationId":"sendMessage","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementSendRequest"}}}},"responses":{"202":{"description":"Message accepted for policy-checked delivery; inspect the inbox or webhook for the outcome.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAction"}}}},"default":{"$ref":"#/components/responses/Error"}},"parameters":[{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Reuse when retrying the same send. It never authorizes resending an uncertain delivery."}]}},"/api/comment-automations":{"get":{"tags":["Comment automations"],"operationId":"listCommentAutomations","parameters":[{"in":"query","name":"profile_id","schema":{"type":"string"}}],"responses":{"200":{"description":"Comment-to-DM automations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentAutomationList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Comment automations"],"operationId":"createCommentAutomation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentAutomationCreateRequest"}}}},"responses":{"201":{"description":"Automation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/comment-automations/{id}":{"parameters":[{"$ref":"#/components/parameters/Id"}],"patch":{"tags":["Comment automations"],"operationId":"updateCommentAutomation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentAutomationUpdateRequest"}}}},"responses":{"200":{"description":"Automation updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Comment automations"],"operationId":"deleteCommentAutomation","responses":{"204":{"description":"Automation deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/comment-automations/{id}/runs":{"get":{"tags":["Comment automations"],"operationId":"listCommentAutomationRuns","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Recent matches and their delivery outcome","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentAutomationRunList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks":{"get":{"tags":["Webhooks"],"operationId":"listWebhooks","responses":{"200":{"description":"Webhook endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Webhooks"],"operationId":"createWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook created; secret is shown once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks/{id}":{"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"204":{"description":"Webhook deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"operationId":"testWebhook","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"202":{"description":"Test delivery queued"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks/{id}/reactivate":{"post":{"tags":["Webhooks"],"operationId":"reactivateWebhook","summary":"Re-enable a webhook that was disabled after repeated failures.","description":"A webhook is disabled (active=false, disabled_at set) when its endpoint answers 410, or after 50 consecutive failed deliveries spanning at least 24 hours. Reactivating sets it active again, restarts the failure count and queues the deliveries that were still pending or waiting for a retry. Safe to call on an active webhook.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Webhook reactivated","content":{"application/json":{"schema":{"type":"object","required":["id","active","requeued"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"id":{"type":"string"},"active":{"type":"boolean"},"requeued":{"type":"integer","description":"Deliveries queued again."}},"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"operationId":"listWebhookDeliveries","summary":"Recent deliveries of one webhook, newest first, with the HTTP response and last error.","parameters":[{"$ref":"#/components/parameters/Id"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivering","delivered","retry_scheduled","failed"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only deliveries created before this time."}],"responses":{"200":{"description":"Webhook deliveries","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/webhooks/{id}/deliveries/{deliveryId}/redeliver":{"post":{"tags":["Webhooks"],"operationId":"redeliverWebhook","summary":"Send a failed or delivered delivery again, signed like the original.","description":"Reopens the delivery and queues it; the attempt appears in the delivery history. 409 while the delivery is pending, delivering or waiting for its automatic retry, or when the webhook is disabled (reactivate it first). An event older than the retry window is sent once without automatic retries.","parameters":[{"$ref":"#/components/parameters/Id"},{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Redelivery queued","content":{"application/json":{"schema":{"type":"object","required":["id","event_id","status"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"id":{"type":"string"},"event_id":{"type":"string"},"status":{"type":"string","enum":["pending"]}},"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/schedules":{"get":{"tags":["Schedules"],"operationId":"listSchedules","responses":{"200":{"description":"Recurring schedules","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Schedules"],"operationId":"createSchedule","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWrite"}}}},"responses":{"201":{"description":"Schedule created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/schedules/{id}":{"parameters":[{"$ref":"#/components/parameters/Id"}],"patch":{"tags":["Schedules"],"operationId":"updateSchedule","description":"Pausing (active=false) or changing the expression or timezone removes the occurrences already generated that have not started; they are generated again from the new definition while the schedule is active.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchedulePatch"}}}},"responses":{"200":{"description":"Schedule updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Schedules"],"operationId":"deleteSchedule","description":"Also removes the occurrences already generated that have not started.","responses":{"204":{"description":"Schedule deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/platforms":{"get":{"tags":["Platform"],"operationId":"listPlatforms","description":"Networks that support an automatic first comment report post_options.first_comment.max_length. The connected profile must also have permission to comment.","responses":{"200":{"description":"Machine-readable provider capabilities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/quotas":{"get":{"tags":["Platform"],"operationId":"getQuotas","responses":{"200":{"description":"Plan usage, feature entitlements, and daily provider estimates","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/api-keys":{"get":{"tags":["API keys"],"operationId":"listApiKeys","responses":{"200":{"description":"Non-secret API key metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["API keys"],"operationId":"createApiKey","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"201":{"description":"API key created; raw key is shown exactly once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedApiKey"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/api-keys/{id}":{"delete":{"tags":["API keys"],"operationId":"revokeApiKey","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"204":{"description":"API key revoked"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/environments":{"get":{"tags":["Environments"],"operationId":"listEnvironments","responses":{"200":{"description":"Embedded environments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericList"}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Environments"],"operationId":"createEnvironment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEnvironmentRequest"}}}},"responses":{"201":{"description":"Environment created","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/environments/{id}":{"patch":{"tags":["Environments"],"operationId":"updateEnvironment","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvironmentRequest"}}}},"responses":{"200":{"description":"Environment updated","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/environments/{id}/verify-domain":{"post":{"tags":["Environments"],"operationId":"verifyEnvironmentDomain","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Verification result and required DNS record","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/platform-apps":{"get":{"tags":["Platform"],"operationId":"listPlatformApps","responses":{"200":{"description":"Tenant-owned provider applications without secrets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/platform-apps/{platform}":{"parameters":[{"in":"path","name":"platform","required":true,"schema":{"$ref":"#/components/schemas/Platform"}}],"put":{"tags":["Platform"],"operationId":"putPlatformApp","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutPlatformAppRequest"}}}},"responses":{"200":{"description":"Provider application stored with encrypted credentials","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Platform"],"operationId":"deletePlatformApp","responses":{"204":{"description":"Provider application credentials deleted"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations":{"get":{"tags":["Instagram automations"],"operationId":"listAutomations","summary":"List automation drafts and published definitions","parameters":[{"in":"query","name":"group_id","schema":{"type":"string"},"description":"Profile group (client profile)"},{"in":"query","name":"profile_id","schema":{"type":"string"}}],"responses":{"200":{"description":"List automation drafts and published definitions","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AutomationSummary"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Instagram automations"],"operationId":"createAutomation","summary":"Create an inactive automation draft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationDraftRequest"}}}},"responses":{"201":{"description":"Create an inactive automation draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}":{"get":{"tags":["Instagram automations"],"operationId":"getAutomation","summary":"Read the draft and publication state","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Read the draft and publication state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Instagram automations"],"operationId":"updateAutomation","summary":"Save a new draft revision without changing the published version","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"expected_revision","schema":{"type":"integer","minimum":0},"description":"When set, the save fails with draft_conflict (409) if the draft revision changed since it was read."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationDraftRequest"}}}},"responses":{"200":{"description":"Save a new draft revision without changing the published version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Instagram automations"],"operationId":"deleteAutomation","summary":"Cancel pending work and delete an automation","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Cancel pending work and delete an automation","content":{"application/json":{"schema":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean","const":true}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/validate":{"post":{"tags":["Instagram automations"],"operationId":"validateAutomation","summary":"Validate graph branches, resources and account readiness","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Validate graph branches, resources and account readiness","content":{"application/json":{"schema":{"type":"object","required":["valid","issues","capabilities"],"properties":{"valid":{"type":"boolean"},"issues":{"type":"array","items":{"type":"object","properties":{"node_id":{"type":"string"},"reason":{"type":"string"},"message":{"type":"string"}}}},"capabilities":{"$ref":"#/components/schemas/EngagementCapabilities"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/simulate":{"post":{"tags":["Instagram automations"],"operationId":"simulateAutomation","summary":"Simulate production flow rules without sending","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"reply":{"type":"string"},"clicked":{"type":"boolean"},"external_result":{}},"additionalProperties":false}}}},"responses":{"200":{"description":"Simulate production flow rules without sending","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/publish":{"post":{"tags":["Instagram automations"],"operationId":"publishAutomation","summary":"Publish an immutable version for future eligible interactions","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Publish an immutable version for future eligible interactions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/pause":{"post":{"tags":["Instagram automations"],"operationId":"pauseAutomation","summary":"Pause an automation and invalidate pending sends","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Pause an automation and invalidate pending sends","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/runs":{"get":{"tags":["Instagram automations"],"operationId":"listAutomationRuns","summary":"Read execution checkpoints and block reasons","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Read execution checkpoints and block reasons","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AutomationRun"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automation-runs/{id}/resume":{"post":{"tags":["Instagram automations"],"operationId":"resumeAutomationRun","summary":"Resume a correlated external step without renewing the messaging window","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["node_id","event_id","result"],"properties":{"node_id":{"type":"string"},"event_id":{"type":"string"},"result":{"description":"JSON result, at most 16 KiB. It cannot overwrite ownership or interaction timestamps."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Resume a correlated external step without renewing the messaging window","content":{"application/json":{"schema":{"type":"object","required":["run_id","status"],"properties":{"run_id":{"type":"string"},"status":{"type":"string"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/engagement-capabilities":{"get":{"tags":["Instagram automations"],"operationId":"getEngagementCapabilities","summary":"Inspect Instagram grants, webhook readiness and messaging limits","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Inspect Instagram grants, webhook readiness and messaging limits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementCapabilities"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/engagement-media":{"get":{"tags":["Instagram automations"],"operationId":"listEngagementMedia","summary":"List account-owned Instagram publications","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"after","schema":{"type":"string"}}],"responses":{"200":{"description":"List account-owned Instagram publications","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"after":{"type":["string","null"]},"has_more":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/engagement-repair":{"post":{"tags":["Instagram automations"],"operationId":"repairEngagementWebhooks","summary":"Repair webhook subscriptions for the authorized account","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Repair webhook subscriptions for the authorized account","content":{"application/json":{"schema":{"type":"object","properties":{"repaired":{"type":"boolean"},"reason":{"type":"string"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/private-reply":{"post":{"tags":["Instagram automations"],"operationId":"sendProfilePrivateReply","summary":"Queue the single private reply to an account-owned comment","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Reuse when retrying the same send. It never authorizes resending an uncertain delivery."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["comment_id"],"properties":{"comment_id":{"type":"string"},"text":{"type":"string"},"message":{"$ref":"#/components/schemas/EngagementMessage"}},"oneOf":[{"required":["text"],"not":{"required":["message"],"properties":{"message":{}}},"properties":{"text":{}}},{"required":["message"],"not":{"required":["text"],"properties":{"text":{}}},"properties":{"message":{}}}],"additionalProperties":false}}}},"responses":{"202":{"description":"Queue the single private reply to an account-owned comment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementAction"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}":{"get":{"tags":["Instagram automations"],"operationId":"getConversation","summary":"Read conversation ownership and messaging window","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Read conversation ownership and messaging window","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conversation"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/handoff":{"post":{"tags":["Instagram automations"],"operationId":"handoffConversation","summary":"Claim a conversation for an external integration and invalidate automation sends","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["owner"],"properties":{"owner":{"type":"string","const":"external","description":"Only authenticated dashboard attendants can claim human ownership."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Claim a conversation for an external integration and invalidate automation sends","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conversation"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/resume-automation":{"post":{"tags":["Instagram automations"],"operationId":"resumeConversationAutomation","summary":"Explicitly return a conversation to automation after policy validation","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Explicitly return a conversation to automation after policy validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conversation"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/sender-action":{"post":{"tags":["Instagram contacts"],"operationId":"sendConversationSenderAction","summary":"Show or hide the typing indicator, or mark the latest inbound message seen. Sends no message content.","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["typing_on","typing_off","mark_seen"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"Action sent","content":{"application/json":{"schema":{"type":"object","required":["ok","action"],"properties":{"ok":{"type":"boolean"},"action":{"type":"string"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/profiles/{id}/ice-breakers":{"parameters":[{"$ref":"#/components/parameters/Id"}],"get":{"tags":["Instagram contacts"],"operationId":"getIceBreakers","summary":"Instagram ice breakers shown when someone opens a new chat (mobile app only). A tap arrives as a postback message.","responses":{"200":{"description":"Current ice breakers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IceBreakers"}}}},"default":{"$ref":"#/components/responses/Error"}}},"put":{"tags":["Instagram contacts"],"operationId":"setIceBreakers","summary":"Replace the ice breakers. An empty list removes them.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IceBreakers"}}}},"responses":{"200":{"description":"Ice breakers as Instagram now reports them","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IceBreakers"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/resolve":{"post":{"tags":["Instagram contacts"],"operationId":"resolveConversation","summary":"Mark a conversation as resolved. A new inbound message reopens it.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"New status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationStatus"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/conversations/{id}/reopen":{"post":{"tags":["Instagram contacts"],"operationId":"reopenConversation","summary":"Reopen a resolved conversation","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"New status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationStatus"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/automations/{id}/analytics":{"get":{"tags":["Instagram automations"],"operationId":"getAutomationAnalytics","summary":"Per-step results for one published version","description":"Counts runs that started the selected version (default: the published one) inside the period. Steps are counted once per run and never mixed across versions. Step history exists from `instrumented_since`; older runs only contribute run totals.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"version_id","schema":{"type":"string"}},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Version analytics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutomationAnalytics"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/engagement-analytics":{"get":{"tags":["Instagram automations"],"operationId":"getEngagementAnalytics","summary":"Runs, people and collected emails across flows","parameters":[{"in":"query","name":"from","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"group_id","schema":{"type":"string"},"description":"Profile group (client profile)"},{"in":"query","name":"profile_id","schema":{"type":"string"},"description":"Connected social account"}],"responses":{"200":{"description":"Workspace engagement analytics","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/contacts":{"get":{"tags":["Instagram contacts"],"operationId":"listContacts","summary":"People who interacted with your connected accounts","description":"A contact is one provider-scoped user on one connected account. The same person on two accounts is two contacts; an email address never merges them.","parameters":[{"in":"query","name":"q","schema":{"type":"string"},"description":"Name, username, email, phone, scoped id or tag"},{"in":"query","name":"tag","schema":{"type":"string"}},{"in":"query","name":"has_email","schema":{"type":"string","enum":["true","false"]}},{"in":"query","name":"group_id","schema":{"type":"string"},"description":"Profile group (client profile)"},{"in":"query","name":"profile_id","schema":{"type":"string"},"description":"Connected social account"},{"in":"query","name":"sequence_id","schema":{"type":"string"}},{"in":"query","name":"automation_id","schema":{"type":"string"}},{"in":"query","name":"node_id","schema":{"type":"string"}},{"in":"query","name":"version_id","schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Contacts, newest interaction first; totals use the same filters before pagination","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"totals":{"type":"object","additionalProperties":{"type":"integer"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/contacts/{id}":{"get":{"tags":["Instagram contacts"],"operationId":"getContact","summary":"Contact with tags, sequences, history, conversations and runs","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Instagram contacts"],"operationId":"updateContact","summary":"Set email, phone, display name, tags, custom fields or sequence membership","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":["string","null"]},"phone":{"type":["string","null"],"maxLength":40,"description":"Phone/WhatsApp with explicit country code, e.g. +5511999999999. Stored in fields.phone; null removes it. Does not verify WhatsApp registration."},"display_name":{"type":["string","null"]},"add_tags":{"type":"array","items":{"type":"string"}},"remove_tags":{"type":"array","items":{"type":"string"}},"fields":{"type":"object","additionalProperties":{"type":["string","null"]},"description":"Keys use lowercase letters, numbers and underscores. null removes a field."},"subscribe":{"type":"array","items":{"type":"string"},"description":"Sequence ids"},"unsubscribe":{"type":"array","items":{"type":"string"},"description":"Sequence ids"}}}}}},"responses":{"200":{"description":"Updated contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Instagram contacts"],"operationId":"deleteContact","summary":"Erase the contact's CRM record (email, tags, fields, history)","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/contacts/{id}/history":{"get":{"tags":["Instagram contacts"],"operationId":"getContactHistory","summary":"Chronological contact activity and comment counts at each milestone","description":"Combines retained comments, messages, CRM changes and tracked-link opens, newest first. comments_before counts this person's recorded comments dated at or before each event, scoped to the connected account and environment. Milestone counts are saved when recorded so later retention cannot rewrite them. Historical milestones use retained data at migration. Existing comments appear immediately. Repeated link opens are recorded individually after this feature is deployed; older links only have first-open evidence. Link opens are attributed to the recipient of the tracked URL. Contact detail includes the first page in history. Follow next_cursor using both fields unchanged.","parameters":[{"$ref":"#/components/parameters/Id"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"in":"query","name":"before","schema":{"type":"string","format":"date-time"},"description":"Timestamp from next_cursor, preserving all fractional digits. Requires before_id."},{"in":"query","name":"before_id","schema":{"type":"string","maxLength":200},"description":"Activity id from next_cursor. Requires before."}],"responses":{"200":{"description":"Activity page and totals for the full retained history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactHistory"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/tags":{"get":{"tags":["Instagram contacts"],"operationId":"listTags","summary":"Tags with contact counts","responses":{"200":{"description":"Tags","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Instagram contacts"],"operationId":"createTag","summary":"Create a tag (names are unique ignoring case)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","maxLength":60}}}}}},"responses":{"201":{"description":"Tag","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tag"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/tags/{id}":{"delete":{"tags":["Instagram contacts"],"operationId":"deleteTag","summary":"Delete a tag and remove it from every contact","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/sequences":{"get":{"tags":["Instagram contacts"],"operationId":"listSequences","summary":"Sequence membership lists","description":"PostGate records subscribe and unsubscribe and emits contact.sequence_subscribed / contact.sequence_unsubscribed webhooks. It does not send sequence messages: Instagram only allows automated messages inside the 24-hour window, so delivery belongs to your email or CRM tool.","responses":{"200":{"description":"Sequences","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Sequence"}}}}}}},"default":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Instagram contacts"],"operationId":"createSequence","summary":"Create a sequence membership list","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceRequest"}}}},"responses":{"201":{"description":"Sequence","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sequence"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/sequences/{id}":{"patch":{"tags":["Instagram contacts"],"operationId":"updateSequence","summary":"Rename or describe a sequence","parameters":[{"$ref":"#/components/parameters/Id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceRequest"}}}},"responses":{"200":{"description":"Sequence","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sequence"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"tags":["Instagram contacts"],"operationId":"archiveSequence","summary":"Archive a sequence. Memberships stay in history; flows that reference it block at that step.","parameters":[{"$ref":"#/components/parameters/Id"}],"responses":{"200":{"description":"Archived","content":{"application/json":{"schema":{"type":"object","properties":{"archived":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"PostGate API key"}},"parameters":{"Id":{"in":"path","name":"id","required":true,"schema":{"type":"string"}},"CommentRef":{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"PostGate comment id (cmt_...) or the platform comment id."},"IdempotencyKey":{"in":"header","name":"Idempotency-Key","schema":{"type":"string"},"description":"Reuse when retrying the same send. It never authorizes resending an uncertain delivery."},"Page":{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1}},"PerPage":{"in":"query","name":"per_page","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},"ProfileGroupId":{"in":"query","name":"profile_group_id","schema":{"type":"string"},"description":"Required when an organization-scoped API key has no default group."}},"responses":{"Error":{"description":"RFC 7807-style PostGate error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"MediaUploadLink":{"type":"object","required":["token","upload_url","expires_at","max_files","max_file_bytes"],"properties":{"token":{"type":"string","description":"Pass to GET /api/media/upload-links/{token}."},"upload_url":{"type":"string","format":"uri","description":"Page the person opens to upload files."},"expires_at":{"type":"string","format":"date-time"},"max_files":{"type":"integer"},"max_file_bytes":{"type":"integer"}}},"MediaUploadLinkStatus":{"type":"object","required":["status","media_ids","expires_at","files"],"properties":{"status":{"type":"string","enum":["pending","processing","completed","expired"]},"media_ids":{"type":"array","items":{"type":"string"},"description":"Ready media, usable in post media."},"expires_at":{"type":"string","format":"date-time"},"files":{"type":"array","items":{"type":"object","required":["media_id","filename","status"],"properties":{"media_id":{"type":"string"},"filename":{"type":"string"},"mime":{"type":["string","null"]},"bytes":{"type":["integer","null"]},"status":{"type":"string","enum":["pending","uploaded","processing","ready","failed"]},"error":{"type":["string","null"]}}}}}},"ConversationStatus":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["open","resolved"]}}},"Contact":{"type":"object","required":["id","profile_id","platform","provider_user_id"],"properties":{"id":{"type":"string"},"profile_id":{"type":"string"},"platform":{"type":"string"},"provider_user_id":{"type":"string","description":"Provider-scoped user id (Instagram IGSID) for this connected account"},"username":{"type":["string","null"]},"display_name":{"type":["string","null"]},"email":{"type":["string","null"],"format":"email"},"email_collected_at":{"type":["string","null"],"format":"date-time"},"email_source":{"type":["string","null"],"enum":["automation","manual","api",null]},"fields":{"type":"object","additionalProperties":{"type":"string"}},"follows_business":{"type":["boolean","null"],"description":"null while unknown (Instagram only shares it after the person messaged the account)"},"follows_checked_at":{"type":["string","null"],"format":"date-time"},"last_interaction_at":{"type":["string","null"],"format":"date-time"},"tags":{"type":"array","items":{}},"sequences":{"type":"array","items":{}},"events":{"type":"array","items":{"type":"object","additionalProperties":true}},"history":{"$ref":"#/components/schemas/ContactHistory"},"conversations":{"type":"array","items":{"type":"object","additionalProperties":true}},"runs":{"type":"array","items":{"type":"object","additionalProperties":true}},"created_at":{"type":"string","format":"date-time"}}},"ContactHistory":{"type":"object","required":["data","summary","next_cursor"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","kind","data","actor","created_at","comments_before"],"properties":{"id":{"type":"string"},"kind":{"type":"string"},"data":{"type":"object","additionalProperties":true},"actor":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"comments_before":{"type":"integer","minimum":0},"automation_name":{"type":["string","null"]},"automation_id":{"type":["string","null"]},"run_id":{"type":["string","null"]},"version_id":{"type":["string","null"]},"node_id":{"type":["string","null"]}}}},"summary":{"type":"object","properties":{"comments":{"type":"integer"},"messages":{"type":"integer"},"clicks":{"type":"integer"},"first_click_at":{"type":["string","null"],"format":"date-time"},"lead_at":{"type":["string","null"],"format":"date-time"}}},"next_cursor":{"type":["object","null"],"required":["before","before_id"],"properties":{"before":{"type":"string","format":"date-time"},"before_id":{"type":"string"}}}}},"Tag":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"contacts":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"SequenceRequest":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","maxLength":80},"description":{"type":"string","maxLength":500}}},"Sequence":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"active_contacts":{"type":"integer"}}},"AutomationAnalytics":{"type":"object","properties":{"version":{"type":["object","null"],"additionalProperties":true},"versions":{"type":"array","items":{"type":"object","additionalProperties":true}},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"runs":{"type":["object","null"],"additionalProperties":{"type":"integer"},"description":"started, completed, blocked, in_progress, handed_off, canceled, people"},"steps":{"type":"array","items":{"type":"object","properties":{"node_id":{"type":"string"},"passed":{"type":"integer"},"blocked":{"type":"integer"},"timeouts":{"type":"integer"},"runs":{"type":"integer"}}}},"edges":{"type":"array","items":{"type":"object","properties":{"node_id":{"type":"string"},"branch":{"type":"string"},"count":{"type":"integer"}}}},"waiting":{"type":"array","items":{"type":"object","additionalProperties":true}},"blocked_reasons":{"type":"array","items":{"type":"object","additionalProperties":true}},"clicks":{"type":"object","additionalProperties":true},"instrumented_since":{"type":["string","null"],"format":"date-time"}}},"Platform":{"type":"string","enum":["sandbox","facebook","instagram","threads","linkedin","bluesky","mastodon","telegram","tiktok","youtube","pinterest","google_business","x"]},"PostStatus":{"type":"string","description":"pending_approval means a workspace member scheduled the post and an owner or admin must approve it in the dashboard before it is delivered.","enum":["draft","pending_approval","scheduled","processing","published","partial","failed","canceled"]},"TargetStatus":{"type":"string","enum":["pending","media_ready","publishing","reconciling","retry_scheduled","awaiting_reconnect","published","failed","skipped"]},"CreatePostRequest":{"type":"object","required":["post","profiles"],"properties":{"post":{"$ref":"#/components/schemas/PostInput"},"profiles":{"type":"array","minItems":1,"items":{"type":"string"},"description":"Profile IDs or unambiguous platform slugs."},"media":{"type":"array","maxItems":10,"items":{"type":"string"},"description":"Media IDs, public HTTP(S) URLs, or base64 data URLs."}},"additionalProperties":false},"CreatePostMultipart":{"type":"object","required":["post","profiles"],"properties":{"post":{"type":"string","description":"JSON-encoded PostInput"},"profiles":{"type":"string","description":"JSON-encoded string array"},"media":{"type":"array","maxItems":10,"items":{"type":"string","format":"binary"}}}},"TimeContext":{"type":"object","description":"Presentation timezone of the authenticated account. Offsets apply at each timestamp's instant.","required":["timezone","now"],"properties":{"timezone":{"type":"string","example":"America/Sao_Paulo"},"now":{"type":"string","format":"date-time","example":"2026-10-27T12:00:00.000-03:00"}},"additionalProperties":false},"PostInput":{"type":"object","required":["body"],"properties":{"body":{"type":"string"},"scheduled_at":{"description":"ISO date-time to publish at; an explicit offset identifies the instant and an offset-free value uses the explicit timezone or the account default. Omit to publish now. \"queue\" takes the next free slot of the profile group posting queue (a schedule with kind slots); 422 when the group has no slots, 409 when every slot in the next 30 days is taken.","anyOf":[{"type":"string","format":"date-time"},{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})?$"},{"type":"string","const":"queue"}]},"timezone":{"type":"string","description":"IANA zone; defaults to the account timezone."},"idempotency_key":{"type":"string"},"draft":{"type":"boolean","default":false},"options":{"type":"object","properties":{"youtube":{"$ref":"#/components/schemas/YouTubePostOptions"},"instagram":{"$ref":"#/components/schemas/InstagramPostOptions"},"facebook":{"$ref":"#/components/schemas/FacebookPostOptions"},"threads":{"$ref":"#/components/schemas/ThreadsPostOptions"},"pinterest":{"$ref":"#/components/schemas/PinterestPostOptions"},"tiktok":{"$ref":"#/components/schemas/TikTokPostOptions"},"sandbox":{"type":"object","properties":{"first_comment":{"type":"string","minLength":1,"maxLength":8000,"description":"Simulate a first comment in test mode."}},"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false},"CoverMediaId":{"type":"string","pattern":"^med_","description":"Cover image uploaded through POST /api/media. Use a media ID visible to the destination profile group. Supply the main video in media. The uploaded image takes precedence over the cover URL."},"PinterestPostOptions":{"type":"object","properties":{"board_id":{"type":"string"},"cover_image_url":{"type":"string","format":"uri","description":"Public image URL for a production video Pin."},"cover_media_id":{"$ref":"#/components/schemas/CoverMediaId","description":"Uploaded JPEG or PNG, up to 8 MB, for a production video Pin."}},"additionalProperties":true},"TikTokPostOptions":{"type":"object","properties":{"mode":{"type":"string","enum":["direct","inbox"]},"cover_timestamp_ms":{"type":"integer","minimum":0,"description":"Frame offset in milliseconds for Direct Post videos."},"cover_image_index":{"type":"integer","minimum":0,"description":"Zero-based index of the cover photo in the media array."}},"additionalProperties":true},"YouTubePostOptions":{"type":"object","required":["title","privacy","made_for_kids","community_guidelines_confirmed"],"properties":{"title":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","description":"Maximum 5,000 UTF-8 bytes. Defaults to post.body when omitted."},"privacy":{"type":"string","enum":["private","unlisted","public"]},"made_for_kids":{"type":"boolean"},"community_guidelines_confirmed":{"type":"boolean","const":true},"cover_media_id":{"$ref":"#/components/schemas/CoverMediaId","description":"Uploaded JPEG or PNG, up to 2 MB, for the video thumbnail."},"thumbnail_url":{"type":"string","format":"uri","description":"Optional custom thumbnail, an https URL to a JPEG or PNG up to 2 MB (1280x720 recommended). Applied right after the upload; the channel must be phone-verified. If YouTube refuses it, the video stays published and the target's provider response records thumbnail.status=failed with the reason."}},"additionalProperties":true},"InstagramPostOptions":{"type":"object","properties":{"first_comment":{"type":"string","minLength":1,"maxLength":2196,"description":"Sent after a feed post or Reel is published. Requires instagram_business_manage_comments and comments enabled."},"mode":{"type":"string","enum":["story"],"description":"Set to \"story\" to publish a single image or video as an Instagram Story instead of a feed post, Reel, or carousel. Stories require exactly one media item; carousels and alt text are not supported, and post.body is not sent because Instagram Stories do not display a caption."},"disable_comment":{"type":"boolean","description":"Turn comments off right after publishing (feed posts and Reels, not Stories). Needs instagram_business_manage_comments; if Instagram refuses, the post stays published and the target's provider response records comments_disabled=false."},"share_to_feed":{"type":"boolean","default":true,"description":"For a single-video post (published as a Reel), also show it in the profile feed grid."},"trial_params":{"type":"object","required":["graduation_strategy"],"description":"Publish the Reel as a trial reel, shown to non-followers first. Single-video, non-story posts only. Graduation status cannot be read through the Instagram API.","properties":{"graduation_strategy":{"type":"string","enum":["MANUAL","SS_PERFORMANCE"],"description":"MANUAL lets the creator share it with followers in the Instagram app; SS_PERFORMANCE lets Instagram share it automatically if it performs well."}}},"alt_text":{"type":"string","maxLength":1000,"description":"Alt text for a single image post. Ignored on video."},"alt_texts":{"type":"array","items":{"type":"string","maxLength":1000},"description":"Alt text per media item, by position (carousel images). Overrides alt_text."},"collaborators":{"type":"array","maxItems":3,"items":{"type":"string"},"description":"Instagram usernames invited as collaborators. Not supported for stories."},"user_tags":{"type":"array","description":"People tagged on a single photo or video. On photos x and y (0-1) are required.","items":{"type":"object","required":["username"],"properties":{"username":{"type":"string"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}}}},"location_id":{"type":"string","description":"ID of a Facebook Page with location data."},"cover_media_id":{"$ref":"#/components/schemas/CoverMediaId","description":"Uploaded JPEG, up to 8 MB, for a single-video Reel."},"cover_url":{"type":"string","format":"uri","description":"JPEG cover for a single-video Reel (overrides thumb_offset)."},"thumb_offset":{"type":"integer","minimum":0,"description":"Frame (milliseconds) used as the Reel cover."},"audio_name":{"type":"string","description":"Name for the Reel's original audio. Can be renamed only once."},"is_ai_generated":{"type":"boolean","description":"Label the post as AI-generated."}},"additionalProperties":true},"FacebookPostOptions":{"type":"object","properties":{"first_comment":{"type":"string","minLength":1,"maxLength":8000,"description":"Sent after a Page feed post or Reel is published. Requires pages_manage_engagement."},"mode":{"type":"string","enum":["story","reel"],"description":"\"story\" publishes a single photo or video as a Facebook Page Story instead of a feed post. Requires exactly one media item: video must be 3-60 seconds and ideally 9:16 (minimum 540x960px); photo must be under 10MB. No text/caption is supported and the result has no durable public permalink. \"reel\" publishes a single video (3-90 seconds, 9:16, minimum 540x960px) as a Page Reel with post.body as its description. The target's platform_post_id is the Reel's video ID and its stats come from Reel video insights."}},"additionalProperties":true},"ThreadsPostOptions":{"type":"object","properties":{"first_comment":{"type":"string","minLength":1,"maxLength":500,"description":"Sent as a reply to the root post after it is published."},"topic_tag":{"type":"string","maxLength":50,"description":"Topic tag for the root post; no periods or ampersands."},"reply_control":{"type":"string","enum":["everyone","accounts_you_follow","mentioned_only","parent_post_author_only","followers_only"]},"quote_post_id":{"type":"string","description":"Threads media ID to quote."},"link_attachment":{"type":"string","format":"uri","description":"Link preview URL. Text-only posts."},"poll":{"type":"array","minItems":2,"maxItems":4,"items":{"type":"string","minLength":1,"maxLength":25},"description":"Poll options for a text-only root post (sent as poll_attachment option_a..option_d)."},"spoiler_media":{"type":"boolean","description":"Blur the attached media as a spoiler."},"is_ai_generated":{"type":"boolean","description":"Label the post as made with AI (sent as is_made_with_ai)."}},"additionalProperties":true},"UpdatePostRequest":{"type":"object","required":["post"],"properties":{"post":{"type":"object","properties":{"body":{"type":"string"},"scheduled_at":{"description":"Explicit-offset ISO instant or a local date-time in the supplied timezone or account default.","anyOf":[{"type":"string","format":"date-time"},{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})?$"},{"type":"null"}]},"timezone":{"type":"string"},"options":{"type":"object","additionalProperties":true,"description":"Per-platform publishing options. Supports the same cover and first_comment fields as PostInput."}},"additionalProperties":false}},"additionalProperties":false},"Post":{"type":"object","required":["id","body","status","targets"],"properties":{"id":{"type":"string"},"body":{"type":"string"},"options":{"type":"object","additionalProperties":true},"status":{"$ref":"#/components/schemas/PostStatus"},"scheduled_at":{"type":["string","null"],"format":"date-time"},"timezone":{"type":"string"},"created_via":{"type":"string","enum":["api","dashboard","mcp","schedule","imported"]},"trace_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/Target"}},"media":{"type":"array","items":{"$ref":"#/components/schemas/MediaAsset"}}},"additionalProperties":true},"Target":{"type":"object","required":["id","profile_id","platform","status"],"properties":{"id":{"type":"string"},"profile_id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"status":{"$ref":"#/components/schemas/TargetStatus"},"first_comment":{"type":["object","null"],"description":"Independent delivery result for the first comment. Null before the post is published or if no first comment was configured.","required":["status"],"properties":{"status":{"type":"string","enum":["pending","sending","published","failed","unconfirmed"]},"platform_comment_id":{"type":"string"},"error_code":{"type":"string","enum":["comment_permission_required","comment_rejected","comment_retries_exhausted","delivery_unconfirmed"]}}},"platform_post_id":{"type":["string","null"]},"permalink":{"type":["string","null"],"format":"uri"},"transformations":{"type":"array","items":{"type":"string"}},"error_code":{"type":["string","null"]},"error_message":{"type":["string","null"]},"error_details":{"description":"Validation issues or safe provider diagnostics. account_restricted means the network blocked account activity; review account status before retrying.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array","items":{"type":"object","additionalProperties":true}},{"type":"null"}]},"attempt_count":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"published_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"PostList":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"meta":{"$ref":"#/components/schemas/Pagination"}}},"Pagination":{"type":"object","required":["page","per_page","total","total_pages"],"properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}}},"MediaAsset":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"source":{"type":"string"},"mime":{"type":["string","null"]},"bytes":{"type":["integer","null"]},"sha256":{"type":["string","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"duration_s":{"type":["number","null"]},"content_url":{"type":["string","null"],"format":"uri","description":"Stable public URL for the ready media object."},"status":{"type":"string","enum":["pending","uploaded","processing","ready","failed"]},"probe":{"type":"object","additionalProperties":true},"error":{"type":["object","null"],"additionalProperties":true},"expires_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"CreateMediaFromUrl":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"filename":{"type":"string"},"mime":{"type":"string"},"bytes":{"type":"integer","minimum":1}},"additionalProperties":false},"CreateMultipartMediaUpload":{"type":"object","required":["source","filename","mime","bytes"],"properties":{"source":{"type":"string","const":"upload"},"filename":{"type":"string","minLength":1,"maxLength":255},"mime":{"type":"string","pattern":"^(image|video)/","description":"SVG and other markup types are rejected."},"bytes":{"type":"integer","minimum":1,"maximum":500000000}},"additionalProperties":false},"CompleteMultipartMediaUpload":{"type":"object","required":["upload_id","parts"],"properties":{"upload_id":{"type":"string","minLength":1},"parts":{"type":"array","minItems":1,"maxItems":10000,"items":{"type":"object","required":["part_number","etag"],"properties":{"part_number":{"type":"integer","minimum":1},"etag":{"type":"string","minLength":1}},"additionalProperties":false}}},"additionalProperties":false},"ProfileGroup":{"type":"object","required":["id","name","timezone"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"brand":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"ProfileGroupList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProfileGroup"}}}},"BestTimes":{"type":"object","required":["timezone","days","data"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"timezone":{"type":"string"},"days":{"type":"integer"},"data":{"type":"array","description":"Empty until at least five published posts have analytics.","items":{"type":"object","required":["weekday","hour","score","lift","samples"],"properties":{"weekday":{"type":"integer","minimum":0,"maximum":6,"description":"0 = Sunday"},"hour":{"type":"integer","minimum":0,"maximum":23},"score":{"type":"number","description":"Average engagement rate (or raw engagement when the networks report no impressions)."},"lift":{"type":"number","description":"Score relative to the mean, e.g. 0.4 means 40 percent above average."},"samples":{"type":"integer"}},"additionalProperties":false}},"online_hours":{"type":["array","null"],"description":"Hours the group's Instagram followers are most online (Instagram's 30-day average, shifted to `timezone`). Needs no post history. `null` without a connected Instagram profile with insights, without the analytics plan feature, or below 100 followers.","items":{"type":"object","required":["hour","followers"],"properties":{"hour":{"type":"integer","minimum":0,"maximum":23},"followers":{"type":"integer","description":"Average followers online in that hour."}},"additionalProperties":false}}},"additionalProperties":false},"CreateProfileGroupRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1},"timezone":{"type":"string","description":"IANA zone; defaults to the account timezone."},"brand":{"type":"object","additionalProperties":true}},"additionalProperties":false},"Profile":{"type":"object","required":["id","group_id","platform","platform_account_id","display_name","status"],"properties":{"id":{"type":"string"},"group_id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"platform_account_id":{"type":"string"},"display_name":{"type":"string"},"avatar_url":{"type":["string","null"],"format":"uri","description":"Stable PostGate-hosted avatar URL when a synchronized copy is available; otherwise the provider URL."},"status":{"type":"string","enum":["connected","expired","revoked","error"]},"scopes":{"type":"array","items":{"type":"string"}},"meta":{"type":"object","additionalProperties":true},"last_verified_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"ProfileList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Profile"}}}},"Board":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","description":"Use as post.options.pinterest.board_id."},"name":{"type":"string"},"description":{"type":"string"},"privacy":{"type":"string","description":"Provider value, for example PUBLIC, PROTECTED, or SECRET."}},"additionalProperties":false},"BoardList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Board"}},"meta":{"type":"object","properties":{"profile_id":{"type":"string"},"fetched_at":{"type":"string","format":"date-time","description":"Boards are read live on every call and never cached by PostGate."}}}}},"ProfileHealth":{"type":"object","required":["id","platform","status","scopes","reconnect_required"],"properties":{"id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"status":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"last_verified_at":{"type":["string","null"],"format":"date-time"},"reconnect_required":{"type":"boolean"},"token":{"oneOf":[{"type":"null"},{"type":"object","properties":{"expires_at":{"type":"string","format":"date-time"},"refreshable":{"type":"boolean"}}}]},"publishing_quota":{"description":"Instagram only. Posts published through the API in Instagram's rolling 24-hour window; `null` when unreadable.","oneOf":[{"type":"null"},{"type":"object","required":["used","total","window_seconds"],"properties":{"used":{"type":"integer"},"total":{"type":["integer","null"]},"window_seconds":{"type":["integer","null"]}}}]}}},"CreateConnectRequest":{"type":"object","required":["platform"],"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"profile_group_id":{"type":"string"},"return_url":{"type":"string","format":"uri","description":"Where PostGate sends the browser once the network finishes authorizing. Its origin must be registered with `POST /api/connect-origins` first. On success PostGate appends `connected` and `connection_platform`; on failure it appends `connection_error` and `connection_platform`."},"instance_url":{"type":"string","format":"uri","description":"Required when connecting a Mastodon account."},"linkedin_account_type":{"type":"string","enum":["member","organization"],"default":"member","description":"LinkedIn only. organization uses the separate approved Community Management app and a hosted Page selector after OAuth. Only selected administered Pages are connected. The selection expires after ten minutes and is single-use. Member connections keep the existing OpenID Connect app. Unavailable Page connections return 503."}},"additionalProperties":false},"ConnectLink":{"type":"object","required":["id","url","profile_group_id","platforms","status","usable","connected_platforms","pending_platforms","expires_at","connections","created_at"],"properties":{"id":{"type":"string","example":"clink_01jb..."},"url":{"type":"string","format":"uri","description":"Shareable URL; no PostGate login is needed to use it."},"profile_group_id":{"type":"string"},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/Platform"}},"label":{"type":["string","null"]},"status":{"type":"string","enum":["pending","partial","completed","expired","revoked"],"description":"`completed` once every selected network has at least one connected account (even if the link later expired or was revoked); otherwise `revoked` or `expired` when the link stopped working, else `partial` or `pending`."},"usable":{"type":"boolean","description":"Whether the URL still accepts connections. A completed link stays usable until it expires."},"connected_platforms":{"type":"array","items":{"$ref":"#/components/schemas/Platform"}},"pending_platforms":{"type":"array","items":{"$ref":"#/components/schemas/Platform"}},"expires_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"connections":{"type":"array","items":{"type":"object","properties":{"profile_id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"display_name":{"type":"string"},"connected_at":{"type":"string","format":"date-time"}}}},"created_at":{"type":"string","format":"date-time"}}},"ConnectUrl":{"type":"object","required":["platform","url","expires_in"],"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"url":{"type":"string","format":"uri"},"expires_in":{"type":"integer","minimum":1,"description":"Lifetime of the hosted connection URL in seconds."}}},"DeliveryAttemptList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"StatsList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true,"properties":{"metrics":{"type":"object","additionalProperties":true,"description":"Normalized counters (impressions, reach, likes, comments, shares, saved, clicks, engagements, ...) plus the raw provider payload.","properties":{"avg_watch_time_ms":{"type":"number","description":"Instagram Reels only: average play time in milliseconds. Absent for other posts."},"total_watch_time_ms":{"type":"number","description":"Instagram Reels only: total play time including replays, in milliseconds."},"skip_rate":{"type":"number","description":"Instagram Reels only: percentage (0-100) of views that skipped within the first 3 seconds."},"total_interactions":{"type":"number","description":"Instagram only: interactions as Meta counts them (likes, comments, saves, shares and Story replies, net of undos)."},"profile_visits":{"type":"number","description":"Instagram feed posts and Stories: profile visits from this post. Absent for Reels and other networks."},"follows":{"type":"number","description":"Instagram feed posts and Stories: accounts that followed from this post."},"profile_activity":{"type":"number","description":"Instagram feed posts and Stories: profile actions (bio link, call, email, directions taps) from this post."},"story_navigation":{"type":"number","description":"Instagram Stories only: taps forward, taps back, exits and swipes."},"profile_activity_by_action":{"type":"object","additionalProperties":{"type":"number"},"description":"Instagram feed posts and Stories: profile_activity by lowercase action type (bio_link_clicked, call, direction, email, text, other)."},"story_navigation_by_action":{"type":"object","additionalProperties":{"type":"number"},"description":"Instagram Stories: navigation by lowercase action (tap_forward, tap_back, tap_exit, swipe_forward)."}}}}}}}},"AccountInsights":{"type":"object","required":["platform","from","to","timezone","captured_at","metrics"],"properties":{"source":{"type":"string","enum":["instagram_account_insights","facebook_page_insights","threads_account_insights"]},"platform":{"type":"string","enum":["instagram","facebook","threads"]},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"timezone":{"type":"string","enum":["UTC"]},"captured_at":{"type":"string","format":"date-time"},"metrics":{"type":"object","properties":{"views":{"type":["number","null"]},"reach":{"type":["number","null"],"description":"Native period-unique reach (Instagram only)."},"total_interactions":{"type":["number","null"]},"follows":{"type":["number","null"],"description":"New follows in the period (Instagram, Facebook)."},"unfollows":{"type":["number","null"],"description":"Unfollows in the period (Instagram, Facebook)."},"profile_links_taps":{"type":["number","null"],"description":"Taps on profile contact buttons and links (Instagram)."},"followers":{"type":["number","null"],"description":"Current follower count (Threads)."}}},"audience_split":{"description":"Instagram only (null elsewhere). Reach and views from followers vs non-followers; viewers Instagram cannot classify are left out. Each side is null when unreported.","oneOf":[{"type":"null"},{"type":"object","properties":{"reach":{"$ref":"#/components/schemas/FollowerSplit"},"views":{"$ref":"#/components/schemas/FollowerSplit"}}}]}}},"FollowerSplit":{"oneOf":[{"type":"null"},{"type":"object","required":["followers","non_followers"],"properties":{"followers":{"type":"number"},"non_followers":{"type":"number"}}}]},"IceBreakers":{"type":"object","required":["data"],"properties":{"data":{"type":"array","maxItems":4,"items":{"type":"object","required":["question","payload"],"properties":{"question":{"type":"string","maxLength":80},"payload":{"type":"string","maxLength":1000}},"additionalProperties":false}}},"additionalProperties":false},"Demographics":{"type":["object","null"],"properties":{"age":{"$ref":"#/components/schemas/DemographicValues"},"gender":{"$ref":"#/components/schemas/DemographicValues"},"country":{"$ref":"#/components/schemas/DemographicValues"},"city":{"$ref":"#/components/schemas/DemographicValues"}}},"DemographicValues":{"type":["array","null"],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"number"}}}},"AudienceInsights":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","threads"]},"timeframe":{"type":["string","null"]},"captured_at":{"type":"string","format":"date-time"},"follower_demographics":{"$ref":"#/components/schemas/Demographics"},"engaged_audience_demographics":{"$ref":"#/components/schemas/Demographics"},"online_followers":{"type":["array","null"],"items":{"type":"number"},"description":"Instagram only. Average followers online for each hour 0-23 as keyed by Instagram (Meta reports insight days in Pacific time)."}}},"AnalyticsMetrics":{"type":"object","required":["impressions","reach","likes","comments","shares","saved","clicks","engagements"],"properties":{"impressions":{"type":"number"},"reach":{"type":"number"},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"saved":{"type":"number"},"clicks":{"type":"number"},"engagements":{"type":"number"}}},"AnalyticsSeriesPoint":{"type":"object","required":["date","profile_group_id","platform","metrics","followers","follower_delta"],"properties":{"date":{"type":"string","format":"date"},"profile_group_id":{"type":"string"},"platform":{"type":"string"},"metrics":{"$ref":"#/components/schemas/AnalyticsMetrics"},"followers":{"type":"number"},"follower_delta":{"type":"number"}}},"AnalyticsSeriesSummary":{"allOf":[{"$ref":"#/components/schemas/AnalyticsMetrics"},{"type":"object","required":["followers","follower_delta"],"properties":{"followers":{"type":"number"},"follower_delta":{"type":"number"}}}]},"AnalyticsPeriod":{"type":"object","required":["range","data","summary"],"properties":{"range":{"type":"object","required":["from","to","timezone"],"properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"timezone":{"type":"string"}}},"data":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsSeriesPoint"}},"summary":{"$ref":"#/components/schemas/AnalyticsSeriesSummary"}}},"AnalyticsTimeseries":{"allOf":[{"$ref":"#/components/schemas/AnalyticsPeriod"},{"type":"object","properties":{"comparison":{"anyOf":[{"$ref":"#/components/schemas/AnalyticsPeriod"},{"type":"null"}]}}}]},"Comment":{"type":"object","required":["id","text"],"properties":{"id":{"type":"string"},"target_id":{"type":"string"},"platform_comment_id":{"type":["string","null"]},"author":{"type":"object","additionalProperties":true},"text":{"type":"string"},"parent_id":{"type":["string","null"]},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"CommentList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}}},"InboxComment":{"type":"object","required":["id","profile_id","platform","text","created_at"],"properties":{"id":{"type":"string"},"platform_comment_id":{"type":"string"},"profile_id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"post_id":{"type":["string","null"],"description":"Null for comments on media PostGate did not publish."},"target_id":{"type":["string","null"]},"platform_media_id":{"type":["string","null"]},"parent_id":{"type":["string","null"]},"author":{"type":"object","additionalProperties":true},"text":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"hidden":{"type":"boolean"},"hide_status":{"type":"string","enum":["visible","hiding","hidden","unhiding","failed"]},"deletion_status":{"type":"string","enum":["active","pending","failed"]},"private_reply_status":{"type":["string","null"],"enum":["reserved","sent","unknown",null]}},"additionalProperties":true},"InboxCommentList":{"type":"object","required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/InboxComment"}},"has_more":{"type":"boolean"},"next_cursor":{"anyOf":[{"type":"object","required":["before","before_id"],"properties":{"before":{"type":"string","format":"date-time"},"before_id":{"type":"string"}}},{"type":"null"}]}}},"InboxCommentDetail":{"allOf":[{"$ref":"#/components/schemas/InboxComment"},{"type":"object","required":["replies","actions"],"properties":{"replies":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["public_reply","private_reply","message"]},"status":{"type":"string"},"reason":{"type":["string","null"]},"provider_message_id":{"type":["string","null"]},"message_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}}}}}]},"CommentHideResult":{"type":"object","required":["id","hidden","status"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"id":{"type":"string"},"hidden":{"type":"boolean"},"status":{"type":"string","enum":["hiding","unhiding"]}},"additionalProperties":false},"PrivateReplyRequest":{"type":"object","description":"Provide exactly one of text or message.","properties":{"text":{"type":"string","minLength":1},"message":{"$ref":"#/components/schemas/EngagementMessage"}},"additionalProperties":false},"Conversation":{"type":"object","required":["id","profile_id"],"properties":{"id":{"type":"string"},"profile_id":{"type":"string"},"platform_conv_id":{"type":"string"},"peer":{"type":"object","additionalProperties":true},"last_message_at":{"type":["string","null"],"format":"date-time"},"owner":{"type":"string","enum":["automation","human","external"]},"owner_version":{"type":"integer"},"assigned_to":{"type":["string","null"]},"opted_out":{"type":"boolean"},"mode":{"type":"string","enum":["test","live"]},"last_user_interaction_at":{"type":["string","null"],"format":"date-time"},"window_expires_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"ConversationList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"}}}},"Message":{"type":"object","required":["id","conversation_id","direction","text","status"],"properties":{"id":{"type":"string"},"conversation_id":{"type":"string"},"platform_message_id":{"type":["string","null"]},"direction":{"type":"string","enum":["inbound","outbound"]},"text":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"sent_at":{"type":["string","null"],"format":"date-time"},"actor":{"type":"string","enum":["automation","human","external","user"]},"content":{"type":["object","null"],"additionalProperties":true},"deleted_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"MessageList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"has_more":{"type":"boolean"},"sync_cursor":{"type":"object","required":["at"],"properties":{"at":{"type":"string","format":"date-time"},"id":{"type":"string"}}}}},"TextRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1}},"additionalProperties":false},"IdResponse":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"CommentAutomation":{"type":"object","required":["id","profile_id","scope","match_type","dm_template","once_per_user","active"],"properties":{"id":{"type":"string"},"profile_id":{"type":"string"},"scope":{"type":"string","enum":["all_posts","post"]},"platform_post_id":{"type":["string","null"]},"match_type":{"type":"string","enum":["any_comment","keywords"]},"keywords":{"type":"array","items":{"type":"string"}},"dm_template":{"type":"string","maxLength":1000},"reply_to_comment_enabled":{"type":"boolean"},"reply_to_comment_templates":{"type":"array","items":{"type":"string"}},"once_per_user":{"type":"boolean"},"active":{"type":"boolean"},"disabled_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"CommentAutomationList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CommentAutomation"}}}},"CommentAutomationCreateRequest":{"type":"object","required":["profile_id","scope","dm_template"],"properties":{"profile_id":{"type":"string","description":"A connected Instagram or Facebook profile with the messages engagement scope granted."},"scope":{"type":"string","enum":["all_posts","post"],"description":"Whether the automation matches comments on every post or one specific post."},"platform_post_id":{"type":"string","description":"Required when scope is \"post\" — the platform's own post/media id, not PostGate's internal post id."},"match_type":{"type":"string","enum":["any_comment","keywords"],"default":"any_comment"},"keywords":{"type":"array","items":{"type":"string"},"description":"Whole-word, accent- and case-insensitive. Required when match_type is \"keywords\"."},"dm_template":{"type":"string","minLength":1,"maxLength":1000,"description":"The private reply text. Supports {{username}}."},"reply_to_comment_enabled":{"type":"boolean","default":false,"description":"Also post a public reply, chosen at random from reply_to_comment_templates."},"reply_to_comment_templates":{"type":"array","items":{"type":"string"}},"once_per_user":{"type":"boolean","default":true,"description":"Send at most one DM per commenter across the automation's lifetime."}},"additionalProperties":false},"CommentAutomationUpdateRequest":{"type":"object","properties":{"match_type":{"type":"string","enum":["any_comment","keywords"]},"keywords":{"type":"array","items":{"type":"string"}},"dm_template":{"type":"string","minLength":1,"maxLength":1000},"reply_to_comment_enabled":{"type":"boolean"},"reply_to_comment_templates":{"type":"array","items":{"type":"string"}},"once_per_user":{"type":"boolean"},"active":{"type":"boolean","description":"Set false to pause without deleting."}},"additionalProperties":false},"CommentAutomationRun":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","sent","skipped","failed"]},"platform_comment_id":{"type":"string"},"platform_commenter_id":{"type":"string"},"provider_message_id":{"type":["string","null"]},"public_reply_sent":{"type":"boolean"},"error":{"type":["string","null"]},"sent_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"CommentAutomationRunList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CommentAutomationRun"}}}},"WebhookDelivery":{"type":"object","required":["id","event_id","event","status","attempts","payload","created_at"],"properties":{"id":{"type":"string"},"event_id":{"type":"string"},"event":{"type":"string"},"status":{"type":"string","enum":["pending","delivering","delivered","retry_scheduled","failed"]},"attempts":{"type":"integer"},"response_status":{"type":["integer","null"]},"last_error":{"type":["object","null"],"additionalProperties":true},"payload":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"},"next_at":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false},"Webhook":{"type":"object","required":["id","url","events","active"],"properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"secret":{"type":"string","description":"Only present in the create response."},"created_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"WebhookList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}},"CreateWebhookRequest":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","minItems":1,"items":{"type":"string"},"description":"Topics to deliver. Full catalog: post.draft, post.scheduled, post.published, post.partial, post.failed, post.insights, profile.connected, profile.disconnected, profile.expiring, profile.expired, profile.reauth_required, profile.stats_updated, stats.updated, comment.created, message.received, message.sent, automation.executed, automation.failed. post.insights and profile.stats_updated report analytics snapshots; profile.expired and profile.reauth_required report authorization health and carry a reason of token_expired, refresh_failed, revoked, or publish_auth_error. automation.executed and automation.failed are emitted by comment-to-DM automations (see the Comment automations tag) and are currently gated to workspaces enrolled in the Instagram engagement rollout."}},"additionalProperties":false},"Schedule":{"type":"object","required":["id","group_id","name","kind","expression","template","timezone","active"],"properties":{"id":{"type":"string"},"group_id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["cron","slots"]},"expression":{"type":"string"},"template":{"type":"object","additionalProperties":true},"timezone":{"type":"string"},"active":{"type":"boolean"},"materialized_until":{"type":["string","null"],"format":"date-time"}},"additionalProperties":true},"ScheduleList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Schedule"}}}},"ScheduleWrite":{"type":"object","required":["expression"],"properties":{"name":{"type":"string","minLength":1,"description":"Defaults to \"Queue\" for kind slots."},"profile_group_id":{"type":"string","description":"Required when an organization-scoped key has no default group."},"kind":{"type":"string","enum":["cron","slots"],"default":"cron","description":"cron materializes posts from the template; slots is the posting queue used by scheduled_at=\"queue\" and never creates posts on its own."},"expression":{"type":"string","description":"A cron expression for kind cron, or comma-separated HH:mm times (e.g. \"09:00,18:00\") in the schedule timezone for kind slots."},"template":{"description":"Required for kind cron; ignored for kind slots.","type":"object","required":["post","profiles"],"properties":{"post":{"type":"object","required":["body"],"properties":{"body":{"type":"string"},"options":{"type":"object","additionalProperties":true,"description":"Per-platform publishing options. Supports the same cover and first_comment fields as PostInput."}},"additionalProperties":false},"profiles":{"type":"array","minItems":1,"items":{"type":"string"}},"media":{"type":"array","items":{"type":"string"},"default":[],"description":"IDs (med_...) of media already uploaded to this workspace through POST /api/media. URLs and data URLs are not accepted; an unknown ID is rejected with 422."}},"additionalProperties":false},"timezone":{"type":"string","description":"IANA zone; defaults to the account timezone."}},"additionalProperties":false},"SchedulePatch":{"type":"object","properties":{"name":{"type":"string","minLength":1},"expression":{"type":"string"},"timezone":{"type":"string"},"active":{"type":"boolean"}},"additionalProperties":false},"CreateApiKeyRequest":{"type":"object","required":["name","scopes","mode"],"properties":{"name":{"type":"string","minLength":1},"scopes":{"type":"array","minItems":1,"items":{"type":"string","enum":["full","publish","read"]}},"mode":{"type":"string","enum":["test","live"]},"group_id":{"type":"string"}},"additionalProperties":false},"CreatedApiKey":{"type":"object","required":["id","key","name","scopes","mode"],"properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"mode":{"type":"string","enum":["test","live"]}}},"CreateEnvironmentRequest":{"type":"object","required":["name","mode"],"properties":{"name":{"type":"string","minLength":1},"mode":{"type":"string","enum":["test","live"]},"brand":{"type":"object","additionalProperties":true}},"additionalProperties":false},"UpdateEnvironmentRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"brand":{"type":"object","additionalProperties":true},"custom_domain":{"type":["string","null"]},"logo_url":{"type":["string","null"],"format":"uri"},"primary_color":{"type":["string","null"],"pattern":"^#[0-9a-fA-F]{6}$"}},"additionalProperties":false},"PutPlatformAppRequest":{"type":"object","required":["client_id","client_secret"],"properties":{"client_id":{"type":"string","minLength":1},"client_secret":{"type":"string","minLength":1},"quotas":{"type":"object","additionalProperties":true}},"additionalProperties":false},"GenericList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"time_context":{"$ref":"#/components/schemas/TimeContext"},"error":{"type":"object","required":["code","message","retryable"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"platform":{"type":"string"},"retryable":{"type":"boolean"},"details":{},"request_id":{"type":"string"}},"additionalProperties":true}},"additionalProperties":false},"AutomationGraph":{"type":"object","properties":{"schema_version":{"type":"number","const":1},"entry":{"type":"string","minLength":1},"nodes":{"minItems":2,"maxItems":100,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"trigger"},"config":{"type":"object","properties":{"type":{"type":"string","enum":["comment","dm","story_reply","story_mention"]},"scope":{"default":"all_posts","type":"string","enum":["all_posts","post"]},"platform_post_id":{"type":"string","minLength":1},"scheduled_post_id":{"type":"string","minLength":1},"match_type":{"default":"keywords","type":"string","enum":["any","keywords"]},"keywords":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"exclude_keywords":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"once_per_person":{"default":true,"type":"boolean"}},"required":["type"],"additionalProperties":false}},"required":["id","type","config"],"description":"Entry step. Exactly one per graph, referenced by graph.entry. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"message"},"config":{"type":"object","properties":{"message":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"text"},"text":{"type":"string","minLength":1,"maxLength":4000}},"required":["type","text"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"buttons"},"text":{"type":"string","minLength":1,"maxLength":4000},"buttons":{"minItems":1,"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","text","buttons"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"quick_replies"},"text":{"type":"string","minLength":1,"maxLength":4000},"quick_replies":{"minItems":1,"maxItems":13,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["title","payload"],"additionalProperties":false}}},"required":["type","text","quick_replies"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["image","file"]},"media_id":{"type":"string","minLength":1}},"required":["type","media_id"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"card"},"title":{"type":"string","minLength":1,"maxLength":80},"subtitle":{"type":"string","maxLength":80},"media_id":{"type":"string","minLength":1},"buttons":{"default":[],"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","title"],"additionalProperties":false}]},"private_reply":{"default":false,"type":"boolean"}},"required":["message"],"additionalProperties":false}},"required":["id","type","config"],"description":"Sends a DM. private_reply=true sends it as the private reply to the triggering comment (one per comment, within 7 days). Text supports {{username}}, {{comment}} and captured variables. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"public_reply"},"config":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":4000}},"required":["text"],"additionalProperties":false}},"required":["id","type","config"],"description":"Replies publicly to the triggering comment. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"wait_reply"},"config":{"type":"object","properties":{"variable":{"default":"answer","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Waits for the person's next DM and stores it in variable. With timeout_seconds: two edges, branch \"reply\" and \"timeout\". Without: one edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"collect_email"},"config":{"type":"object","properties":{"variable":{"default":"email","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"invalid_text":{"default":"This doesn't look like a valid email. Could you check it?","type":"string","minLength":1,"maxLength":4000},"max_attempts":{"default":2,"type":"integer","minimum":1,"maximum":3},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Asks for an email until valid or max_attempts. Edges: branch \"valid\" and \"invalid\", plus \"timeout\" when timeout_seconds is set."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"collect_phone"},"config":{"type":"object","properties":{"variable":{"default":"phone","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"invalid_text":{"default":"Please include the country code, e.g. +5511999999999.","type":"string","minLength":1,"maxLength":4000},"max_attempts":{"default":2,"type":"integer","minimum":1,"maximum":3},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Collects a phone/WhatsApp number with an explicit country code and stores it in the contact phone field. Edges: valid, invalid, and timeout when configured. Does not verify WhatsApp registration."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"tag"},"config":{"type":"object","properties":{"action":{"type":"string","enum":["add","remove"]},"tag":{"type":"string","minLength":1,"maxLength":60}},"required":["action","tag"],"additionalProperties":false}},"required":["id","type","config"],"description":"Adds or removes a contact tag. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"set_field"},"config":{"type":"object","properties":{"field":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},"value":{"type":"string","maxLength":500}},"required":["field","value"],"additionalProperties":false}},"required":["id","type","config"],"description":"Sets a custom contact field. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"sequence"},"config":{"type":"object","properties":{"action":{"type":"string","enum":["subscribe","unsubscribe"]},"sequence_id":{"type":"string","minLength":1,"maxLength":80}},"required":["action","sequence_id"],"additionalProperties":false}},"required":["id","type","config"],"description":"Subscribes or unsubscribes the contact from a sequence (id from list_sequences). Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"check"},"config":{"type":"object","properties":{"rule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"tag"},"tag":{"type":"string","minLength":1,"maxLength":60}},"required":["type","tag"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"has_email"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"follows"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"last_interaction"},"within_hours":{"type":"integer","minimum":1,"maximum":2160}},"required":["type","within_hours"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"field"},"field":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},"operator":{"type":"string","enum":["equals","contains","exists","not_exists"]},"value":{"type":"string","maxLength":500}},"required":["type","field","operator"],"additionalProperties":false}]}},"required":["rule"],"additionalProperties":false}},"required":["id","type","config"],"description":"Tests a contact rule. Edges: branch \"true\" and \"false\", plus \"unknown\" for the follows rule."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"random"},"config":{"type":"object","properties":{"splits":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_-]{1,32}$"},"label":{"default":"","type":"string","maxLength":40},"weight":{"type":"integer","minimum":1,"maximum":100}},"required":["id","weight"],"additionalProperties":false}}},"required":["splits"],"additionalProperties":false}},"required":["id","type","config"],"description":"Random A/B split. One edge per split, with branch equal to the split id."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"condition"},"config":{"type":"object","properties":{"variable":{"type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_.]{0,127}$"},"operator":{"type":"string","enum":["equals","contains","exists","not_exists"]},"value":{"type":"string","maxLength":2000}},"required":["variable","operator"],"additionalProperties":false}},"required":["id","type","config"],"description":"Compares a captured variable. Edges: branch \"true\" and \"false\"."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"delay"},"config":{"type":"object","properties":{"seconds":{"type":"integer","minimum":1,"maximum":82800}},"required":["seconds"],"additionalProperties":false}},"required":["id","type","config"],"description":"Waits a fixed time. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"external"},"config":{"type":"object","properties":{"webhook_id":{"type":"string","minLength":1},"wait_for_result":{"default":true,"type":"boolean"},"variable":{"default":"external_result","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"}},"required":["webhook_id"],"additionalProperties":false}},"required":["id","type","config"],"description":"Calls a registered webhook (id from list_webhooks) and optionally waits for its result. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"handoff"},"config":{"type":"object","properties":{"note":{"default":"","type":"string","maxLength":1000}},"additionalProperties":false}},"required":["id","type","config"],"description":"Hands the conversation to a human. Terminal: no outgoing edges."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"end"},"config":{"type":"object","properties":{},"additionalProperties":false}},"required":["id","type","config"],"description":"Ends the flow. Terminal: no outgoing edges."}]}},"edges":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"source":{"type":"string"},"target":{"type":"string"},"branch":{"description":"Required on edges leaving condition, check, random, collect_email, collect_phone and wait_reply with a timeout; omitted otherwise.","type":"string","maxLength":256}},"required":["id","source","target"],"additionalProperties":false}}},"required":["schema_version","entry","nodes","edges"],"additionalProperties":false,"description":"Automation flow. graph.entry is the single trigger node; every node must be reachable from it and cycles are not allowed."},"AutomationDraftRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"profile_id":{"type":"string","minLength":1},"graph":{"type":"object","properties":{"schema_version":{"type":"number","const":1},"entry":{"type":"string","minLength":1},"nodes":{"minItems":2,"maxItems":100,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"trigger"},"config":{"type":"object","properties":{"type":{"type":"string","enum":["comment","dm","story_reply","story_mention"]},"scope":{"default":"all_posts","type":"string","enum":["all_posts","post"]},"platform_post_id":{"type":"string","minLength":1},"scheduled_post_id":{"type":"string","minLength":1},"match_type":{"default":"keywords","type":"string","enum":["any","keywords"]},"keywords":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"exclude_keywords":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"once_per_person":{"default":true,"type":"boolean"}},"required":["type"],"additionalProperties":false}},"required":["id","type","config"],"description":"Entry step. Exactly one per graph, referenced by graph.entry. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"message"},"config":{"type":"object","properties":{"message":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"text"},"text":{"type":"string","minLength":1,"maxLength":4000}},"required":["type","text"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"buttons"},"text":{"type":"string","minLength":1,"maxLength":4000},"buttons":{"minItems":1,"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","text","buttons"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"quick_replies"},"text":{"type":"string","minLength":1,"maxLength":4000},"quick_replies":{"minItems":1,"maxItems":13,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["title","payload"],"additionalProperties":false}}},"required":["type","text","quick_replies"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["image","file"]},"media_id":{"type":"string","minLength":1}},"required":["type","media_id"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"card"},"title":{"type":"string","minLength":1,"maxLength":80},"subtitle":{"type":"string","maxLength":80},"media_id":{"type":"string","minLength":1},"buttons":{"default":[],"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","title"],"additionalProperties":false}]},"private_reply":{"default":false,"type":"boolean"}},"required":["message"],"additionalProperties":false}},"required":["id","type","config"],"description":"Sends a DM. private_reply=true sends it as the private reply to the triggering comment (one per comment, within 7 days). Text supports {{username}}, {{comment}} and captured variables. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"public_reply"},"config":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":4000}},"required":["text"],"additionalProperties":false}},"required":["id","type","config"],"description":"Replies publicly to the triggering comment. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"wait_reply"},"config":{"type":"object","properties":{"variable":{"default":"answer","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Waits for the person's next DM and stores it in variable. With timeout_seconds: two edges, branch \"reply\" and \"timeout\". Without: one edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"collect_email"},"config":{"type":"object","properties":{"variable":{"default":"email","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"invalid_text":{"default":"This doesn't look like a valid email. Could you check it?","type":"string","minLength":1,"maxLength":4000},"max_attempts":{"default":2,"type":"integer","minimum":1,"maximum":3},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Asks for an email until valid or max_attempts. Edges: branch \"valid\" and \"invalid\", plus \"timeout\" when timeout_seconds is set."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"collect_phone"},"config":{"type":"object","properties":{"variable":{"default":"phone","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"},"invalid_text":{"default":"Please include the country code, e.g. +5511999999999.","type":"string","minLength":1,"maxLength":4000},"max_attempts":{"default":2,"type":"integer","minimum":1,"maximum":3},"timeout_seconds":{"type":"integer","minimum":60,"maximum":82800}},"additionalProperties":false}},"required":["id","type","config"],"description":"Collects a phone/WhatsApp number with an explicit country code and stores it in the contact phone field. Edges: valid, invalid, and timeout when configured. Does not verify WhatsApp registration."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"tag"},"config":{"type":"object","properties":{"action":{"type":"string","enum":["add","remove"]},"tag":{"type":"string","minLength":1,"maxLength":60}},"required":["action","tag"],"additionalProperties":false}},"required":["id","type","config"],"description":"Adds or removes a contact tag. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"set_field"},"config":{"type":"object","properties":{"field":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},"value":{"type":"string","maxLength":500}},"required":["field","value"],"additionalProperties":false}},"required":["id","type","config"],"description":"Sets a custom contact field. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"sequence"},"config":{"type":"object","properties":{"action":{"type":"string","enum":["subscribe","unsubscribe"]},"sequence_id":{"type":"string","minLength":1,"maxLength":80}},"required":["action","sequence_id"],"additionalProperties":false}},"required":["id","type","config"],"description":"Subscribes or unsubscribes the contact from a sequence (id from list_sequences). Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"check"},"config":{"type":"object","properties":{"rule":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"tag"},"tag":{"type":"string","minLength":1,"maxLength":60}},"required":["type","tag"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"has_email"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"follows"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"last_interaction"},"within_hours":{"type":"integer","minimum":1,"maximum":2160}},"required":["type","within_hours"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"field"},"field":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},"operator":{"type":"string","enum":["equals","contains","exists","not_exists"]},"value":{"type":"string","maxLength":500}},"required":["type","field","operator"],"additionalProperties":false}]}},"required":["rule"],"additionalProperties":false}},"required":["id","type","config"],"description":"Tests a contact rule. Edges: branch \"true\" and \"false\", plus \"unknown\" for the follows rule."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"random"},"config":{"type":"object","properties":{"splits":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9_-]{1,32}$"},"label":{"default":"","type":"string","maxLength":40},"weight":{"type":"integer","minimum":1,"maximum":100}},"required":["id","weight"],"additionalProperties":false}}},"required":["splits"],"additionalProperties":false}},"required":["id","type","config"],"description":"Random A/B split. One edge per split, with branch equal to the split id."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"condition"},"config":{"type":"object","properties":{"variable":{"type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_.]{0,127}$"},"operator":{"type":"string","enum":["equals","contains","exists","not_exists"]},"value":{"type":"string","maxLength":2000}},"required":["variable","operator"],"additionalProperties":false}},"required":["id","type","config"],"description":"Compares a captured variable. Edges: branch \"true\" and \"false\"."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"delay"},"config":{"type":"object","properties":{"seconds":{"type":"integer","minimum":1,"maximum":82800}},"required":["seconds"],"additionalProperties":false}},"required":["id","type","config"],"description":"Waits a fixed time. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"external"},"config":{"type":"object","properties":{"webhook_id":{"type":"string","minLength":1},"wait_for_result":{"default":true,"type":"boolean"},"variable":{"default":"external_result","type":"string","pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,63}$"}},"required":["webhook_id"],"additionalProperties":false}},"required":["id","type","config"],"description":"Calls a registered webhook (id from list_webhooks) and optionally waits for its result. Exactly one outgoing edge without branch."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"handoff"},"config":{"type":"object","properties":{"note":{"default":"","type":"string","maxLength":1000}},"additionalProperties":false}},"required":["id","type","config"],"description":"Hands the conversation to a human. Terminal: no outgoing edges."},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","maxLength":120},"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]},"type":{"type":"string","const":"end"},"config":{"type":"object","properties":{},"additionalProperties":false}},"required":["id","type","config"],"description":"Ends the flow. Terminal: no outgoing edges."}]}},"edges":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"source":{"type":"string"},"target":{"type":"string"},"branch":{"description":"Required on edges leaving condition, check, random, collect_email, collect_phone and wait_reply with a timeout; omitted otherwise.","type":"string","maxLength":256}},"required":["id","source","target"],"additionalProperties":false}}},"required":["schema_version","entry","nodes","edges"],"additionalProperties":false,"description":"Automation flow. graph.entry is the single trigger node; every node must be reachable from it and cycles are not allowed."},"priority":{"default":0,"type":"integer","minimum":-1000,"maximum":1000}},"required":["name","profile_id","graph"],"additionalProperties":false},"EngagementMessage":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"text"},"text":{"type":"string","minLength":1,"maxLength":4000}},"required":["type","text"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"buttons"},"text":{"type":"string","minLength":1,"maxLength":4000},"buttons":{"minItems":1,"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","text","buttons"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"quick_replies"},"text":{"type":"string","minLength":1,"maxLength":4000},"quick_replies":{"minItems":1,"maxItems":13,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["title","payload"],"additionalProperties":false}}},"required":["type","text","quick_replies"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["image","file"]},"media_id":{"type":"string","minLength":1}},"required":["type","media_id"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"card"},"title":{"type":"string","minLength":1,"maxLength":80},"subtitle":{"type":"string","maxLength":80},"media_id":{"type":"string","minLength":1},"buttons":{"default":[],"maxItems":3,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"postback"},"title":{"type":"string","minLength":1,"maxLength":20},"payload":{"type":"string","minLength":1,"maxLength":256}},"required":["type","title","payload"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"web_url"},"title":{"type":"string","minLength":1,"maxLength":20},"url":{"type":"string","format":"uri"}},"required":["type","title","url"],"additionalProperties":false}]}}},"required":["type","title"],"additionalProperties":false}]},"Automation":{"type":"object","required":["id","name","profile_id","mode","status","draft_graph","draft_revision"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"profile_id":{"type":"string"},"mode":{"type":"string","enum":["test","live"]},"priority":{"type":"integer"},"status":{"type":"string","enum":["draft","published","paused","blocked"]},"draft_graph":{"$ref":"#/components/schemas/AutomationGraph"},"draft_revision":{"type":"integer"},"published_version_id":{"type":["string","null"]},"published_graph":{"anyOf":[{"$ref":"#/components/schemas/AutomationGraph"},{"type":"null"}]},"disabled_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"EngagementSendRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"description":"At most 1000 UTF-8 bytes after rendering. Automated disclosure is added if absent."},"message":{"$ref":"#/components/schemas/EngagementMessage"},"human_agent":{"type":"boolean","const":false,"description":"API keys and MCP cannot request the human support extension."}},"oneOf":[{"required":["text"],"not":{"required":["message"],"properties":{"message":{}}},"properties":{"text":{}}},{"required":["message"],"not":{"required":["text"],"properties":{"text":{}}},"properties":{"message":{}}}],"additionalProperties":false},"EngagementAction":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"message_id":{"type":["string","null"]},"status":{"type":"string","enum":["pending","sending","sent","blocked","failed","unknown"]},"reason":{"type":["string","null"]}},"additionalProperties":true},"EngagementCapabilities":{"type":"object","required":["profile_id","ready","mode","limits"],"properties":{"profile_id":{"type":"string"},"ready":{"type":"boolean"},"mode":{"type":"string","enum":["test","live"]},"reason":{"type":["string","null"]},"missing_scopes":{"type":"array","items":{"type":"string"}},"webhook_status":{"type":"string"},"webhook_error":{"type":["string","null"],"description":"Provider diagnostic from the last failed account subscription attempt."},"human_agent_approved":{"type":"boolean"},"limits":{"type":"object","additionalProperties":true}},"additionalProperties":true},"AutomationRun":{"type":"object","required":["id","automation_id","status","current_node_id"],"properties":{"id":{"type":"string"},"automation_id":{"type":"string"},"version_id":{"type":"string"},"conversation_id":{"type":["string","null"]},"current_node_id":{"type":"string"},"status":{"type":"string","enum":["running","waiting_reply","waiting_delay","waiting_external","waiting_action","completed","blocked","failed","handed_off","canceled"]},"reason":{"type":["string","null"]},"step":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"AutomationSummary":{"type":"object","required":["id","name","profile_id","mode","status","draft_revision"],"properties":{"draft_graph":{"$ref":"#/components/schemas/AutomationGraph"},"id":{"type":"string"},"name":{"type":"string"},"profile_id":{"type":"string"},"mode":{"type":"string","enum":["test","live"]},"priority":{"type":"integer"},"status":{"type":"string","enum":["draft","published","paused","blocked"]},"draft_revision":{"type":"integer"},"published_version_id":{"type":["string","null"]},"published_graph":{"anyOf":[{"$ref":"#/components/schemas/AutomationGraph"},{"type":"null"}]},"disabled_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}}}