{"openapi":"3.1.0","info":{"title":"Postgale Publishing API","version":"1.1.0","description":"Authenticate with `Authorization: Bearer sk_...`. Keys are rate limited (default 60 requests/minute). Posts may be held for human approval when enabled for the organization, account, or API key; approval is dashboard-only. Webhooks are signed: HMAC-SHA256(secret, `${X-SocialAPI-Timestamp}.${body}`) hex in X-SocialAPI-Signature; reject timestamps older than 5 minutes."},"servers":[{"url":"/api/v1"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}}}}},"Target":{"type":"object","required":["accountId"],"properties":{"accountId":{"type":"string"},"platform":{"type":"string","enum":["reddit","instagram","tiktok","x","linkedin","facebook"],"description":"Optional; must match the account"},"platformSpecificData":{"type":"object","description":"reddit: subreddit (required live), title, url, flairId. instagram: mediaUrl (public https, e.g. an uploaded media publicUrl; images must be JPEG), mediaType IMAGE|VIDEO (Reel)|STORIES|CAROUSEL (mediaUrls, 2-10 items). tiktok: privacyLevel (required; one of the creator's options; SELF_ONLY until the app is audited), mediaUrl or mediaUrls (verified URL prefix, e.g. uploaded media publicUrl), mediaType video|image, disableComment, disableDuet, disableStitch (interactions are off unless set to false), brandContent (paid partnership; not SELF_ONLY), brandOrganic (your brand)."}}},"Media":{"type":"object","properties":{"id":{"type":"string"},"postId":{"type":["string","null"]},"fileName":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"publicUrl":{"type":["string","null"],"description":"Public https URL of the stored file when object storage is configured (null otherwise). Pass it as platformSpecificData.mediaUrl/mediaUrls for Instagram and TikTok."}}},"NewPost":{"type":"object","required":["content","platforms"],"properties":{"content":{"type":"string","maxLength":40000},"platforms":{"type":"array","minItems":1,"maxItems":20,"items":{"$ref":"#/components/schemas/Target"}},"scheduledFor":{"type":"string","format":"date-time"},"publishNow":{"type":"boolean"}}},"PostTarget":{"type":"object","properties":{"id":{"type":"string"},"accountId":{"type":"string"},"platform":{"type":"string"},"status":{"type":"string","enum":["pending","publishing","published","failed"]},"platformPostId":{"type":["string","null"]},"url":{"type":["string","null"]},"error":{"type":["string","null"]},"attempts":{"type":"integer"}}},"Post":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","pending_approval","queued","publishing","published","partial","failed","rejected"]},"scheduledFor":{"type":["string","null"],"format":"date-time"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/PostTarget"}}}}}},"security":[{"BearerAuth":[]}],"paths":{"/accounts":{"get":{"summary":"List connected social accounts","responses":{"200":{"description":"Accounts"},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/connect/{platform}":{"get":{"summary":"Get an OAuth authorization URL for the account owner (valid 10 minutes, single use)","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["reddit","instagram","tiktok"]}}],"responses":{"200":{"description":"{authUrl, expiresInSeconds}"},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media":{"post":{"summary":"Upload media (multipart file, base64 JSON, or public URL import)","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"base64":{"type":"string"},"fileName":{"type":"string"},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif","video/mp4","video/quicktime"]}}}}}},"responses":{"201":{"description":"{media}; media.publicUrl can be used as mediaUrl/mediaUrls","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"$ref":"#/components/schemas/Media"}}}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"summary":"List uploaded media (newest 200)","responses":{"200":{"description":"{media}","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"}}}}}}}}}},"/media/{id}":{"get":{"summary":"Get uploaded media, including publicUrl","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{media}","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"$ref":"#/components/schemas/Media"}}}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts":{"get":{"summary":"List recent posts (max 100)","parameters":[{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"{posts}"}}},"post":{"summary":"Create a post","parameters":[{"name":"x-request-id","in":"header","description":"Idempotency key","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewPost"}}}},"responses":{"200":{"description":"Idempotent replay"},"201":{"description":"{post}","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts/{id}":{"get":{"summary":"Get post","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{post}"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Edit content (re-queues approval if previously approved)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"}}}}}},"responses":{"200":{"description":"{post}"},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete post record","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{deleted}"}}}},"/posts/{id}/publish":{"post":{"summary":"Publish post now","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{status}"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/posts/{id}/comments":{"get":{"summary":"List comments on published targets","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{comments}"}}}},"/comments/{id}/reply":{"post":{"summary":"Reply to a comment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["platformPostId","text"],"properties":{"platformPostId":{"type":"string"},"text":{"type":"string"}}}}}},"responses":{"200":{"description":"{ok}"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"summary":"List webhooks","responses":{"200":{"description":"{webhooks}"}}},"post":{"summary":"Create webhook (secret returned once)","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"Public https URL"},"events":{"type":"array","items":{"type":"string","enum":["post.published","post.failed","post.pending_approval","post.approved","post.rejected"]}}}}}}},"responses":{"201":{"description":"{webhook}"},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete webhook","parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{deleted}"}}}}}}