{"openapi":"3.1.0","info":{"title":"PostWing Agent API","version":"1.1.0","description":"Schedule, preview, edit, and cancel social posts; connect/disconnect accounts; manage workspaces. All data is scoped to the authenticated user and active workspace. Schedule/edit writes require a confirmation_token from the matching preview endpoint (5 minute TTL). Use targets[] with platform_options for per-account captions and platform settings (X quote posts, Pinterest boards, YouTube titles, Instagram Reels, TikTok privacy, etc.). Human docs: https://postwing.io/docs","contact":{"url":"https://postwing.io/docs"}},"servers":[{"url":"https://postwing.io/api/v1","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":["accounts:read","accounts:write","posts:read","posts:write","workspaces:read","workspaces:write"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"PostWing API key (`pw_live_…`) created in Dashboard → AI & API."},"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://postwing.io/oauth/authorize","tokenUrl":"https://postwing.io/oauth/token","refreshUrl":"https://postwing.io/oauth/token","scopes":{"accounts:read":"Access scope accounts:read","accounts:write":"Access scope accounts:write","posts:read":"Access scope posts:read","posts:write":"Access scope posts:write","workspaces:read":"Access scope workspaces:read","workspaces:write":"Access scope workspaces:write"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"MediaItem":{"type":"object","required":["url","type"],"properties":{"url":{"type":"string","format":"uri"},"type":{"type":"string","enum":["image","video"]}}},"PlatformOptions":{"type":"object","description":"Platform-specific settings for this target account. Keys depend on the account platform. X quote posts: set quote_tweet_url. Pinterest: set board_ids from GET /accounts/pinterest-boards. See https://postwing.io/docs#platform-options","additionalProperties":true,"properties":{"quote_tweet_url":{"type":"string","description":"X only. Tweet URL or ID to publish as a native quote post.","examples":["https://x.com/user/status/1234567890"]},"reply_settings":{"type":"string","nullable":true,"enum":[null,"following","mentionedUsers","subscribers","verified"],"description":"X only. Who can reply (null = everyone)."},"placement":{"type":"string","enum":["timeline","reels"],"description":"Facebook / Instagram. Where the post appears."},"share_to_feed":{"type":"boolean","description":"Instagram Reels: also share to the main feed."},"trial_reel_type":{"type":"string","nullable":true,"enum":[null,"manual","performance"],"description":"Instagram Reels trial mode."},"title":{"type":"string","description":"YouTube (required), Pinterest pin title, or TikTok image title."},"made_for_kids":{"type":"boolean","description":"YouTube only."},"privacy_status":{"type":"string","enum":["public","private"],"description":"TikTok only."},"allow_comment":{"type":"boolean","description":"TikTok only."},"allow_duet":{"type":"boolean","description":"TikTok only."},"allow_stitch":{"type":"boolean","description":"TikTok only."},"is_ai_generated":{"type":"boolean","description":"TikTok only."},"is_draft":{"type":"boolean","description":"TikTok only. Save as app draft."},"board_ids":{"type":"array","items":{"type":"string"},"description":"Pinterest only. Required board IDs."},"link":{"type":"string","format":"uri","description":"Pinterest destination URL."},"caption":{"type":"string","description":"Optional caption stored inside platform_options (prefer targets[].caption)."}}},"ScheduleTarget":{"type":"object","required":["account_id"],"description":"Per-account schedule target. Use instead of account_ids/platforms when you need per-account captions or platform_options (e.g. X quote posts, Pinterest boards).","properties":{"account_id":{"type":"string","format":"uuid","description":"PostWing social account UUID"},"caption":{"type":"string","description":"Optional per-account caption override"},"platform_options":{"$ref":"#/components/schemas/PlatformOptions"}}},"PreviewScheduleBody":{"type":"object","required":["caption","scheduled_at"],"properties":{"caption":{"type":"string","minLength":1},"scheduled_at":{"type":"string","format":"date-time"},"account_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"platforms":{"type":"array","items":{"type":"string","enum":["instagram","tiktok","youtube","linkedin","x","facebook","pinterest","threads"]}},"targets":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleTarget"},"description":"Preferred for per-account captions or platform_options (quote posts, boards, etc.)"},"post_type":{"type":"string","enum":["text","image","video"]},"media_items":{"type":"array","items":{"$ref":"#/components/schemas/MediaItem"}},"media_urls":{"type":"array","items":{"type":"string","format":"uri"}}},"examples":[{"caption":"Adding my take","scheduled_at":"2026-09-21T15:00:00Z","targets":[{"account_id":"00000000-0000-0000-0000-000000000001","platform_options":{"quote_tweet_url":"https://x.com/someone/status/1234567890"}}]}]},"PreviewEditBody":{"type":"object","required":["post_ids"],"properties":{"post_ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":20},"caption":{"type":"string"},"scheduled_at":{"type":"string","format":"date-time"},"shift_minutes":{"type":"integer"},"account_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"platforms":{"type":"array","items":{"type":"string"}},"targets":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleTarget"},"description":"Replace targets (captions / platform_options)"},"target_options":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleTarget"},"description":"Update captions/platform_options for accounts already on the post without replacing the whole target list"},"media_items":{"type":"array","items":{"$ref":"#/components/schemas/MediaItem"}},"media_urls":{"type":"array","items":{"type":"string","format":"uri"}},"remove_media":{"type":"boolean"}}}}},"paths":{"/accounts":{"get":{"operationId":"listAccounts","summary":"List connected social accounts","security":[{"bearerAuth":[]},{"oauth2":["accounts:read"]}],"responses":{"200":{"description":"Accounts for the authenticated user"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}},"post":{"operationId":"connectAccount","summary":"Start OAuth connect for a platform (returns browser URL)","security":[{"bearerAuth":[]},{"oauth2":["accounts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["platform"],"properties":{"platform":{"type":"string","description":"facebook, instagram, linkedin, pinterest, threads, tiktok, x, youtube"}}}}}},"responses":{"200":{"description":"Connect URL"},"400":{"description":"Invalid platform"},"403":{"description":"Limit or subscription"}}},"delete":{"operationId":"disconnectAccount","summary":"Disconnect an account (confirm: true required)","security":[{"bearerAuth":[]},{"oauth2":["accounts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["account_id","confirm"],"properties":{"account_id":{"type":"string","format":"uuid"},"confirm":{"type":"boolean","enum":[true]}}}}}},"responses":{"200":{"description":"Disconnected"},"400":{"description":"Missing confirm"},"404":{"description":"Not found"}}}},"/accounts/sync":{"post":{"operationId":"syncAccounts","summary":"Sync accounts after the user completes OAuth","security":[{"bearerAuth":[]},{"oauth2":["accounts:write"]}],"responses":{"200":{"description":"Synced accounts"}}}},"/accounts/pinterest-boards":{"get":{"operationId":"listPinterestBoards","summary":"List Pinterest boards for an account","security":[{"bearerAuth":[]},{"oauth2":["accounts:read"]}],"parameters":[{"name":"account_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Boards"},"404":{"description":"Pinterest account not found"}}}},"/workspaces":{"get":{"operationId":"listWorkspaces","summary":"List workspaces","security":[{"bearerAuth":[]},{"oauth2":["workspaces:read"]}],"responses":{"200":{"description":"Workspaces"}}},"post":{"operationId":"createWorkspace","summary":"Create a workspace (Scale plan)","security":[{"bearerAuth":[]},{"oauth2":["workspaces:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Created"},"403":{"description":"Plan does not support workspaces"}}}},"/workspaces/active":{"post":{"operationId":"switchWorkspace","summary":"Set the active workspace","security":[{"bearerAuth":[]},{"oauth2":["workspaces:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workspace_id"],"properties":{"workspace_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Active workspace updated"}}}},"/posts":{"get":{"operationId":"listPosts","summary":"List scheduled posts (paginated)","security":[{"bearerAuth":[]},{"oauth2":["posts:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0}},{"name":"fields","in":"query","schema":{"type":"string","enum":["full","summary"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["scheduled","publishing","published","partially_failed","failed","paused"]}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"include_past","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Paginated posts for the authenticated user"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/schedule/summary":{"get":{"operationId":"getScheduleSummary","summary":"Schedule counts and patterns","security":[{"bearerAuth":[]},{"oauth2":["posts:read"]}],"responses":{"200":{"description":"Summary for the authenticated user"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/media":{"post":{"operationId":"importMedia","summary":"Import media from public HTTPS URLs","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["urls"],"properties":{"urls":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":10}}}}}},"responses":{"200":{"description":"Imported media_items"},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/posts/preview":{"post":{"operationId":"previewSchedulePost","summary":"Preview a post and get a confirmation_token (5 min)","description":"Supports account_ids, platforms, or targets with platform_options. For an X quote post, pass targets[{account_id, platform_options:{quote_tweet_url}}].","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewScheduleBody"},"examples":{"quoteTweet":{"summary":"X native quote post","value":{"caption":"Adding my take","scheduled_at":"2026-09-21T15:00:00Z","targets":[{"account_id":"00000000-0000-0000-0000-000000000001","platform_options":{"quote_tweet_url":"https://x.com/someone/status/1234567890"}}]}}}}}},"responses":{"200":{"description":"Preview + confirmation_token"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/posts/confirm":{"post":{"operationId":"confirmSchedulePost","summary":"Schedule a post using confirmation_token from preview","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirmation_token"],"properties":{"confirmation_token":{"type":"string"}}}}}},"responses":{"200":{"description":"Post scheduled"},"400":{"description":"Invalid or expired token"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/posts/edit/preview":{"post":{"operationId":"previewEditPosts","summary":"Preview edits and get a confirmation_token (5 min)","description":"Only send fields being changed. Use targets or target_options to update platform_options (e.g. quote_tweet_url).","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewEditBody"}}}},"responses":{"200":{"description":"Edit preview + confirmation_token"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/posts/edit/confirm":{"post":{"operationId":"confirmEditPosts","summary":"Apply edits using confirmation_token from edit preview","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirmation_token"],"properties":{"confirmation_token":{"type":"string"}}}}}},"responses":{"200":{"description":"Posts updated"},"400":{"description":"Invalid or expired token"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"}}}},"/posts/{id}":{"get":{"operationId":"getPost","summary":"Get one post with media and platform_options","security":[{"bearerAuth":[]},{"oauth2":["posts:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Post detail"},"404":{"description":"Not found for this user"}}},"delete":{"operationId":"cancelPost","summary":"Cancel a scheduled or paused post (requires confirm: true)","security":[{"bearerAuth":[]},{"oauth2":["posts:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirm"],"properties":{"confirm":{"type":"boolean","enum":[true]}}}}}},"responses":{"200":{"description":"Post cancelled"},"400":{"description":"Missing confirm or invalid state"},"401":{"description":"Unauthorized"},"403":{"description":"Missing scope or subscription"},"404":{"description":"Not found for this user"}}}}},"x-postwing-oauth-resource":{"resource":"https://postwing.io/api/v1","authorization_servers":["https://postwing.io"],"scopes_supported":["accounts:read","accounts:write","posts:read","posts:write","workspaces:read","workspaces:write"],"bearer_methods_supported":["header"],"resource_name":"PostWing API","resource_documentation":"https://postwing.io/docs"},"x-postwing-platform-options":[{"platform":"x","label":"X (Twitter)","fields":[{"key":"quote_tweet_url","type":"string","description":"Tweet URL or status ID to quote. Creates a native X quote post. Example: https://x.com/user/status/123"},{"key":"reply_settings","type":"string | null","description":"Who can reply: null (everyone), following, mentionedUsers, subscribers, verified"}]},{"platform":"instagram","label":"Instagram","fields":[{"key":"placement","type":"string","description":"Set automatically: reels for video, timeline for image/text"},{"key":"share_to_feed","type":"boolean","description":"Video/Reels only. If true, also share the Reel to the main feed (default true)"},{"key":"trial_reel_type","type":"string | null","description":"Video only. null, manual, or performance (trial reels; 1000+ followers)"}]},{"platform":"facebook","label":"Facebook","fields":[{"key":"placement","type":"string","description":"timeline or reels (video defaults to reels)"}]},{"platform":"youtube","label":"YouTube","fields":[{"key":"title","type":"string","description":"Required for YouTube. Shorts/long-form title"},{"key":"made_for_kids","type":"boolean","description":"Whether the video is made for kids (default false)"}]},{"platform":"tiktok","label":"TikTok","fields":[{"key":"title","type":"string","description":"Image posts only (not used for video)"},{"key":"privacy_status","type":"string","description":"public or private (default public)"},{"key":"allow_comment","type":"boolean","description":"Allow comments (default true)"},{"key":"allow_duet","type":"boolean","description":"Allow duets (default true)"},{"key":"allow_stitch","type":"boolean","description":"Allow stitch (default true)"},{"key":"is_ai_generated","type":"boolean","description":"Mark as AI-generated content (default false)"},{"key":"is_draft","type":"boolean","description":"Save as draft in the TikTok app (default false)"}]},{"platform":"pinterest","label":"Pinterest","fields":[{"key":"board_ids","type":"string[]","description":"Required. Board IDs from GET /accounts/pinterest-boards or list_pinterest_boards"},{"key":"title","type":"string","description":"Pin title"},{"key":"link","type":"string","description":"Destination URL for the pin"}]},{"platform":"linkedin","label":"LinkedIn","fields":[{"key":"(none)","type":"n/a","description":"Caption only; no extra platform options"}]},{"platform":"threads","label":"Threads","fields":[{"key":"(none)","type":"n/a","description":"Caption only; no extra platform options"}]}]}