{"openapi":"3.0.0","info":{"title":"PostPeer API","description":"Cross-platform social media posting API","version":"1.0.0"},"components":{"securitySchemes":{"accessKey":{"type":"apiKey","in":"header","name":"x-access-key"}},"schemas":{"Platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"Status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"SortOrder":{"type":"string","enum":["asc","desc"]},"ErrorResponse":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}},"PostPayload":{"additionalProperties":false,"type":"object","required":["content","platforms"],"properties":{"content":{"description":"Post text body","type":"string"},"mediaItems":{"description":"Media attachments (images, videos, GIFs)","type":"array","items":{"additionalProperties":false,"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"format":"uri","type":"string"},"thumbnail":{"format":"uri","description":"Thumbnail image URL for video items. Supported on YouTube regular videos (not Shorts). JPEG, PNG, or GIF, max 2 MB, min 640 px wide.","type":"string"}}}},"platforms":{"minItems":1,"description":"Target platform accounts to publish to","type":"array","items":{"additionalProperties":false,"type":"object","required":["platform","accountId"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"accountId":{"description":"Integration._id — find yours via GET /connect/integrations","type":"string"},"content":{"description":"Optional per-platform text override. Use when you want to change the text for this platform because different platforms talk differently. When omitted, the top-level `content` is used.","type":"string"},"platformSpecificData":{"type":"object","additionalProperties":true,"description":"Platform-specific options. See TwitterConfigurations, YouTubeConfigurations, TikTokConfigurations, PinterestConfigurations, or LinkedInConfigurations in the schema reference for available fields per platform."}}}},"publishNow":{"description":"Publish immediately. Required when scheduledFor is omitted.","type":"boolean"},"scheduledFor":{"format":"date-time","description":"ISO 8601 datetime to schedule the post for future publishing","type":"string"},"timezone":{"description":"IANA timezone for the scheduled time (e.g. America/New_York). Defaults to UTC.","type":"string"}}},"TwitterConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Twitter/X, including Community post options.","type":"object","properties":{"communityId":{"description":"Community ID to publish this post into.","type":"string"},"shareWithFollowers":{"description":"When posting to a Community, also share the post with followers.","type":"boolean"},"replyToTweetId":{"description":"Tweet ID to reply to.","type":"string"},"replySettings":{"type":"string","enum":["following","mentionedUsers","subscribers","verified"]},"threadItems":{"description":"Additional tweets to chain as a thread. The root tweet uses post.content.","type":"array","items":{"additionalProperties":false,"type":"object","required":["content"],"properties":{"content":{"description":"Text of this thread tweet (max 280 chars)","type":"string"},"mediaItems":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"format":"uri","type":"string"},"thumbnail":{"format":"uri","description":"Thumbnail image URL for video items. Supported on YouTube regular videos (not Shorts). JPEG, PNG, or GIF, max 2 MB, min 640 px wide.","type":"string"}}}}}}},"poll":{"additionalProperties":false,"description":"Cannot be combined with media or threadItems.","type":"object","required":["options","durationMinutes"],"properties":{"options":{"minItems":2,"maxItems":4,"description":"2–4 poll options.","type":"array","items":{"type":"string"}},"durationMinutes":{"minimum":5,"maximum":10080,"description":"Poll duration in minutes (5 min – 7 days).","type":"number"}}}}},"YouTubeConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to YouTube.","type":"object","properties":{"title":{"maxLength":100,"description":"Video title (max 100 chars, no < or >). Defaults to first 100 chars of content, or \"Untitled Video\".","type":"string"},"tags":{"description":"Video tags. Total characters across all tags must be ≤500.","type":"array","items":{"type":"string"}},"visibility":{"type":"string","enum":["public","private","unlisted"],"description":"Who can see the video. Defaults to \"public\". Scheduled posts upload as private and flip to this value at publish time."},"madeForKids":{"description":"COPPA compliance flag. Setting to true permanently disables comments, notification bell, personalized ads, end screens, and cards on the video. Defaults to false.","type":"boolean"},"containsSyntheticMedia":{"description":"AI-generated content disclosure. YouTube is increasingly enforcing this requirement. Defaults to false.","type":"boolean"},"categoryId":{"description":"YouTube category ID. Defaults to \"22\" (People & Blogs). Common values: \"1\" Film & Animation, \"10\" Music, \"20\" Gaming, \"22\" People & Blogs, \"27\" Education, \"28\" Science & Technology.","type":"string"},"firstComment":{"maxLength":10000,"description":"Auto-posted comment after the video goes live. Max 10,000 characters. For publishNow posts: posted immediately after upload. For scheduled posts: posted when the video becomes public.","type":"string"}}},"TikTokConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to TikTok.","type":"object","properties":{"privacyLevel":{"type":"string","enum":["PUBLIC_TO_EVERYONE","MUTUAL_FOLLOW_FRIENDS","FOLLOWER_OF_CREATOR","SELF_ONLY"],"description":"Who can see this post. Defaults to \"PUBLIC_TO_EVERYONE\"."},"disableComment":{"description":"Disable comments on this post. Defaults to false.","type":"boolean"},"disableDuet":{"description":"Disable duet for this video. Videos only. Defaults to false.","type":"boolean"},"disableStitch":{"description":"Disable stitch for this video. Videos only. Defaults to false.","type":"boolean"},"brandContentToggle":{"description":"Mark as branded content (paid partnership). Defaults to false.","type":"boolean"},"brandOrganicToggle":{"description":"Mark as organic brand promotion. Defaults to false.","type":"boolean"},"isAigc":{"description":"AI-generated content disclosure. Videos only. Defaults to false.","type":"boolean"},"videoCoverTimestampMs":{"description":"Timestamp in milliseconds to use as the video cover frame. Videos only. Defaults to 1000ms.","type":"number"},"autoAddMusic":{"description":"Automatically add background music to photo carousels. Photo posts only. Defaults to true.","type":"boolean"},"photoCoverIndex":{"minimum":0,"description":"0-indexed position of the cover image in a photo carousel. Photo posts only. Defaults to 0.","type":"number"},"draft":{"description":"When true, sends content to the creator's TikTok inbox as a draft. Defaults to false (publishes immediately via DIRECT_POST).","type":"boolean"}}},"PinterestConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Pinterest.","type":"object","required":["boardId"],"properties":{"boardId":{"description":"Target board ID. Retrieve available boards via GET /v1/pinterest/boards.","type":"string"},"title":{"maxLength":100,"description":"Pin title. Max 100 characters. Defaults to first line of content.","type":"string"},"link":{"format":"uri","description":"HTTPS destination URL when the pin is clicked. Important for driving traffic.","type":"string"},"altText":{"maxLength":500,"description":"Accessible image description. Max 500 characters.","type":"string"},"dominantColor":{"description":"Hex color for the loading placeholder (e.g. \"#6E7874\").","type":"string"},"coverImageUrl":{"format":"uri","description":"Custom cover image URL for video pins.","type":"string"}}},"LinkedInConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to LinkedIn.","type":"object","properties":{"visibility":{"type":"string","enum":["PUBLIC","CONNECTIONS"],"description":"Post visibility. \"PUBLIC\" = visible to everyone, \"CONNECTIONS\" = visible to connections only. Defaults to \"PUBLIC\"."},"articleUrl":{"format":"uri","description":"URL for an article/link post. When provided, the post becomes a link share with a preview card.","type":"string"},"articleTitle":{"maxLength":400,"description":"Title for the article preview card. Max 400 characters.","type":"string"},"articleDescription":{"maxLength":400,"description":"Description for the article preview card. Max 400 characters.","type":"string"}}},"BlueskyConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Bluesky.","type":"object","properties":{"langs":{"description":"BCP-47 language tags for the post (e.g. [\"en\"], [\"en-US\", \"es\"]). Defaults to [\"en\"].","type":"array","items":{"type":"string"}},"altText":{"description":"Alt text for each image, in the same order as mediaItems. Strongly encouraged for accessibility.","type":"array","items":{"type":"string"}}}},"FacebookConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Facebook Pages.","type":"object","properties":{"link":{"format":"uri","description":"When provided on a text-only post, Facebook renders a link preview card from this URL's Open Graph tags. Ignored when mediaItems are attached.","type":"string"},"published":{"description":"When false, the post is created on the Page in unpublished/draft state — useful for staging or scheduling via Facebook's own composer. Defaults to true.","type":"boolean"},"videoThumbnailUrl":{"format":"uri","description":"Video posts only. Public URL of an image Facebook will use as the video's cover/thumbnail. Applied as a follow-up call after publish — if the upload fails, the post still succeeds (Facebook just auto-picks a frame). Ignored when no video is attached.","type":"string"}}},"InstagramConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Instagram Business accounts. All fields are optional and apply to Reels/video posts; image posts ignore them.","type":"object","properties":{"shareToFeed":{"description":"Reels-only. When true (default), the Reel also appears in the account's main feed grid. Set false to publish to Reels only.","type":"boolean"},"coverUrl":{"format":"uri","description":"Video-only. Public URL of an image Instagram will use as the cover frame for the Reel/video post. Ignored for image posts.","type":"string"},"thumbOffset":{"minimum":0,"description":"Video-only. Timestamp in milliseconds Instagram extracts as the cover frame. Ignored when coverUrl is set or for image posts.","type":"integer"}}},"ThreadsConfigurations":{"additionalProperties":false,"description":"Pass this object in platformSpecificData when posting to Threads.","type":"object","properties":{"replyControl":{"type":"string","enum":["everyone","accounts_you_follow","mentioned_only"],"description":"Who can reply to this thread. Defaults to \"everyone\" when omitted."},"altText":{"description":"Alt text for each image, in the same order as mediaItems. Strongly encouraged for accessibility.","type":"array","items":{"type":"string"}}}}}},"paths":{"/v1/health":{"get":{"operationId":"healthCheck","summary":"Health check","tags":["Health"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/health/auth":{"get":{"operationId":"healthCheckAuth","summary":"Verify that the provided access key is valid","tags":["Health"],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/connect/{platform}":{"get":{"operationId":"getOAuthUrl","summary":"Get OAuth URL for a platform","tags":["Connect"],"parameters":[{"schema":{"format":"uri","type":"string"},"in":"query","name":"redirectUri","required":false,"description":"URL to redirect to after a successful connection"},{"schema":{"type":"string"},"in":"query","name":"profileId","required":false,"description":"Profile to associate the resulting integration with. Must belong to the same project. Omit to connect without a profile."},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Connect under your own OAuth app (Bring Your Own Keys). Pass the id of an OAuth app created via /v1/apps for this same platform. Omit to use postpeer's system app."},{"schema":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"in":"path","name":"platform","required":true}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/connect/bluesky/auth":{"post":{"operationId":"connectBluesky","summary":"Connect a Bluesky account via app password","tags":["Connect"],"description":"Bluesky has no OAuth redirect. Have the user generate an app password at https://bsky.app/settings/app-passwords, then submit it here.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["identifier","password"],"properties":{"identifier":{"description":"Bluesky handle (e.g. \"alice.bsky.social\") or DID (e.g. \"did:plc:abc123\").","type":"string"},"password":{"description":"An app password generated at https://bsky.app/settings/app-passwords. Do NOT use the account password.","type":"string"}}}}}},"parameters":[{"schema":{"format":"uri","type":"string"},"in":"query","name":"redirectUri","required":false,"description":"URL to redirect to after a successful connection"},{"schema":{"type":"string"},"in":"query","name":"profileId","required":false,"description":"Profile to associate the resulting integration with. Must belong to the same project. Omit to connect without a profile."},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Connect under your own OAuth app (Bring Your Own Keys). Pass the id of an OAuth app created via /v1/apps for this same platform. Omit to use postpeer's system app."}],"security":[{"accessKey":[]}],"responses":{"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"502":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/connect/integrations":{"get":{"operationId":"listIntegrations","summary":"List integrations connected to this project","tags":["Connect"],"parameters":[{"schema":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"in":"query","name":"platform","required":false},{"schema":{"type":"string"},"in":"query","name":"profileId","required":false,"description":"Filter to integrations belonging to this profile. Pass \"null\" (literal string) to filter to integrations with no profile."},{"schema":{"type":"string"},"in":"query","name":"q","required":false,"description":"Case-insensitive search across the connected account name (displayName), username, and platform user ID."},{"schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"},"in":"query","name":"limit","required":false,"description":"Page size (max 100)"},{"schema":{"minimum":0,"default":0,"type":"integer"},"in":"query","name":"offset","required":false,"description":"Number of integrations to skip"},{"schema":{"$ref":"#/components/schemas/SortOrder"},"in":"query","name":"sort","required":false}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","total","integrations"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"description":"Total matched integrations across all pages","type":"integer"},"integrations":{"type":"array","items":{"type":"object","required":["id","platform","platformUserId","username","displayName","profileUrl","imageUrl","profileId","appId","app","byok","createdAt"],"properties":{"id":{"description":"Use this as accountId when creating posts","type":"string"},"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"platformUserId":{"type":"string","nullable":true,"description":"The user ID on the platform, or null if not yet retrieved"},"username":{"type":"string","nullable":true,"description":"The public username or handle, including @ for handle-based platforms"},"displayName":{"type":"string","nullable":true,"description":"Human-readable display name of the connected account"},"profileUrl":{"type":"string","format":"uri","nullable":true,"description":"Public profile/page URL for the connected account, when it can be derived"},"imageUrl":{"type":"string","format":"uri","nullable":true,"description":"Profile image URL for the connected account, or null if unavailable"},"platformMetadata":{"type":"object","additionalProperties":true,"description":"Provider-specific public metadata for this connected account."},"profileId":{"type":"string","nullable":true,"description":"Profile this integration belongs to, or null if it was connected without a profile"},"appId":{"type":"string","nullable":true,"description":"The OAuth app (customer's own OAuth app) this integration was connected under, or null if postpeer's system app was used."},"app":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"imageUrl":{"type":"string","nullable":true}},"description":"The OAuth app metadata for BYOK integrations, or null when postpeer system app was used."},"byok":{"description":"True when this integration was connected under the customer's own OAuth app (Bring Your Own Keys), i.e. appId is set. False when postpeer's system app is used.","type":"boolean"},"createdAt":{"format":"date-time","type":"string"}}}}}}}}}}}},"/v1/connect/integrations/{id}":{"delete":{"operationId":"disconnectIntegration","summary":"Disconnect a platform integration","tags":["Connect"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Integration ID to disconnect"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/profiles/":{"post":{"operationId":"createProfile","summary":"Create a profile","tags":["Profiles"],"description":"Profiles group integrations under a label. Pass the returned `id` as `profileId` when calling /v1/connect/:platform to bind the resulting integration to this profile.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"minLength":1,"maxLength":200,"description":"Profile name (e.g. \"Acme Co\", \"Personal Brand\")","type":"string"},"description":{"maxLength":1000,"description":"Optional description of what this profile is for","type":"string"}}}}}},"security":[{"accessKey":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","profile"],"properties":{"success":{"type":"boolean"},"profile":{"type":"object","required":["id","name","description","integrationCount","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"integrationCount":{"minimum":0,"description":"Number of active integrations bound to this profile","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}}}},"get":{"operationId":"listProfiles","summary":"List profiles for this project","tags":["Profiles"],"parameters":[{"schema":{"minimum":1,"default":1,"type":"integer"},"in":"query","name":"page","required":false},{"schema":{"minimum":1,"maximum":100,"default":50,"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"minLength":1,"maxLength":200,"type":"string"},"in":"query","name":"name","required":false,"description":"Case-insensitive substring match on profile name"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","total","page","limit","profiles"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"type":"integer"},"page":{"minimum":1,"type":"integer"},"limit":{"minimum":1,"type":"integer"},"profiles":{"type":"array","items":{"type":"object","required":["id","name","description","integrationCount","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"integrationCount":{"minimum":0,"description":"Number of active integrations bound to this profile","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}}}}}},"/v1/profiles/{id}":{"get":{"operationId":"getProfile","summary":"Get a single profile","tags":["Profiles"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Profile ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","profile"],"properties":{"success":{"type":"boolean"},"profile":{"type":"object","required":["id","name","description","integrationCount","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"integrationCount":{"minimum":0,"description":"Number of active integrations bound to this profile","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}},"patch":{"operationId":"updateProfile","summary":"Update a profile","tags":["Profiles"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"minLength":1,"maxLength":200,"type":"string"},"description":{"type":"string","nullable":true,"maxLength":1000}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Profile ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","profile"],"properties":{"success":{"type":"boolean"},"profile":{"type":"object","required":["id","name","description","integrationCount","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"integrationCount":{"minimum":0,"description":"Number of active integrations bound to this profile","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}},"delete":{"operationId":"deleteProfile","summary":"Delete a profile","tags":["Profiles"],"description":"Soft-deletes the profile. Existing integrations bound to it keep their profileId — they are not orphaned, but listing /v1/profiles will no longer surface this row.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Profile ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/apps/":{"post":{"operationId":"createApp","summary":"Register your own OAuth app (Bring Your Own Keys)","tags":["Apps (BYOK)"],"description":"Store the client credentials of your own OAuth app for a platform. Pass the returned `id` as `appId` when calling /v1/connect/:platform to connect accounts under it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["platform","name","clientId","clientSecret"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"name":{"minLength":1,"maxLength":200,"description":"A label for this app (e.g. \"Acme Twitter OAuth App\")","type":"string"},"clientId":{"minLength":1,"description":"The client id of your OAuth app for this platform","type":"string"},"clientSecret":{"minLength":1,"description":"The client secret of your OAuth app. Stored encrypted.","type":"string"},"imageUrl":{"format":"uri","description":"Optional icon URL for the app","type":"string"}}}}}},"security":[{"accessKey":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","app"],"properties":{"success":{"type":"boolean"},"app":{"type":"object","required":["id","platform","name","imageUrl","clientId","integrationCount","createdAt","updatedAt"],"properties":{"id":{"description":"Pass this as appId when connecting","type":"string"},"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"name":{"type":"string"},"imageUrl":{"type":"string","nullable":true},"clientId":{"description":"The OAuth app client id. The client secret is never returned.","type":"string"},"integrationCount":{"minimum":0,"description":"Number of active integrations connected under this app","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}},"get":{"operationId":"listApps","summary":"List registered OAuth apps for this project","tags":["Apps (BYOK)"],"parameters":[{"schema":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"in":"query","name":"platform","required":false},{"schema":{"minimum":1,"default":1,"type":"integer"},"in":"query","name":"page","required":false},{"schema":{"minimum":1,"maximum":100,"default":50,"type":"integer"},"in":"query","name":"limit","required":false},{"schema":{"minLength":1,"maxLength":200,"type":"string"},"in":"query","name":"name","required":false,"description":"Case-insensitive substring match on app name"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","total","page","limit","apps"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"type":"integer"},"page":{"minimum":1,"type":"integer"},"limit":{"minimum":1,"type":"integer"},"apps":{"type":"array","items":{"type":"object","required":["id","platform","name","imageUrl","clientId","integrationCount","createdAt","updatedAt"],"properties":{"id":{"description":"Pass this as appId when connecting","type":"string"},"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"name":{"type":"string"},"imageUrl":{"type":"string","nullable":true},"clientId":{"description":"The OAuth app client id. The client secret is never returned.","type":"string"},"integrationCount":{"minimum":0,"description":"Number of active integrations connected under this app","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}}}}}},"/v1/apps/{id}":{"get":{"operationId":"getApp","summary":"Get a single OAuth app","tags":["Apps (BYOK)"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"OAuth app ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","app"],"properties":{"success":{"type":"boolean"},"app":{"type":"object","required":["id","platform","name","imageUrl","clientId","integrationCount","createdAt","updatedAt"],"properties":{"id":{"description":"Pass this as appId when connecting","type":"string"},"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"name":{"type":"string"},"imageUrl":{"type":"string","nullable":true},"clientId":{"description":"The OAuth app client id. The client secret is never returned.","type":"string"},"integrationCount":{"minimum":0,"description":"Number of active integrations connected under this app","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}},"patch":{"operationId":"updateApp","summary":"Update an OAuth app","tags":["Apps (BYOK)"],"description":"Change the name, image, or rotate the client secret. The clientId and platform are immutable: a refresh token is bound to the clientId that issued it, so changing the app would brick existing integrations — create a new OAuth app and reconnect instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","properties":{"name":{"minLength":1,"maxLength":200,"type":"string"},"imageUrl":{"type":"string","nullable":true},"clientSecret":{"minLength":1,"description":"Rotate the stored client secret. The clientId stays the same so existing tokens keep working — to switch to a different app, create a new OAuth app and reconnect.","type":"string"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"OAuth app ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","app"],"properties":{"success":{"type":"boolean"},"app":{"type":"object","required":["id","platform","name","imageUrl","clientId","integrationCount","createdAt","updatedAt"],"properties":{"id":{"description":"Pass this as appId when connecting","type":"string"},"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"name":{"type":"string"},"imageUrl":{"type":"string","nullable":true},"clientId":{"description":"The OAuth app client id. The client secret is never returned.","type":"string"},"integrationCount":{"minimum":0,"description":"Number of active integrations connected under this app","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}},"delete":{"operationId":"deleteApp","summary":"Delete an OAuth app","tags":["Apps (BYOK)"],"description":"Deletes the app. Blocked with 409 while active integrations are still connected under it — those integrations rely on the app for token refresh. Disconnect or reconnect them first.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"OAuth app ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/notifications/test":{"post":{"operationId":"testNotification","summary":"Test a notification destination before saving it","tags":["Notifications"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["channel"],"properties":{"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"webhook":{"additionalProperties":false,"type":"object","required":["url"],"properties":{"url":{"format":"uri","description":"HTTPS endpoint that receives PostPeer JSON payloads","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}}}}}}},"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/notifications/":{"post":{"operationId":"createNotification","summary":"Create a notification subscription","tags":["Notifications"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["channel","eventTypes"],"properties":{"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"eventTypes":{"minItems":1,"uniqueItems":true,"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"default":false,"description":"When true, deliver matching notifications only for posts that were scheduled.","type":"boolean"},"enabled":{"default":true,"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url"],"properties":{"url":{"format":"uri","description":"HTTPS endpoint that receives PostPeer JSON payloads","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}}}}}}},"security":[{"accessKey":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","notification"],"properties":{"success":{"type":"boolean"},"notification":{"additionalProperties":false,"type":"object","required":["id","channel","profileId","eventTypes","onlyScheduledPosts","enabled","lastTestAt","lastTestStatus","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"type":"boolean"},"enabled":{"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url","secret"],"properties":{"url":{"format":"uri","type":"string"},"secret":{"description":"Masked webhook signing secret","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}},"lastTestAt":{"type":"string","nullable":true,"format":"date-time"},"lastTestStatus":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"get":{"operationId":"listNotifications","summary":"List notification subscriptions","tags":["Notifications"],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","notifications"],"properties":{"success":{"type":"boolean"},"notifications":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","channel","profileId","eventTypes","onlyScheduledPosts","enabled","lastTestAt","lastTestStatus","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"type":"boolean"},"enabled":{"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url","secret"],"properties":{"url":{"format":"uri","type":"string"},"secret":{"description":"Masked webhook signing secret","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}},"lastTestAt":{"type":"string","nullable":true,"format":"date-time"},"lastTestStatus":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}}}}}},"/v1/notifications/{id}":{"get":{"operationId":"getNotification","summary":"Get a notification subscription","tags":["Notifications"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Notification subscription ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","notification"],"properties":{"success":{"type":"boolean"},"notification":{"additionalProperties":false,"type":"object","required":["id","channel","profileId","eventTypes","onlyScheduledPosts","enabled","lastTestAt","lastTestStatus","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"type":"boolean"},"enabled":{"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url","secret"],"properties":{"url":{"format":"uri","type":"string"},"secret":{"description":"Masked webhook signing secret","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}},"lastTestAt":{"type":"string","nullable":true,"format":"date-time"},"lastTestStatus":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"patch":{"operationId":"updateNotification","summary":"Update a notification subscription","tags":["Notifications"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","properties":{"profileId":{"type":"string","nullable":true},"eventTypes":{"minItems":1,"uniqueItems":true,"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"description":"When true, deliver matching notifications only for posts that were scheduled.","type":"boolean"},"enabled":{"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url"],"properties":{"url":{"format":"uri","description":"HTTPS endpoint that receives PostPeer JSON payloads","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Notification subscription ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","notification"],"properties":{"success":{"type":"boolean"},"notification":{"additionalProperties":false,"type":"object","required":["id","channel","profileId","eventTypes","onlyScheduledPosts","enabled","lastTestAt","lastTestStatus","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"channel":{"type":"string","enum":["webhook","email"]},"profileId":{"type":"string","nullable":true},"eventTypes":{"type":"array","items":{"type":"string","enum":["post.scheduled","post.published","post.partial","post.failed"]}},"onlyScheduledPosts":{"type":"boolean"},"enabled":{"type":"boolean"},"webhook":{"additionalProperties":false,"type":"object","required":["url","secret"],"properties":{"url":{"format":"uri","type":"string"},"secret":{"description":"Masked webhook signing secret","type":"string"}}},"email":{"additionalProperties":false,"type":"object","required":["recipients"],"properties":{"recipients":{"minItems":1,"maxItems":10,"type":"array","items":{"format":"email","type":"string"}}}},"lastTestAt":{"type":"string","nullable":true,"format":"date-time"},"lastTestStatus":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"delete":{"operationId":"deleteNotification","summary":"Delete a notification subscription","tags":["Notifications"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Notification subscription ID"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/platforms":{"get":{"operationId":"listPlatforms","summary":"List available platforms and their status","tags":["Platforms"],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["platforms"],"properties":{"platforms":{"type":"array","items":{"type":"object","required":["name","status"],"properties":{"name":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"status":{"type":"string","enum":["prod","beta","dev"]}}}}}}}}}}}},"/v1/posts/":{"post":{"operationId":"createPost","summary":"Publish a post to one or more social media platforms","tags":["Posts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["content","platforms"],"properties":{"content":{"description":"Post text body","type":"string"},"mediaItems":{"description":"Media attachments (images, videos, GIFs)","type":"array","items":{"additionalProperties":false,"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"format":"uri","type":"string"},"thumbnail":{"format":"uri","description":"Thumbnail image URL for video items. Supported on YouTube regular videos (not Shorts). JPEG, PNG, or GIF, max 2 MB, min 640 px wide.","type":"string"}}}},"platforms":{"minItems":1,"description":"Target platform accounts to publish to","type":"array","items":{"additionalProperties":false,"type":"object","required":["platform","accountId"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"accountId":{"description":"Integration._id — find yours via GET /connect/integrations","type":"string"},"content":{"description":"Optional per-platform text override. Use when you want to change the text for this platform because different platforms talk differently. When omitted, the top-level `content` is used.","type":"string"},"platformSpecificData":{"type":"object","additionalProperties":true,"description":"Platform-specific options. See TwitterConfigurations, YouTubeConfigurations, TikTokConfigurations, PinterestConfigurations, or LinkedInConfigurations in the schema reference for available fields per platform."}}}},"publishNow":{"description":"Publish immediately. Required when scheduledFor is omitted.","type":"boolean"},"scheduledFor":{"format":"date-time","description":"ISO 8601 datetime to schedule the post for future publishing","type":"string"},"timezone":{"description":"IANA timezone for the scheduled time (e.g. America/New_York). Defaults to UTC.","type":"string"}}},"example":{"content":"Hello world!","platforms":[{"platform":"twitter","accountId":"<your-account-id>"}],"publishNow":true}}}},"security":[{"accessKey":[]}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","status","postId","platforms"],"properties":{"success":{"description":"false only when every platform failed","type":"boolean"},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"scheduledFor":{"format":"date-time","description":"ISO 8601 datetime the post is scheduled for (only present for scheduled posts)","type":"string"},"postId":{"description":"id of the saved Post document","type":"string"},"platforms":{"type":"array","items":{"type":"object","required":["platform","success"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"success":{"type":"boolean"},"platformPostUrl":{"description":"Direct URL to the published post","type":"string"},"error":{"description":"Error message when success is false","type":"string"},"warningMessage":{"description":"Warning message when the post published but a non-critical follow-up action failed","type":"string"}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"get":{"operationId":"listPosts","summary":"List all posts for the project","tags":["Posts"],"description":"Returns a paginated list of posts. Filter by status, platform (OR logic), and date ranges. Published posts include platformPostUrl per platform.","parameters":[{"schema":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"in":"query","name":"status","required":false},{"schema":{"type":"array","items":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]}},"in":"query","name":"platform","required":false,"description":"Filter by platform (repeatable — OR logic)"},{"schema":{"type":"string"},"in":"query","name":"profileId","required":false,"description":"Filter to posts targeting an integration bound to this profile. Pass \"null\" (literal string) to filter to posts whose integrations have no profile."},{"schema":{"format":"date-time","type":"string"},"in":"query","name":"createdAfter","required":false,"description":"ISO 8601 lower bound on createdAt"},{"schema":{"format":"date-time","type":"string"},"in":"query","name":"createdBefore","required":false,"description":"ISO 8601 upper bound on createdAt"},{"schema":{"format":"date-time","type":"string"},"in":"query","name":"scheduledAfter","required":false,"description":"ISO 8601 lower bound on scheduledFor"},{"schema":{"format":"date-time","type":"string"},"in":"query","name":"scheduledBefore","required":false,"description":"ISO 8601 upper bound on scheduledFor"},{"schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"},"in":"query","name":"limit","required":false,"description":"Page size (max 100)"},{"schema":{"minimum":0,"default":0,"type":"integer"},"in":"query","name":"offset","required":false,"description":"Number of posts to skip"},{"schema":{"$ref":"#/components/schemas/SortOrder"},"in":"query","name":"sort","required":false}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","total","posts"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"description":"Total matched posts across all pages","type":"integer"},"posts":{"type":"array","items":{"type":"object","required":["postId","content","status","scheduledFor","timezone","mediaItems","platforms","crosspostingEnabled","rawRequestBody","createdAt","updatedAt"],"properties":{"postId":{"description":"MongoDB ObjectId of the Post document","type":"string"},"content":{"type":"string"},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"scheduledFor":{"type":"string","format":"date-time","nullable":true,"description":"ISO 8601 scheduled datetime"},"timezone":{"type":"string"},"mediaItems":{"type":"array","items":{"type":"object","required":["type","url","filename","size","mimeType"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"filename":{"type":"string"},"size":{"type":"number"},"mimeType":{"type":"string"}}}},"platforms":{"type":"array","items":{"type":"object","required":["platform","status","content","platformPostId","platformPostUrl","publishedAt","errorMessage","warningMessage"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"content":{"type":"string","nullable":true,"description":"Per-platform text override that was used for this platform. Null when the top-level `content` was used."},"platformPostId":{"type":"string","nullable":true},"platformPostUrl":{"type":"string","nullable":true,"description":"Direct URL to the published post"},"publishedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true},"warningMessage":{"type":"string","nullable":true}}}},"crosspostingEnabled":{"type":"boolean"},"rawRequestBody":{"type":"object","additionalProperties":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/posts/{postId}":{"get":{"operationId":"getPost","summary":"Get a single post by ID","tags":["Posts"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"postId","required":true,"description":"Post identifier"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","post"],"properties":{"success":{"type":"boolean"},"post":{"type":"object","required":["postId","content","status","scheduledFor","timezone","mediaItems","platforms","crosspostingEnabled","rawRequestBody","createdAt","updatedAt"],"properties":{"postId":{"description":"MongoDB ObjectId of the Post document","type":"string"},"content":{"type":"string"},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"scheduledFor":{"type":"string","format":"date-time","nullable":true,"description":"ISO 8601 scheduled datetime"},"timezone":{"type":"string"},"mediaItems":{"type":"array","items":{"type":"object","required":["type","url","filename","size","mimeType"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"filename":{"type":"string"},"size":{"type":"number"},"mimeType":{"type":"string"}}}},"platforms":{"type":"array","items":{"type":"object","required":["platform","status","content","platformPostId","platformPostUrl","publishedAt","errorMessage","warningMessage"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]},"content":{"type":"string","nullable":true,"description":"Per-platform text override that was used for this platform. Null when the top-level `content` was used."},"platformPostId":{"type":"string","nullable":true},"platformPostUrl":{"type":"string","nullable":true,"description":"Direct URL to the published post"},"publishedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true},"warningMessage":{"type":"string","nullable":true}}}},"crosspostingEnabled":{"type":"boolean"},"rawRequestBody":{"type":"object","additionalProperties":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"delete":{"operationId":"deletePost","summary":"Delete a post by ID","tags":["Posts"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"postId","required":true,"description":"Post identifier"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["success"],"properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/posts/scheduled/":{"get":{"operationId":"listScheduledPosts","summary":"List all scheduled posts","tags":["Schedule"],"description":"Returns a paginated list of scheduled posts. Use `limit` + `offset` to page through the results.","parameters":[{"schema":{"minimum":1,"maximum":100,"default":20,"type":"integer"},"in":"query","name":"limit","required":false,"description":"Page size (max 100)"},{"schema":{"minimum":0,"default":0,"type":"integer"},"in":"query","name":"offset","required":false,"description":"Number of scheduled posts to skip"},{"schema":{"$ref":"#/components/schemas/SortOrder"},"in":"query","name":"sort","required":false}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","total","posts"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"description":"Total matched scheduled posts across all pages","type":"integer"},"posts":{"type":"array","items":{"type":"object","required":["postId","content","scheduledFor","timezone","platforms","createdAt"],"properties":{"postId":{"description":"MongoDB ObjectId of the Post document","type":"string"},"content":{"description":"Post text body","type":"string"},"scheduledFor":{"type":"string","format":"date-time","nullable":true,"description":"ISO 8601 scheduled datetime"},"timezone":{"description":"IANA timezone for the scheduled time","type":"string"},"mediaItems":{"description":"Media attachments","type":"array","items":{"additionalProperties":false,"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"format":"uri","type":"string"},"thumbnail":{"format":"uri","description":"Thumbnail image URL for video items. Supported on YouTube regular videos (not Shorts). JPEG, PNG, or GIF, max 2 MB, min 640 px wide.","type":"string"}}}},"platforms":{"type":"array","items":{"type":"object","required":["platform","status"],"properties":{"platform":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]},"status":{"type":"string","enum":["draft","pending","scheduled","publishing","published","failed","partial"]}}}},"createdAt":{"format":"date-time","type":"string"}}}}}}}}}}}},"/v1/posts/scheduled/{postId}":{"delete":{"operationId":"cancelScheduledPost","summary":"Cancel a scheduled post (moves it back to draft)","tags":["Schedule"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"postId","required":true}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}},"patch":{"operationId":"reschedulePost","summary":"Reschedule a post to a new time","tags":["Schedule"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scheduledFor"],"properties":{"scheduledFor":{"format":"date-time","description":"New ISO 8601 datetime to schedule the post","type":"string"},"timezone":{"description":"IANA timezone","type":"string"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"postId","required":true}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message","scheduledFor"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"},"scheduledFor":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/media/upload":{"post":{"operationId":"createMediaUpload","summary":"Get a presigned S3 URL to upload a media file","tags":["Media"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["filename","mimeType"],"properties":{"filename":{"minLength":1,"type":"string"},"mimeType":{"minLength":1,"type":"string"}}}}}},"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean"},"data":{"type":"object","required":["uploadUrl","publicUrl"],"properties":{"uploadUrl":{"type":"string"},"publicUrl":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/analytics/":{"get":{"operationId":"getAnalytics","summary":"Get post analytics","tags":["Analytics"],"description":"With postId, returns analytics for a single post. Without postId, returns a paginated list of published posts with analytics. Accepts both PostPeer post IDs and external platform post IDs (auto-resolved). fromDate defaults to 90 days ago if omitted, max range 366 days. Each call costs 1 credit.","parameters":[{"schema":{"type":"string"},"in":"query","name":"postId","required":false,"description":"PostPeer post ID or external platform post ID (auto-resolved). When omitted, returns a paginated list of all published posts with analytics."},{"schema":{"$ref":"#/components/schemas/Platform"},"in":"query","name":"platform","required":false},{"schema":{"type":"string"},"in":"query","name":"accountId","required":false,"description":"Integration ID. Required for external ID lookups and source=platform."},{"schema":{"type":"string","enum":["postpeer","platform"]},"in":"query","name":"source","required":false,"description":"Where the result came from. \"postpeer\" = posts published via PostPeer (stored in our DB). \"platform\" = fetched directly from the connected platform account."},{"schema":{"format":"date","type":"string"},"in":"query","name":"fromDate","required":false,"description":"Inclusive start date (YYYY-MM-DD). Defaults to 90 days ago."},{"schema":{"format":"date","type":"string"},"in":"query","name":"toDate","required":false,"description":"Inclusive end date (YYYY-MM-DD). Defaults to today."},{"schema":{"type":"string","enum":["date","likes","comments","impressions","views","shares","saves","clicks","engagement"],"default":"date"},"in":"query","name":"sortBy","required":false,"description":"Sort results by this metric"},{"schema":{"$ref":"#/components/schemas/SortOrder"},"in":"query","name":"order","required":false},{"schema":{"minimum":1,"maximum":100,"default":50,"type":"integer"},"in":"query","name":"limit","required":false,"description":"Page size (1-100)"},{"schema":{"minimum":1,"default":1,"type":"integer"},"in":"query","name":"page","required":false,"description":"Page number"}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Single-post response (when postId is supplied) or paginated list response.","content":{"application/json":{"schema":{"description":"Single-post response (when postId is supplied) or paginated list response.","anyOf":[{"type":"object","required":["success","post"],"properties":{"success":{"type":"boolean"},"post":{"type":"object","required":["source","postId","content","publishedAt","aggregated","platforms"],"properties":{"source":{"type":"string","enum":["postpeer","platform"],"description":"Where the result came from. \"postpeer\" = posts published via PostPeer (stored in our DB). \"platform\" = fetched directly from the connected platform account."},"postId":{"type":"string","nullable":true,"description":"PostPeer post ID. null when source=platform (post fetched directly from the platform)."},"content":{"type":"string","nullable":true},"publishedAt":{"type":"string","format":"date-time","nullable":true},"aggregated":{"type":"object","required":["impressions","reach","likes","comments","shares","saves","clicks","views","engagementRate"],"properties":{"impressions":{"type":"number","nullable":true},"reach":{"type":"number","nullable":true},"likes":{"type":"number","nullable":true},"comments":{"type":"number","nullable":true},"shares":{"type":"number","nullable":true},"saves":{"type":"number","nullable":true},"clicks":{"type":"number","nullable":true},"views":{"type":"number","nullable":true},"engagementRate":{"type":"number","nullable":true,"description":"Engagement rate (0-1). null when the platform does not report engagement."}}},"platforms":{"type":"array","items":{"type":"object","required":["platform","platformPostId","platformPostUrl","metrics"],"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"platformPostId":{"description":"Native post ID on the platform","type":"string"},"platformPostUrl":{"type":"string","nullable":true,"description":"Direct URL to the published post, if known"},"metrics":{"type":"object","required":["impressions","reach","likes","comments","shares","saves","clicks","views","engagementRate"],"properties":{"impressions":{"type":"number","nullable":true},"reach":{"type":"number","nullable":true},"likes":{"type":"number","nullable":true},"comments":{"type":"number","nullable":true},"shares":{"type":"number","nullable":true},"saves":{"type":"number","nullable":true},"clicks":{"type":"number","nullable":true},"views":{"type":"number","nullable":true},"engagementRate":{"type":"number","nullable":true,"description":"Engagement rate (0-1). null when the platform does not report engagement."}}}}}}}}}},{"type":"object","required":["success","total","page","limit","posts"],"properties":{"success":{"type":"boolean"},"total":{"minimum":0,"description":"Total matched posts across all pages","type":"integer"},"page":{"minimum":1,"type":"integer"},"limit":{"minimum":1,"type":"integer"},"posts":{"type":"array","items":{"type":"object","required":["source","postId","content","publishedAt","aggregated","platforms"],"properties":{"source":{"type":"string","enum":["postpeer","platform"],"description":"Where the result came from. \"postpeer\" = posts published via PostPeer (stored in our DB). \"platform\" = fetched directly from the connected platform account."},"postId":{"type":"string","nullable":true,"description":"PostPeer post ID. null when source=platform (post fetched directly from the platform)."},"content":{"type":"string","nullable":true},"publishedAt":{"type":"string","format":"date-time","nullable":true},"aggregated":{"type":"object","required":["impressions","reach","likes","comments","shares","saves","clicks","views","engagementRate"],"properties":{"impressions":{"type":"number","nullable":true},"reach":{"type":"number","nullable":true},"likes":{"type":"number","nullable":true},"comments":{"type":"number","nullable":true},"shares":{"type":"number","nullable":true},"saves":{"type":"number","nullable":true},"clicks":{"type":"number","nullable":true},"views":{"type":"number","nullable":true},"engagementRate":{"type":"number","nullable":true,"description":"Engagement rate (0-1). null when the platform does not report engagement."}}},"platforms":{"type":"array","items":{"type":"object","required":["platform","platformPostId","platformPostUrl","metrics"],"properties":{"platform":{"$ref":"#/components/schemas/Platform"},"platformPostId":{"description":"Native post ID on the platform","type":"string"},"platformPostUrl":{"type":"string","nullable":true,"description":"Direct URL to the published post, if known"},"metrics":{"type":"object","required":["impressions","reach","likes","comments","shares","saves","clicks","views","engagementRate"],"properties":{"impressions":{"type":"number","nullable":true},"reach":{"type":"number","nullable":true},"likes":{"type":"number","nullable":true},"comments":{"type":"number","nullable":true},"shares":{"type":"number","nullable":true},"saves":{"type":"number","nullable":true},"clicks":{"type":"number","nullable":true},"views":{"type":"number","nullable":true},"engagementRate":{"type":"number","nullable":true,"description":"Engagement rate (0-1). null when the platform does not report engagement."}}}}}}}}}}}]}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/pinterest/boards":{"get":{"operationId":"getPinterestBoards","summary":"List Pinterest boards for a connected account","tags":["Pinterest"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"accountId","required":false,"description":"Integration ID of the Pinterest account. If omitted, uses the first connected Pinterest account."}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","boards"],"properties":{"success":{"type":"boolean"},"boards":{"type":"array","items":{"type":"object","required":["id","name","description","privacy"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"privacy":{"type":"string"}}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"502":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/tiktok/creator-info":{"get":{"operationId":"getTikTokCreatorInfo","summary":"Fetch TikTok creator info for a connected account","tags":["TikTok"],"description":"Proxies TikTok's /v2/post/publish/creator_info/query/ endpoint. Use the returned `privacyLevelOptions`, `commentDisabled`, `duetDisabled`, `stitchDisabled`, and `maxVideoPostDurationSec` to build a compliant \"Post to TikTok\" UX.","parameters":[{"schema":{"type":"string"},"in":"query","name":"accountId","required":false,"description":"Integration ID of the TikTok account. If omitted, uses the first connected TikTok account."}],"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean"},"data":{"type":"object","required":["creatorAvatarUrl","creatorUsername","creatorNickname","privacyLevelOptions","commentDisabled","duetDisabled","stitchDisabled","maxVideoPostDurationSec"],"properties":{"creatorAvatarUrl":{"description":"Profile avatar URL returned by TikTok.","anyOf":[{"type":"string"},{"type":"null"}]},"creatorUsername":{"description":"Username (@handle) of the creator.","anyOf":[{"type":"string"},{"type":"null"}]},"creatorNickname":{"description":"Display name of the creator.","anyOf":[{"type":"string"},{"type":"null"}]},"privacyLevelOptions":{"description":"Privacy levels available to this creator. Your UX must restrict the privacy dropdown to these values.","type":"array","items":{"type":"string","enum":["PUBLIC_TO_EVERYONE","MUTUAL_FOLLOW_FRIENDS","FOLLOWER_OF_CREATOR","SELF_ONLY"]}},"commentDisabled":{"description":"If true, the creator has disabled comments in their app settings — grey out the Allow Comment toggle.","type":"boolean"},"duetDisabled":{"description":"If true, the creator has disabled duet in their app settings — grey out the Allow Duet toggle.","type":"boolean"},"stitchDisabled":{"description":"If true, the creator has disabled stitch in their app settings — grey out the Allow Stitch toggle.","type":"boolean"},"maxVideoPostDurationSec":{"description":"Maximum video duration (in seconds) this creator may post. Reject videos longer than this before upload.","type":"number"}}},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"502":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/v1/ai/write":{"post":{"operationId":"aiWriteContent","summary":"Generate a social media caption from a description","tags":["AI"],"description":"Generates a caption tailored to the platforms you'll post to. Costs 2 credits per successful generation. Failed calls do not deduct credits.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["description"],"properties":{"description":{"minLength":3,"maxLength":1500,"description":"Free-form description of what the post should be about, in the creator's own words.","type":"string"},"platforms":{"description":"Platforms this post will target. Used to fit the strictest character limit.","type":"array","items":{"type":"string","enum":["twitter","instagram","youtube","tiktok","pinterest","linkedin","bluesky","facebook","threads"]}},"existingContent":{"description":"Optional existing draft to rewrite/improve rather than start from scratch.","type":"string"}}}}}},"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","content","creditsCharged"],"properties":{"success":{"type":"boolean"},"content":{"type":"string"},"creditsCharged":{"type":"number"}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}},"/v1/ai/image":{"post":{"operationId":"aiGenerateImage","summary":"Generate a social media image from a description","tags":["AI"],"description":"Generates a square or vertical image suitable for social media. Costs 10 credits per successful generation. Failed calls do not deduct credits.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["description"],"properties":{"description":{"minLength":3,"maxLength":1500,"type":"string"},"aspectRatio":{"type":"string","enum":["square","vertical","landscape"],"description":"Output aspect ratio. Defaults to square when omitted."},"style":{"type":"string","enum":["photo","illustration","minimal","vibrant","cinematic","3d-render","retro","hand-drawn"],"description":"Visual style preset. Adds style guidance to the prompt. Omit for the model to pick whatever fits the brief."},"referenceImageUrls":{"maxItems":4,"description":"Reference images. Used as style/vibe inspiration ONLY. The model will not copy them. Useful for \"match my brand look\" or \"same composition as this\".","type":"array","items":{"format":"uri","type":"string"}},"assetImageUrls":{"maxItems":4,"description":"Asset images that MUST appear in the generated image (e.g. a brand logo, a specific product photo). The model will place them faithfully according to the brief, without redrawing them.","type":"array","items":{"format":"uri","type":"string"}},"referenceImageUrl":{"format":"uri","description":"DEPRECATED: use referenceImageUrls instead. Still accepted for backwards compatibility.","type":"string"}}}}}},"security":[{"accessKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","url","mimeType","creditsCharged"],"properties":{"success":{"type":"boolean"},"url":{"format":"uri","type":"string"},"mimeType":{"type":"string"},"creditsCharged":{"type":"number"}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}}}}}},"servers":[{"url":"https://api.postpeer.dev","description":"Production"}]}