{"openapi":"3.1.0","info":{"title":"Planable Public API","version":"1.0.0","description":"REST API for managing Planable companies, workspaces, pages, posts and more.\n\n**Plan eligibility:** new API tokens can only be generated by companies on the **Pro** and **Enterprise** plans. Tokens that have already been generated continue to work regardless of plan."},"servers":[{"url":"https://api.planable.io/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"pln_*"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR","UNAUTHORIZED","FORBIDDEN","NOT_FOUND","METHOD_NOT_ALLOWED","RATE_LIMITED","POST_ALREADY_PUBLISHED","PUBLISHING_IN_PROGRESS","WORKSPACE_LIMIT_REACHED","INTERNAL"]},"message":{"type":"string"},"requestId":{"type":"string"}},"required":["code","message","requestId"]}},"required":["error"]}},"parameters":{}},"paths":{"/ping":{"get":{"tags":["System"],"summary":"Health check","description":"Returns 200 if the token is valid and has the read scope.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"tokenId":{"type":"string"},"companyId":{"type":"string"}},"required":["ok","tokenId","companyId"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts":{"get":{"tags":["Posts"],"summary":"List posts","description":"Returns posts for a workspace with pagination. Each item includes the same post detail fields as GET /posts/{id}.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"pageId","in":"query","required":false,"schema":{"type":"string"}},{"name":"campaignId","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by campaign ID, or `no-campaign` for posts not assigned to any campaign"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of post details with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string"},"plainText":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"gridPosition":{"type":"number"},"campaignId":{"type":["string","null"]},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}},"approval":{"type":"object","properties":{"status":{"type":"string","enum":["NOT_APPLICABLE","NEVER_SENT","PENDING","PARTIALLY_APPROVED","FULLY_APPROVED"]},"approved":{"type":"boolean"},"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED","MULTIPLE"]},"completedLevels":{"type":"integer","minimum":0},"totalLevels":{"type":"integer","minimum":0},"currentLevelId":{"type":"string"},"levels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}}},"required":["id","label","approved","approvedBy"]}}},"required":["status","approved","type","completedLevels","totalLevels","levels"]},"published":{"type":"boolean"},"scheduledSet":{"type":"boolean"},"teamOnly":{"type":"boolean"},"archived":{"type":"boolean"},"modifiedAt":{"type":"string","format":"date-time"},"mediaType":{"type":"string"},"videoThumbnailUrl":{"type":"string","format":"uri","description":"Current thumbnail (cover) URL of the post video, when the post has a video with a thumbnail."},"labels":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"text":{"type":"string"},"color":{"type":"string"}},"required":["uuid","text","color"]}},"commentsCounter":{"type":"number"},"notesCounter":{"type":"number"},"publicShareLink":{"type":"string","format":"uri"},"publishedPostLink":{"type":"string","format":"uri"},"groupId":{"type":"string"},"groupPageIds":{"type":"array","items":{"type":"string"}},"groupSync":{"type":"boolean"},"pinterest":{"type":"object","properties":{"boardId":{"type":"string"},"boardName":{"type":"string"},"title":{"type":["string","null"]},"link":{"type":["string","null"]},"description":{"type":["string","null"]}},"required":["boardId","boardName","title","link","description"]}},"required":["id","workspaceId","pageId","type","classification","plainText","createdAt","campaignId","media","scheduledAt","status","approved","approval","published","scheduledSet","teamOnly","archived","commentsCounter","notesCounter"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Posts"],"summary":"Create a new post","description":"Creates a post in the specified workspace and page. Use `pageId` for a single post or `pageIds` to create grouped cross-page posts. When `media` URLs are provided for grouped posts, each file is imported into the workspace Media Library once and the same asset is reused across every post in the group instead of being copied per platform. The `notify` flag controls whether workspace members receive a post-added notification (email/in-app push); set it to `false` to suppress those notifications. Internal activity feed entries are always recorded. `notify` is not an approval request — use POST /posts/{id}/request-approval to notify approvers. The `media` field: Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs. Use `videoThumbnail` to set a custom video thumbnail (cover); it requires a video in `media` that finishes transcoding during the request, otherwise the request returns 400 after the post is created — in that case, retry via PATCH /posts/{id} once the video is processed.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"pageId":{"type":"string","minLength":1},"pageIds":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":20},"text":{"type":"string","maxLength":25000,"default":""},"gridPosition":{"type":"integer","minimum":0},"scheduledAt":{"type":"string","format":"date-time"},"labels":{"type":"array","items":{"type":"string"},"default":[]},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"default":[],"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"teamOnly":{"type":"boolean"},"approved":{"type":"boolean"},"approvedBy":{"type":"string","minLength":1},"publishAtScheduledDate":{"type":"boolean","default":false},"firstComment":{"type":"string","maxLength":8000},"internalNote":{"type":"string","maxLength":8000},"youtubeTitle":{"type":"string","maxLength":100},"linkedinPdfTitle":{"type":"string","maxLength":150,"description":"LinkedIn PDF carousel title (`linkedinData.pdfTitle`). When set on a LinkedIn post with multiple images, also enables publishing as a PDF document carousel (`linkedinData.publishCarouselAsPdf`). Pass an empty string on PATCH to disable PDF mode and clear the title."},"linkedinVideoTitle":{"type":"string","maxLength":150},"notify":{"type":"boolean","default":true,"description":"Controls whether workspace members receive a post-added notification (email/in-app push). This is not an approval request — use POST /posts/{id}/request-approval to notify approvers."},"pinterest":{"type":"object","properties":{"boardId":{"type":"string","minLength":1},"title":{"type":"string","maxLength":100},"link":{"type":"string","format":"uri"},"description":{"type":"string","maxLength":500}},"required":["boardId"]},"campaignId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"},{"type":"null"}]},"videoThumbnail":{"type":"object","properties":{"imageUrl":{"type":"string","format":"uri","description":"Public URL of a static image that is uploaded and set as the video thumbnail (cover)."},"offsetSeconds":{"type":"number","minimum":0,"description":"Offset into the video, in seconds; the frame at this position is extracted and set as the thumbnail."}},"description":"Sets a custom thumbnail on the post video (the single video, or the first video for mixed media). Requires the video to be fully transcoded."}},"required":["workspaceId"]}}}},"responses":{"201":{"description":"Post created","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string"},"plainText":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"gridPosition":{"type":"number"},"campaignId":{"type":["string","null"]},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}},"approval":{"type":"object","properties":{"status":{"type":"string","enum":["NOT_APPLICABLE","NEVER_SENT","PENDING","PARTIALLY_APPROVED","FULLY_APPROVED"]},"approved":{"type":"boolean"},"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED","MULTIPLE"]},"completedLevels":{"type":"integer","minimum":0},"totalLevels":{"type":"integer","minimum":0},"currentLevelId":{"type":"string"},"levels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}}},"required":["id","label","approved","approvedBy"]}}},"required":["status","approved","type","completedLevels","totalLevels","levels"]},"published":{"type":"boolean"},"scheduledSet":{"type":"boolean"},"teamOnly":{"type":"boolean"},"archived":{"type":"boolean"},"modifiedAt":{"type":"string","format":"date-time"},"mediaType":{"type":"string"},"videoThumbnailUrl":{"type":"string","format":"uri","description":"Current thumbnail (cover) URL of the post video, when the post has a video with a thumbnail."},"labels":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"text":{"type":"string"},"color":{"type":"string"}},"required":["uuid","text","color"]}},"commentsCounter":{"type":"number"},"notesCounter":{"type":"number"},"publicShareLink":{"type":"string","format":"uri"},"publishedPostLink":{"type":"string","format":"uri"},"groupId":{"type":"string"},"groupPageIds":{"type":"array","items":{"type":"string"}},"groupSync":{"type":"boolean"},"pinterest":{"type":"object","properties":{"boardId":{"type":"string"},"boardName":{"type":"string"},"title":{"type":["string","null"]},"link":{"type":["string","null"]},"description":{"type":["string","null"]}},"required":["boardId","boardName","title","link","description"]}},"required":["id","workspaceId","pageId","type","classification","plainText","createdAt","campaignId","media","scheduledAt","status","approved","approval","published","scheduledSet","teamOnly","archived","commentsCounter","notesCounter"]}}},"required":["posts"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workspace or page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}":{"get":{"tags":["Posts"],"summary":"Get post detail","description":"Returns a single post by ID including media URLs.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Post detail with media","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string"},"plainText":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"gridPosition":{"type":"number"},"campaignId":{"type":["string","null"]},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}},"approval":{"type":"object","properties":{"status":{"type":"string","enum":["NOT_APPLICABLE","NEVER_SENT","PENDING","PARTIALLY_APPROVED","FULLY_APPROVED"]},"approved":{"type":"boolean"},"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED","MULTIPLE"]},"completedLevels":{"type":"integer","minimum":0},"totalLevels":{"type":"integer","minimum":0},"currentLevelId":{"type":"string"},"levels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}}},"required":["id","label","approved","approvedBy"]}}},"required":["status","approved","type","completedLevels","totalLevels","levels"]},"published":{"type":"boolean"},"scheduledSet":{"type":"boolean"},"teamOnly":{"type":"boolean"},"archived":{"type":"boolean"},"modifiedAt":{"type":"string","format":"date-time"},"mediaType":{"type":"string"},"videoThumbnailUrl":{"type":"string","format":"uri","description":"Current thumbnail (cover) URL of the post video, when the post has a video with a thumbnail."},"labels":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"text":{"type":"string"},"color":{"type":"string"}},"required":["uuid","text","color"]}},"commentsCounter":{"type":"number"},"notesCounter":{"type":"number"},"publicShareLink":{"type":"string","format":"uri"},"publishedPostLink":{"type":"string","format":"uri"},"groupId":{"type":"string"},"groupPageIds":{"type":"array","items":{"type":"string"}},"groupSync":{"type":"boolean"},"pinterest":{"type":"object","properties":{"boardId":{"type":"string"},"boardName":{"type":"string"},"title":{"type":["string","null"]},"link":{"type":["string","null"]},"description":{"type":["string","null"]}},"required":["boardId","boardName","title","link","description"]}},"required":["id","workspaceId","pageId","type","classification","plainText","createdAt","campaignId","media","scheduledAt","status","approved","approval","published","scheduledSet","teamOnly","archived","commentsCounter","notesCounter"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Posts"],"summary":"Delete a post","description":"Deletes a post in a workspace accessible to the calling token.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Post deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Posts"],"summary":"Update a post","description":"Updates a post. Published posts are immutable and will return 400. The `media` field: Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs. Pass an empty array to clear media. Stories support a single, non-GIF media item; submitting multiple media URLs or a GIF for a story returns 400. Set `archived` to `true` to archive a post or `false` to restore it; archiving removes any active schedule. Use `videoThumbnail` to set a custom video thumbnail (cover) from an image URL or from a video frame offset; the post must have a fully transcoded video (the first video is used for mixed media). Set `notify` to `false` to suppress notifications (email/in-app push, Zapier) for the edit activities created by this update; internal activity feed entries are always recorded. `notify` modifies nothing by itself, so it does not count towards the at-least-one-field requirement. It is not an approval request — use POST /posts/{id}/request-approval to notify approvers.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","maxLength":25000},"scheduledAt":{"type":["string","null"],"format":"date-time"},"labels":{"type":"array","items":{"type":"string"}},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"teamOnly":{"type":"boolean"},"approved":{"type":"boolean"},"approvedBy":{"type":"string","minLength":1},"linkedinPdfTitle":{"type":"string","maxLength":150,"description":"LinkedIn PDF carousel title (`linkedinData.pdfTitle`). When set on a LinkedIn post with multiple images, also enables publishing as a PDF document carousel (`linkedinData.publishCarouselAsPdf`). Pass an empty string on PATCH to disable PDF mode and clear the title."},"linkedinVideoTitle":{"type":"string","maxLength":150},"pinterest":{"type":"object","properties":{"boardId":{"type":"string","minLength":1},"title":{"type":"string","maxLength":100},"link":{"type":"string","format":"uri"},"description":{"type":"string","maxLength":500}}},"publishAtScheduledDate":{"type":"boolean"},"archived":{"type":"boolean"},"campaignId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"},{"type":"null"}]},"notify":{"type":"boolean","description":"When false, the edit activities created by this update do not trigger notifications (email/in-app push, Zapier). Modifies nothing by itself, so at least one other field must be provided."},"videoThumbnail":{"type":"object","properties":{"imageUrl":{"type":"string","format":"uri","description":"Public URL of a static image that is uploaded and set as the video thumbnail (cover)."},"offsetSeconds":{"type":"number","minimum":0,"description":"Offset into the video, in seconds; the frame at this position is extracted and set as the thumbnail."}},"description":"Sets a custom thumbnail on the post video (the single video, or the first video for mixed media). Requires the video to be fully transcoded."}}}}}},"responses":{"200":{"description":"Updated post detail","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string"},"plainText":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"gridPosition":{"type":"number"},"campaignId":{"type":["string","null"]},"media":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Up to 20 public image or video URLs, each max 100MB. Files are downloaded server-side from the provided URLs."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}},"approval":{"type":"object","properties":{"status":{"type":"string","enum":["NOT_APPLICABLE","NEVER_SENT","PENDING","PARTIALLY_APPROVED","FULLY_APPROVED"]},"approved":{"type":"boolean"},"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED","MULTIPLE"]},"completedLevels":{"type":"integer","minimum":0},"totalLevels":{"type":"integer","minimum":0},"currentLevelId":{"type":"string"},"levels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"levelId":{"type":"string"}},"required":["userId","approvedAt"]}}},"required":["id","label","approved","approvedBy"]}}},"required":["status","approved","type","completedLevels","totalLevels","levels"]},"published":{"type":"boolean"},"scheduledSet":{"type":"boolean"},"teamOnly":{"type":"boolean"},"archived":{"type":"boolean"},"modifiedAt":{"type":"string","format":"date-time"},"mediaType":{"type":"string"},"videoThumbnailUrl":{"type":"string","format":"uri","description":"Current thumbnail (cover) URL of the post video, when the post has a video with a thumbnail."},"labels":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"text":{"type":"string"},"color":{"type":"string"}},"required":["uuid","text","color"]}},"commentsCounter":{"type":"number"},"notesCounter":{"type":"number"},"publicShareLink":{"type":"string","format":"uri"},"publishedPostLink":{"type":"string","format":"uri"},"groupId":{"type":"string"},"groupPageIds":{"type":"array","items":{"type":"string"}},"groupSync":{"type":"boolean"},"pinterest":{"type":"object","properties":{"boardId":{"type":"string"},"boardName":{"type":"string"},"title":{"type":["string","null"]},"link":{"type":["string","null"]},"description":{"type":["string","null"]}},"required":["boardId","boardName","title","link","description"]}},"required":["id","workspaceId","pageId","type","classification","plainText","createdAt","campaignId","media","scheduledAt","status","approved","approval","published","scheduledSet","teamOnly","archived","commentsCounter","notesCounter"]}},"required":["data"]}}}},"400":{"description":"Validation error or post is already published"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/metrics":{"get":{"tags":["Posts"],"summary":"Get post metrics","description":"Returns the latest metrics snapshot for a published post.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Latest metrics snapshot for the post","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"postId":{"type":"string"},"pageId":{"type":"string"},"pageType":{"type":"string"},"fetchedAt":{"type":"string","format":"date-time"},"impressions":{"type":"number"},"engagement":{"type":"number"},"reactions":{"type":"number"},"facebook":{"type":"object","properties":{}},"instagram":{"type":"object","properties":{}},"linkedin":{"type":"object","properties":{}},"tiktok":{"type":"object","properties":{}},"threads":{"type":"object","properties":{}},"youtube":{"type":"object","properties":{}}},"required":["postId","pageId","pageType","fetchedAt","impressions","engagement","reactions"]}},"required":["data"]}}}},"400":{"description":"Post is not published"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post not found or metrics missing"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/sync":{"post":{"tags":["Posts"],"summary":"Trigger post metrics sync","description":"Triggers a fresh metrics sync for a published post.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Post metrics sync queued or deduplicated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"postId":{"type":"string"},"started":{"type":"boolean"},"message":{"type":"string"}},"required":["postId","started","message"]}},"required":["data"]}}}},"400":{"description":"Post is not published"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/sync-status":{"get":{"tags":["Posts"],"summary":"Get post metrics sync status","description":"Returns whether a post metrics sync is in progress and when metrics last synced.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Post metrics sync status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"postId":{"type":"string"},"syncInProgress":{"type":"boolean"},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}},"required":["postId","syncInProgress","lastSyncedAt"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/share":{"post":{"tags":["Posts"],"summary":"Create a public share link","description":"Generates a client-shareable public link for a post. Idempotent: if the post is already shared, returns the existing link. Grouped posts share a single link across the group.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Public share link for the post","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"publicShareLink":{"type":"string","format":"uri"}},"required":["publicShareLink"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Posts"],"summary":"Revoke the public share link","description":"Removes the public share link from a post. Idempotent: returns 204 even if the post is not shared.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Public share link revoked"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/reorder":{"patch":{"tags":["Posts"],"summary":"Reorder posts in the grid","description":"Sets zero-based grid positions for posts using the order of `postIds`. The first ID receives `gridPosition: 0`, the second receives `gridPosition: 1`, and so on.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"postIds":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":500}},"required":["workspaceId","postIds"]}}}},"responses":{"200":{"description":"Posts reordered","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"gridPosition":{"type":"number"}},"required":["id","gridPosition"]}}},"required":["posts"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workspace or post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/request-approval":{"post":{"tags":["Posts"],"summary":"Send a post for approval","description":"Notifies the given workspace members to review and approve the post. Approvers must be members of the post workspace; for team-only posts only team members are notified. Optionally pass `levelId` to target a specific approval level on workspaces with multi-level approval, and `note` to include a message in the notification.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"approverIds":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":100},"levelId":{"type":"string"},"note":{"type":"string","maxLength":2000}},"required":["approverIds"]}}}},"responses":{"200":{"description":"Approval request sent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"postId":{"type":"string"},"notifiedUserIds":{"type":"array","items":{"type":"string"}},"levelId":{"type":"string"}},"required":["postId","notifiedUserIds","levelId"]}},"required":["data"]}}}},"400":{"description":"Validation error: an approver is not a workspace member, only client users were provided for a team-only post, or the post is already published"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/count":{"get":{"tags":["Posts"],"summary":"Get total posts count","description":"Returns the total number of posts across all workspaces the token has access to.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Total posts count and per-workspace breakdown","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"total":{"type":"number"},"workspaces":{"type":"array","items":{"type":"object","properties":{"workspaceId":{"type":"string"},"count":{"type":"number"}},"required":["workspaceId","count"]}}},"required":["total","workspaces"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/campaigns":{"get":{"tags":["Campaigns"],"summary":"List campaigns","description":"Returns campaigns for a workspace with pagination, optionally filtered by status.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","archived","paused","planned","completed"]}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of campaigns with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["active","archived","paused","planned","completed"]},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":["string","null"]}},"required":["url","title"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","name","status","icon","color","startedAt","endedAt","links","createdAt"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Campaigns"],"summary":"Create a campaign","description":"Creates a campaign in a workspace. `description` is supplied as plain text and stored as rich text. Subject to the workspace campaign plan limit.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":80},"status":{"type":"string","enum":["active","archived","paused","planned","completed"],"default":"planned"},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","minLength":1},"title":{"type":"string"}},"required":["url"]}}},"required":["workspaceId","name"]}}}},"responses":{"201":{"description":"Campaign created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["active","archived","paused","planned","completed"]},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":["string","null"]}},"required":["url","title"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","name","status","icon","color","startedAt","endedAt","links","createdAt"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Campaign limit reached or insufficient permissions"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/campaigns/{id}":{"get":{"tags":["Campaigns"],"summary":"Get campaign detail","description":"Returns a single campaign by ID.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Campaign detail","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["active","archived","paused","planned","completed"]},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":["string","null"]}},"required":["url","title"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","name","status","icon","color","startedAt","endedAt","links","createdAt"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Campaign not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Campaigns"],"summary":"Update a campaign","description":"Partially updates a campaign. Any subset of the create fields may be provided.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"status":{"type":"string","enum":["active","archived","paused","planned","completed"]},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","minLength":1},"title":{"type":"string"}},"required":["url"]}}}}}}},"responses":{"200":{"description":"Campaign updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["active","archived","paused","planned","completed"]},"icon":{"type":"string","enum":["star","bulb","calendar","apple","gift","christmasTree","glass","eggCracked","archive","ghost","cross","candle","home","briefcase","school","camera","bike","bell","barbell","barrier","paint","bolt","heart","babyCarriage","trophy","award","paw","bone","creditCard","discount","shield","tag","thumbUp","thumbDown","umbrella","flag","sun","campfire","seeding","leaf","cherry","macro","clover","pumpkin","flame","cactus","globe","stack","basketball","baseball","ball","gasPump","car","balloon","mug","location","analyze","chartPie","chartDots","cards","mail","headphones","microphone","key"]},"color":{"type":"string"},"startedAt":{"type":["string","null"],"format":"date-time"},"endedAt":{"type":["string","null"],"format":"date-time"},"description":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":["string","null"]}},"required":["url","title"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","name","status","icon","color","startedAt","endedAt","links","createdAt"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Campaign not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Campaigns"],"summary":"Delete a campaign","description":"Deletes a campaign and detaches it from its posts. Posts are kept; only the `campaignId` link is removed.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Campaign deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Campaign not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/labels":{"get":{"tags":["Labels"],"summary":"List labels","description":"Returns all labels for a workspace.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of labels","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","color","name"]}}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Labels"],"summary":"Create a label","description":"Creates a new label in a workspace.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"text":{"type":"string","minLength":1},"color":{"type":"string","enum":["pattens-blue","feta","pink-lace","pippin","peach-cream","fog","half-and-half","lime-flurish","snowy-mint","blue-chalk","mabel","silver-sand"]}},"required":["workspaceId","text","color"]}}}},"responses":{"201":{"description":"Label created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","color","name"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/members":{"get":{"tags":["Members"],"summary":"List workspace members","description":"Returns the members of a workspace with their permissions, membership type (team or client), and approver status. Use this to map member ids to people when requesting approvals or interpreting comment authors.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of workspace members","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"membership":{"type":"string"},"isApprover":{"type":"boolean"},"approvalLevelIds":{"type":"array","items":{"type":"string"}},"avatarUrl":{"type":["string","null"]}},"required":["id","name","email","permissions","membership","isApprover","avatarUrl"]}}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token does not have access to this workspace"},"404":{"description":"Workspace not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/media":{"get":{"tags":["Media"],"summary":"List media uploads","description":"Returns media uploads for a workspace with pagination.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of media uploads with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"type":{"type":"string","enum":["image","video","gif"]},"name":{"type":"string"},"url":{"type":["string","null"],"format":"uri"},"thumbnailUrl":{"type":["string","null"],"format":"uri"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"size":{"type":"number"},"mimeType":{"type":"string"},"status":{"type":"string","enum":["uploading","processing","error","success"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","type","name","url","thumbnailUrl","width","height","size","mimeType","status","createdAt"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Media"],"summary":"Upload media from URLs","description":"Accepts 1 to 20 public image or video URLs (each max 100MB) for async download and processing. Returns 202 immediately with processing status for each item.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"mediaUrls":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":20,"description":"Array of 1 to 20 public image/video URLs to upload to the workspace media library. Each file max ~100MB."}},"required":["workspaceId","mediaUrls"]}}}},"responses":{"202":{"description":"Media upload accepted for processing","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["processing"]}},"required":["id","status"]}}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/media/{id}":{"get":{"tags":["Media"],"summary":"Get media upload","description":"Returns a single media upload by ID.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Media upload detail","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"type":{"type":"string","enum":["image","video","gif"]},"name":{"type":"string"},"url":{"type":["string","null"],"format":"uri"},"thumbnailUrl":{"type":["string","null"],"format":"uri"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"size":{"type":"number"},"mimeType":{"type":"string"},"status":{"type":"string","enum":["uploading","processing","error","success"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","type","name","url","thumbnailUrl","width","height","size","mimeType","status","createdAt"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Media not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/sync":{"post":{"tags":["Pages"],"summary":"Trigger page metrics sync","description":"Triggers a fresh analytics metrics sync for a page.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Page metrics sync queued or deduplicated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"pageId":{"type":"string"},"started":{"type":"boolean"},"message":{"type":"string"}},"required":["pageId","started","message"]}},"required":["data"]}}}},"400":{"description":"Page type does not support analytics sync"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/sync-status":{"get":{"tags":["Pages"],"summary":"Get page metrics sync status","description":"Returns whether a page metrics sync is in progress and when metrics last synced.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Page metrics sync status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"pageId":{"type":"string"},"syncInProgress":{"type":"boolean"},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}},"required":["pageId","syncInProgress","lastSyncedAt"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages":{"get":{"tags":["Pages"],"summary":"List pages","description":"Returns pages (social channels) the token has access to, with pagination.","parameters":[{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of pages with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"platform":{"type":"string"},"workspaceId":{"type":"string"},"createdAt":{"type":["string","null"],"format":"date-time"},"isConnected":{"type":"boolean"},"profilePicture":{"type":["string","null"]},"link":{"type":["string","null"]}},"required":["id","name","platform","workspaceId","createdAt","isConnected","profilePicture","link"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/metrics":{"get":{"tags":["Pages"],"summary":"Get page metrics","description":"Returns paginated raw page metrics snapshots for a date range.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"startDate","in":"query","required":true,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":true,"schema":{"type":"string","format":"date-time"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":90,"default":30}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Paginated page metrics snapshots","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"pageId":{"type":"string"},"pageType":{"type":"string"},"fetchedAt":{"type":"string","format":"date-time"},"partial":{"type":"boolean"},"facebook":{"type":"object","properties":{"followers":{"type":"number"},"gainedFollowers":{"type":"number"},"posts":{"type":"number"},"engagement":{"type":"number"},"reactions":{"type":"number"},"pageViews":{"type":"number"},"unFollows":{"type":"number"},"views":{"type":"number"},"organic":{"type":"object","properties":{"views":{"type":"number"}},"required":["views"]},"paid":{"type":"object","properties":{"views":{"type":"number"},"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"spendCurrency":{"type":"string"}}},"paidByAdAccount":{"type":"object","additionalProperties":{"type":"object","properties":{"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"spendCurrency":{"type":"string"}},"required":["impressions","clicks","spend"]}},"totalFollowers":{"type":"number"}},"required":["followers","gainedFollowers","posts","engagement","reactions","pageViews","unFollows","views"]},"instagram":{"type":"object","properties":{"gainedFollowers":{"type":"number"},"unFollows":{"type":"number"},"totalFollowers":{"type":"number"},"followersIncomplete":{"type":"boolean"},"impressions":{"type":"number"},"views":{"type":"number"},"reach":{"type":"number"},"accountsReachBreakdown":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"profileViews":{"type":"number"},"posts":{"type":"number"},"engagement":{"type":"number"},"engagementBreakdown":{"type":"object","properties":{"post":{"type":"number"},"reel":{"type":"number"},"ad":{"type":"number"},"story":{"type":"number"},"carousel":{"type":"number"}}},"reachBreakdown":{"type":"object","properties":{"post":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"reel":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"story":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"ad":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]}},"required":["post","reel","story"]},"viewsBreakdown":{"type":"object","properties":{"post":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"reel":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"story":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"ad":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]}},"required":["post","reel","story"]},"viewsAudienceBreakdown":{"type":"object","properties":{"total":{"type":"number"},"followers":{"type":"number"},"nonFollowers":{"type":"number"}},"required":["total","followers","nonFollowers"]},"organic":{"type":"object","properties":{"reach":{"type":"number"},"views":{"type":"number"}}},"paid":{"type":"object","properties":{"reach":{"type":"number"},"views":{"type":"number"},"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"spendCurrency":{"type":"string"}}},"paidByAdAccount":{"type":"object","additionalProperties":{"type":"object","properties":{"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"spendCurrency":{"type":"string"}},"required":["impressions","clicks","spend"]}}},"required":["gainedFollowers","unFollows","reach","posts","engagement"]},"linkedin":{"type":"object","properties":{"followers":{"type":"number"},"paidFollowers":{"type":"number"},"totalFollowers":{"type":"number"},"impressions":{"type":"number"},"engagement":{"type":"number"},"pageInsights":{"type":"number"},"pageViews":{"type":"number"},"posts":{"type":"number"},"reshares":{"type":"number"},"reactions":{"type":"number"},"comments":{"type":"number"},"shareStats":{"type":"object","properties":{"uniqueImpressionsCount":{"type":"number"},"clickCount":{"type":"number"},"engagement":{"type":"number"},"likeCount":{"type":"number"},"commentCount":{"type":"number"},"shareCount":{"type":"number"},"impressionCount":{"type":"number"},"commentMentionsCount":{"type":"number"},"shareMentionsCount":{"type":"number"}},"required":["uniqueImpressionsCount","clickCount","engagement","likeCount","commentCount","shareCount","impressionCount"]},"paid":{"type":"object","properties":{"impressions":{"type":"number"},"engagement":{"type":"number"},"clicks":{"type":"number"},"reactions":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"oneClickLeads":{"type":"number"},"qualifiedLeads":{"type":"number"},"spend":{"type":"number"},"spendCurrency":{"type":"string"}},"required":["impressions","engagement","clicks","reactions","comments","shares","spend"]}},"required":["followers","impressions"]},"tiktok":{"type":"object","properties":{"profile_views":{"type":"number"},"video_views":{"type":"number"},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"followers_count":{"type":"number"},"engagement":{"type":"number"},"videos":{"type":"number"},"paid":{"type":"object","properties":{"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"videoViews":{"type":"number"},"engagement":{"type":"number"},"reach":{"type":"number"},"videoWatched2s":{"type":"number"},"videoWatched6s":{"type":"number"},"videoViewsP25":{"type":"number"},"videoViewsP50":{"type":"number"},"videoViewsP75":{"type":"number"},"videoViewsP100":{"type":"number"},"follows":{"type":"number"},"profileVisits":{"type":"number"},"conversions":{"type":"number"},"spendCurrency":{"type":"string"}},"required":["impressions","clicks","spend","likes","comments","shares","videoViews","engagement","reach","videoWatched2s","videoWatched6s","videoViewsP25","videoViewsP50","videoViewsP75","videoViewsP100","follows","profileVisits","conversions"]},"paidByAdAccount":{"type":"object","additionalProperties":{"type":"object","properties":{"impressions":{"type":"number"},"clicks":{"type":"number"},"spend":{"type":"number"},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"videoViews":{"type":"number"},"engagement":{"type":"number"},"reach":{"type":"number"},"videoWatched2s":{"type":"number"},"videoWatched6s":{"type":"number"},"videoViewsP25":{"type":"number"},"videoViewsP50":{"type":"number"},"videoViewsP75":{"type":"number"},"videoViewsP100":{"type":"number"},"follows":{"type":"number"},"profileVisits":{"type":"number"},"conversions":{"type":"number"},"spendCurrency":{"type":"string"}},"required":["impressions","clicks","spend","likes","comments","shares","videoViews","engagement","reach","videoWatched2s","videoWatched6s","videoViewsP25","videoViewsP50","videoViewsP75","videoViewsP100","follows","profileVisits","conversions"]}}},"required":["profile_views","video_views","likes","comments","shares","followers_count","engagement","videos"]},"threads":{"type":"object","properties":{"views":{"type":"number"},"likes":{"type":"number"},"replies":{"type":"number"},"reposts":{"type":"number"},"quotes":{"type":"number"}},"required":["views","likes","replies","reposts","quotes"]},"googleMyBusiness":{"type":"object","properties":{"posts":{"type":"number"},"callClicks":{"type":"number"},"websiteClicks":{"type":"number"},"impressions":{"type":"number"},"engagement":{"type":"number"},"businessConversations":{"type":"number"},"businessImpressionsMobileSearch":{"type":"number"},"businessImpressionsDesktopMaps":{"type":"number"},"businessImpressionsDesktopSearch":{"type":"number"},"businessImpressionsMobileMaps":{"type":"number"},"businessDirectionRequests":{"type":"number"},"businessBookings":{"type":"number"},"businessFoodOrders":{"type":"number"}},"required":["posts","callClicks","websiteClicks","impressions","engagement","businessConversations","businessImpressionsMobileSearch","businessImpressionsDesktopMaps","businessImpressionsDesktopSearch","businessImpressionsMobileMaps","businessDirectionRequests","businessBookings","businessFoodOrders"]},"youtube":{"type":"object","properties":{"subscribers":{"type":"number"},"totalSubscribers":{"type":"number"},"subscribersGained":{"type":"number"},"subscribersLost":{"type":"number"},"videos":{"type":"number"},"views":{"type":"number"},"estimatedMinutesWatched":{"type":"number"},"comments":{"type":"number"},"likes":{"type":"number"},"dislikes":{"type":"number"},"shares":{"type":"number"},"engagement":{"type":"number"},"averageViewDuration":{"type":"number"}},"required":["subscribers","subscribersGained","subscribersLost","videos","views","estimatedMinutesWatched","comments","likes","dislikes","shares","engagement","averageViewDuration"]}},"required":["pageId","pageType","fetchedAt","partial"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/competitors":{"get":{"tags":["Competitors"],"summary":"List tracked competitors","description":"Lists the competitors tracked for one of your pages. Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Tracked competitors","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"trackedCompetitorId":{"type":"string"},"scrapedPageId":{"type":["string","null"]},"handle":{"type":"string"},"displayName":{"type":"string"},"platform":{"type":"string"},"profileImageUrl":{"type":["string","null"]},"syncStatus":{"type":"string"},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}},"required":["trackedCompetitorId","scrapedPageId","handle","displayName","platform","profileImageUrl","syncStatus","lastSyncedAt"]}}},"required":["data"]}}}},"400":{"description":"Page type does not support competitor analytics"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this page or the Analytics add-on is inactive"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Competitors"],"summary":"Track a competitor","description":"Starts tracking a competitor for one of your pages, identified by @handle or profile URL. Capped at 5 competitors per page. Re-adding an already-tracked competitor is idempotent — it returns 200 with the existing row instead of creating a duplicate. Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1}}}}}},"responses":{"200":{"description":"Competitor was already tracked (idempotent re-add)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"trackedCompetitorId":{"type":"string"},"scrapedPageId":{"type":["string","null"]},"handle":{"type":"string"},"displayName":{"type":"string"},"platform":{"type":"string"},"profileImageUrl":{"type":["string","null"]},"syncStatus":{"type":"string"},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}},"required":["trackedCompetitorId","scrapedPageId","handle","displayName","platform","profileImageUrl","syncStatus","lastSyncedAt"]}},"required":["data"]}}}},"201":{"description":"Competitor is now tracked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"trackedCompetitorId":{"type":"string"},"scrapedPageId":{"type":["string","null"]},"handle":{"type":"string"},"displayName":{"type":"string"},"platform":{"type":"string"},"profileImageUrl":{"type":["string","null"]},"syncStatus":{"type":"string"},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}},"required":["trackedCompetitorId","scrapedPageId","handle","displayName","platform","profileImageUrl","syncStatus","lastSyncedAt"]}},"required":["data"]}}}},"400":{"description":"Missing handle/url, unsupported page type, or the profile is currently unavailable"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the write scope, the Analytics add-on is inactive, or the competitor cap is reached"},"404":{"description":"Page not found, or the handle could not be found on the platform"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/competitors/comparison":{"get":{"tags":["Competitors"],"summary":"Compare your page against its competitors","description":"Your page and its tracked competitors over a window — followers, posts, total and average engagement. Own and competitor engagement use slightly different bases (own = platform-reported, competitor = scraped). Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d","all"],"default":"30d"}},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Own + competitor comparison rows","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"isOwn":{"type":"boolean"},"displayName":{"type":"string"},"handle":{"type":"string"},"platform":{"type":"string"},"profileImageUrl":{"type":["string","null"]},"followers":{"type":["number","null"]},"posts":{"type":["number","null"]},"totalEngagement":{"type":["number","null"]},"avgEngagement":{"type":["number","null"]}},"required":["id","isOwn","displayName","handle","platform","profileImageUrl","followers","posts","totalEngagement","avgEngagement"]}}},"required":["data"]}}}},"400":{"description":"Page type does not support competitor analytics"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this page or the Analytics add-on is inactive"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/competitors/metrics":{"get":{"tags":["Competitors"],"summary":"Follower & engagement trend for your page and its competitors","description":"Daily follower and engagement series for your page and each tracked competitor over a window. Own and competitor engagement use slightly different bases (own = platform-reported, competitor = scraped). Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d","all"],"default":"30d"}},{"name":"scrapedPageIds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"description":"Optional competitor scrapedPageIds filter. Repeat the query param or pass a comma-separated list."},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Own + competitor trend series","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"isOwn":{"type":"boolean"},"handle":{"type":"string"},"displayName":{"type":"string"},"platform":{"type":"string"},"profileImageUrl":{"type":["string","null"]},"points":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date-time"},"followers":{"type":["number","null"]},"engagement":{"type":["number","null"]}},"required":["date","followers","engagement"]}}},"required":["id","isOwn","handle","displayName","platform","profileImageUrl","points"]}}},"required":["data"]}}}},"400":{"description":"Page type does not support competitor analytics"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this page or the Analytics add-on is inactive"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/competitors/top-posts":{"get":{"tags":["Competitors"],"summary":"Top posts across your page's competitors","description":"Top posts across all tracked competitors, merged and ranked by sortBy (descending), each tagged with its competitor. Competitors only — your own posts are available via /posts. Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"sortBy","in":"query","required":true,"schema":{"type":"string","enum":["engagementRate","likes","views"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d","all"],"default":"30d"}},{"name":"scrapedPageIds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"description":"Optional competitor scrapedPageIds filter. Repeat the query param or pass a comma-separated list."},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Top competitor posts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"scrapedPageId":{"type":"string"},"handle":{"type":"string"},"url":{"type":"string"},"content":{"type":["string","null"]},"mediaType":{"type":["string","null"]},"postedAt":{"type":"string","format":"date-time"},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":["number","null"]},"views":{"type":["number","null"]},"engagementRate":{"type":["number","null"]},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["scrapedPageId","handle","url","content","mediaType","postedAt","likes","comments","shares","views","engagementRate","hashtags"]}}},"required":["data"]}}}},"400":{"description":"Validation error or page type does not support competitor analytics"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this page or the Analytics add-on is inactive"},"404":{"description":"Page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pages/{id}/competitors/{scrapedPageId}":{"delete":{"tags":["Competitors"],"summary":"Stop tracking a competitor","description":"Stops tracking a competitor on your page. Re-adding within the cooling window restores its history. Instagram, Facebook, YouTube, TikTok, LinkedIn pages only.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"scrapedPageId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Competitor untracked"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the write scope or the Analytics add-on is inactive"},"404":{"description":"Page not found, or the competitor is not tracked by this page"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords":{"get":{"tags":["Social Listening"],"summary":"List tracked keywords","description":"Lists the keywords tracked for a workspace, optionally filtered by type.","parameters":[{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["brand","topic"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Tracked keywords","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"keywordId":{"type":"string"},"text":{"type":"string"},"type":{"type":"string","enum":["brand","topic"]},"createdAt":{"type":"string","format":"date-time"}},"required":["keywordId","text","type","createdAt"]}}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Social Listening"],"summary":"Track a keyword","description":"Starts tracking a keyword for a workspace. Re-adding an already-tracked keyword is idempotent — it returns 200 with the existing row instead of creating a duplicate. The response contains the keyword object only (no sync state); poll `GET /keywords/{keywordId}/sync-status` until the sync completes, same contract as `POST /pages/{id}/sync` → `GET /pages/{id}/sync-status`.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"keyword":{"type":"string","minLength":1,"maxLength":200},"type":{"type":"string","enum":["brand","topic"],"default":"topic"}},"required":["workspaceId","keyword"]}}}},"responses":{"200":{"description":"Keyword was already tracked (idempotent re-add)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"keywordId":{"type":"string"},"text":{"type":"string"},"type":{"type":"string","enum":["brand","topic"]},"createdAt":{"type":"string","format":"date-time"}},"required":["keywordId","text","type","createdAt"]}},"required":["data"]}}}},"201":{"description":"Keyword is now tracked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"keywordId":{"type":"string"},"text":{"type":"string"},"type":{"type":"string","enum":["brand","topic"]},"createdAt":{"type":"string","format":"date-time"}},"required":["keywordId","text","type","createdAt"]}},"required":["data"]}}}},"400":{"description":"Keyword limit reached, brand limit reached, or type conflict with an existing listener"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the write scope, workspace is outside token scope, or workspace is a sample workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords/{keywordId}":{"delete":{"tags":["Social Listening"],"summary":"Stop tracking a keyword","description":"Stops tracking a keyword on a workspace. Returns 204 when the listener is removed.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"keywordId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Keyword untracked"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the write scope, workspace is outside token scope, or workspace is a sample workspace"},"404":{"description":"Keyword is not tracked by this workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords/{keywordId}/mentions":{"get":{"tags":["Social Listening"],"summary":"List mentions for a tracked keyword","description":"Windowed mentions for a keyword, with optional platform/sentiment filter and sort. Every saved mention is returned. Mentions are returned as a curated, typed shape — common fields plus per-platform metric fields as optional properties.","parameters":[{"name":"keywordId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","14d","30d","90d"],"default":"7d"}},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["twitter","youtube","reddit","tiktok","facebook","instagram"]}},{"name":"sentiment","in":"query","required":false,"schema":{"type":"string","enum":["all","positive","negative","neutral"],"default":"all"}},{"name":"sortBy","in":"query","required":false,"schema":{"type":"string","enum":["engagement","recency"],"default":"engagement"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Mentions for the keyword","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"engagement":{"type":"number"},"sentiment":{"type":"string","enum":["positive","negative","neutral"]},"url":{"type":"string"},"text":{"type":"string"},"author":{"type":"object","properties":{"name":{"type":"string"},"username":{"type":["string","null"]},"profileImageUrl":{"type":["string","null"]}},"required":["name","username","profileImageUrl"]},"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"views":{"type":"number"},"upvotes":{"type":"number"},"replies":{"type":"number"},"retweets":{"type":"number"},"quotes":{"type":"number"},"bookmarks":{"type":"number"},"impressions":{"type":"number"},"plays":{"type":"number"},"saves":{"type":"number"}},"required":["platform","publishedAt","engagement","url","text","author"]}},"pagination":{"type":"object","properties":{"nextCursor":{"type":["number","null"]},"total":{"type":"number"}},"required":["nextCursor","total"]}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this workspace"},"404":{"description":"Keyword is not tracked by this workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords/{keywordId}/metrics/summary":{"get":{"tags":["Social Listening"],"summary":"Aggregated metrics for a tracked keyword","description":"Aggregated mention, engagement, sentiment, and per-platform totals for a keyword over a window. Internal API-spend fields are never exposed.","parameters":[{"name":"keywordId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","14d","30d","90d"],"default":"7d"}},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Aggregated metrics summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"mentions":{"type":"number"},"engagement":{"type":"number"},"sentiment":{"type":"object","properties":{"positive":{"type":"number"},"negative":{"type":"number"},"neutral":{"type":"number"}},"required":["positive","negative","neutral"]},"platformBreakdown":{"type":"object","additionalProperties":{"type":"object","properties":{"mentions":{"type":"number"},"engagement":{"type":"number"}},"required":["mentions","engagement"]}},"daysWithData":{"type":"number"}},"required":["mentions","engagement","sentiment","platformBreakdown","daysWithData"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this workspace"},"404":{"description":"Keyword is not tracked by this workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords/{keywordId}/metrics":{"get":{"tags":["Social Listening"],"summary":"Daily metrics for a tracked keyword","description":"Daily mention, engagement, sentiment, and per-platform breakdown for a keyword over a window. Internal API-spend fields (costs/totalCost) are never exposed.","parameters":[{"name":"keywordId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","14d","30d","90d"],"default":"7d"}},{"name":"startDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Daily metrics series","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date-time"},"mentions":{"type":"number"},"engagement":{"type":"number"},"sentiment":{"type":"object","properties":{"positive":{"type":"number"},"negative":{"type":"number"},"neutral":{"type":"number"}},"required":["positive","negative","neutral"]},"platformBreakdown":{"type":"object","additionalProperties":{"type":"object","properties":{"mentions":{"type":"number"},"engagement":{"type":"number"}},"required":["mentions","engagement"]}}},"required":["date","mentions","engagement","platformBreakdown"]}}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this workspace"},"404":{"description":"Keyword is not tracked by this workspace"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/keywords/{keywordId}/sync-status":{"get":{"tags":["Social Listening"],"summary":"Get keyword sync status","description":"Polls the sync job status for a tracked keyword. After `POST /keywords`, poll this endpoint until `status` is `complete` (or `removed` if the keyword was deleted mid-poll). Mirrors `GET /pages/{id}/sync-status`.","parameters":[{"name":"keywordId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Keyword sync status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"keywordId":{"type":"string"},"status":{"type":"string","enum":["running","complete","removed"]},"totalJobs":{"type":"integer","minimum":0},"completedJobs":{"type":"integer","minimum":0}},"required":["keywordId","status","totalJobs","completedJobs"]}},"required":["data"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token cannot read this workspace"},"404":{"description":"Keyword has a listener but no sync jobs were found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/stories":{"post":{"tags":["Stories"],"summary":"Create a story (single or multi-frame)","description":"Creates a story on a story-capable page (Instagram and Facebook). Provide `media` as a single URL for a one-frame story, or as an array of URLs (max 20) to create a multi-frame story group (one frame per URL, in order). When a multi-frame story is created the response also includes `posts` (every frame, in order) and `group` (the shared story-group id and its post ids). GIFs are not supported. Media is processed asynchronously, so the `media` URL is typically `null` in this response while the upload is still processing — use `mediaId` with GET /media/{id} (or re-fetch the story) to poll `mediaStatus` until it is `success`, at which point the URL becomes available. The `notify` flag controls whether workspace members receive a post-added notification (email/in-app push); set it to `false` to suppress those notifications. Internal activity feed entries are always recorded. `notify` is not an approval request — use POST /posts/{id}/request-approval to notify approvers.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","minLength":1},"pageId":{"type":"string","minLength":1},"media":{"anyOf":[{"type":"string","format":"uri"},{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":20}],"description":"A single media URL creates a one-frame story. An array of media URLs (max 20) creates a multi-frame story group — one frame per URL, in order. GIFs are not supported."},"stickers":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","location","link","music","mention","hashtags","questions","notes","fundraiser","feelings","other"]},"value":{"type":"string"}},"required":["type","value"]},"default":[]},"scheduledAt":{"type":"string","format":"date-time"},"labels":{"type":"array","items":{"type":"string"},"default":[]},"teamOnly":{"type":"boolean"},"approved":{"type":"boolean"},"approvedBy":{"type":"string","minLength":1},"publishAtScheduledDate":{"type":"boolean","default":false},"notify":{"type":"boolean","default":true,"description":"Controls whether workspace members receive a post-added notification (email/in-app push). This is not an approval request — use POST /posts/{id}/request-approval to notify approvers."},"internalNote":{"type":"string","maxLength":8000}},"required":["workspaceId","pageId","media"]}}}},"responses":{"201":{"description":"Story created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string","enum":["story"]},"media":{"type":["string","null"],"format":"uri"},"mediaId":{"type":["string","null"],"description":"Media library id of the attached media. Use with GET /media/{id} to poll its processing status."},"mediaStatus":{"type":["string","null"],"enum":["uploading","processing","error","success"],"description":"Processing status of the attached media. The `media` URL is only populated once this is `success`."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"scheduledSet":{"type":"boolean"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"}},"required":["userId","approvedAt"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","pageId","type","classification","media","mediaId","mediaStatus","scheduledAt","scheduledSet","status","approved","createdAt"]},"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workspaceId":{"type":"string"},"pageId":{"type":"string"},"type":{"type":"string"},"classification":{"type":"string","enum":["story"]},"media":{"type":["string","null"],"format":"uri"},"mediaId":{"type":["string","null"],"description":"Media library id of the attached media. Use with GET /media/{id} to poll its processing status."},"mediaStatus":{"type":["string","null"],"enum":["uploading","processing","error","success"],"description":"Processing status of the attached media. The `media` URL is only populated once this is `success`."},"scheduledAt":{"type":["string","null"],"format":"date-time"},"scheduledSet":{"type":"boolean"},"status":{"type":"string"},"approved":{"type":"boolean"},"approvedBy":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"}},"required":["userId","approvedAt"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","workspaceId","pageId","type","classification","media","mediaId","mediaStatus","scheduledAt","scheduledSet","status","approved","createdAt"]}},"group":{"type":"object","properties":{"id":{"type":"string"},"postIds":{"type":"array","items":{"type":"string"}}},"required":["id","postIds"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workspace or page not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/comments":{"get":{"tags":["Posts"],"summary":"List comments on a post","description":"Returns comments for a post with pagination.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}},{"name":"teamOnly","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of comments with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"postId":{"type":"string"},"text":{"type":"string"},"authorId":{"type":"string"},"teamOnly":{"type":"boolean"},"replyFor":{"type":"string"},"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"emojiId":{"type":"string"},"emojiSkin":{"type":"integer"},"emojiNative":{"type":"string"},"users":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"userName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["userId"]}}},"required":["emoji","emojiId","emojiSkin","emojiNative","users"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","postId","text","authorId","teamOnly","reactions","createdAt"]}},"pagination":{"type":"object","properties":{"offset":{"type":"number"},"limit":{"type":"number"},"hasMore":{"type":"boolean"}},"required":["offset","limit","hasMore"]}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Posts"],"summary":"Add a comment to a post","description":"Creates a new comment on a post. Pass replyToCommentId to create a threaded reply to an existing comment on the same post.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1},"teamOnly":{"type":"boolean","default":false},"replyToCommentId":{"type":"string","minLength":1}},"required":["text"]}}}},"responses":{"201":{"description":"Comment created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"postId":{"type":"string"},"text":{"type":"string"},"authorId":{"type":"string"},"teamOnly":{"type":"boolean"},"replyFor":{"type":"string"},"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"emojiId":{"type":"string"},"emojiSkin":{"type":"integer"},"emojiNative":{"type":"string"},"users":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"userName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["userId"]}}},"required":["emoji","emojiId","emojiSkin","emojiNative","users"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","postId","text","authorId","teamOnly","reactions","createdAt"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/comments/{commentId}":{"patch":{"tags":["Posts"],"summary":"Update a comment on a post","description":"Updates the text of a comment. Only the comment author (the user who created the API token) can edit it.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":8000}},"required":["text"]}}}},"responses":{"200":{"description":"Comment updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"postId":{"type":"string"},"text":{"type":"string"},"authorId":{"type":"string"},"teamOnly":{"type":"boolean"},"replyFor":{"type":"string"},"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"emojiId":{"type":"string"},"emojiSkin":{"type":"integer"},"emojiNative":{"type":"string"},"users":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"userName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["userId"]}}},"required":["emoji","emojiId","emojiSkin","emojiNative","users"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","postId","text","authorId","teamOnly","reactions","createdAt"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Only the comment author can edit it"},"404":{"description":"Post or comment not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Posts"],"summary":"Delete a comment from a post","description":"Deletes a comment and its replies. Only the comment author (the user who created the API token) can delete it.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Comment deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Only the comment author can delete it"},"404":{"description":"Post or comment not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/posts/{id}/comments/{commentId}/reactions":{"post":{"tags":["Posts"],"summary":"Toggle a reaction on a comment","description":"Adds the token user emoji reaction to a comment. Toggle semantics: sending the same emoji again removes the reaction. Returns the updated reactions of the comment.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"emoji":{"type":"string","minLength":1},"emojiId":{"type":"string","minLength":1},"emojiSkin":{"anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]},{"type":"number","enum":[4]},{"type":"number","enum":[5]},{"type":"number","enum":[6]}]},"emojiNative":{"type":"string","minLength":1}},"required":["emoji","emojiId","emojiSkin","emojiNative"]}}}},"responses":{"200":{"description":"Updated reactions of the comment","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"emojiId":{"type":"string"},"emojiSkin":{"type":"integer"},"emojiNative":{"type":"string"},"users":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"userName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["userId"]}}},"required":["emoji","emojiId","emojiSkin","emojiNative","users"]}}},"required":["reactions"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Post or comment not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/workspaces":{"get":{"tags":["Workspaces"],"summary":"List workspaces","description":"Returns all workspaces the token has access to.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of workspaces","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"companyId":{"type":"string"},"timezone":{"type":"string"},"websiteUrl":{"type":["string","null"]},"approvalSettings":{"anyOf":[{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["MULTIPLE"]},"approvalLevels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approversIds":{"type":"array","items":{"type":"string"}}},"required":["id","label","approversIds"]}}},"required":["type"]}]},{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED"]}},"required":["type"]}]}]},"defaultTeamOnlyPosts":{"type":"boolean"},"hideEmailsFromClients":{"type":"boolean"},"labels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","color","name"]}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","companyId","timezone","websiteUrl","approvalSettings","defaultTeamOnlyPosts","hideEmailsFromClients","labels","createdAt","updatedAt"]}}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Workspaces"],"summary":"Create a workspace","description":"Creates a new workspace in the calling token's company.","security":[{"bearerAuth":["write"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"timezone":{"type":"string"},"approvalSettings":{"anyOf":[{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["MULTIPLE"]},"approvalLevels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approversIds":{"type":"array","items":{"type":"string"}}},"required":["id","label","approversIds"]}}},"required":["type"]}]},{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED"]}},"required":["type"]}]}]},"websiteUrl":{"type":"string","maxLength":2048}},"required":["name","timezone","approvalSettings"]}}}},"responses":{"201":{"description":"Workspace created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"companyId":{"type":"string"},"websiteUrl":{"type":["string","null"]},"approvalSettings":{"anyOf":[{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["MULTIPLE"]},"approvalLevels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"approversIds":{"type":"array","items":{"type":"string"}}},"required":["id","label","approversIds"]}}},"required":["type"]}]},{"allOf":[{"type":"object","properties":{"autoSchedule":{"type":"boolean"},"autoLock":{"type":"boolean"},"sendReminders":{"type":"boolean"}},"required":["autoSchedule","autoLock"]},{"type":"object","properties":{"type":{"type":"string","enum":["NONE","OPTIONAL","REQUIRED"]}},"required":["type"]}]}]},"defaultTeamOnlyPosts":{"type":"boolean"},"hideEmailsFromClients":{"type":"boolean"},"labels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"color":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","color","name"]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","timezone","companyId","websiteUrl","approvalSettings","defaultTeamOnlyPosts","hideEmailsFromClients","labels","createdAt"]}},"required":["data"]}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Workspace limit reached or insufficient permissions"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/workspaces/{id}":{"delete":{"tags":["Workspaces"],"summary":"Delete a workspace","description":"Deletes a workspace in the company associated with the calling token.","security":[{"bearerAuth":["write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Workspace deleted"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden"},"404":{"description":"Workspace not found"},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}