{"openapi":"3.1.0","info":{"title":"Trawline API","version":"1.0.0","description":"Social-media data API. Public, logged-out data only. Stable versioned JSON (v1). Every credit price is a config fact; every uptime number at /api/status is measured, not promised. 5 of 52 services Live across 2 platforms."},"servers":[{"url":"https://trawline.dev"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"trw_ API key"}},"schemas":{"Meta":{"type":"object","properties":{"fetchedAt":{"type":"string","format":"date-time"},"cached":{"type":"boolean"}},"required":["fetchedAt"]},"Note":{"type":"object","description":"Explains an absent field or a caveat on the data — e.g. a metric the platform withholds from public (logged-out) requests. `code` is stable for programmatic handling; `message` is human-readable.","properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"LegacyEnvelopeError":{"type":"object","description":"The envelope shape WITHOUT a guaranteed `retryable`. Sent by the service-unavailable answers on the metered path. Treat a missing `retryable` as unknown, not as false.","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string"},"retryable":{"type":"boolean"},"message":{"type":"string"}},"required":["code"]},"billing_receipt_id":{"type":"string","description":"Quote this if you contact support."},"billing_status":{"type":"string","enum":["unknown"]}},"required":["ok","error"]},"RefusalError":{"type":"object","description":"The FLAT one of THREE error shapes this API returns (the others are `Error`, whose nested `retryable` is required, and `LegacyEnvelopeError`, whose `retryable` is absent on several 503s). Here `error` is a stable string slug, not an object. It is sent by most pre-routing refusals (bad or revoked key, rate limit, insufficient credits, unknown endpoint, an unbound service). It is NOT universal: some 402 and 503 answers use the `Error` envelope instead, which is why those statuses are documented as a oneOf. `message` is absent on the insufficient-credits 402, which carries `credits_remaining` and `cost` instead.","properties":{"error":{"type":"string","description":"Stable slug, e.g. invalid_key, key_revoked, rate_limited, insufficient_credits."},"message":{"type":"string"},"credits_remaining":{"type":"integer","description":"Present on 402 only."},"cost":{"type":"integer","description":"Present on 402 only: what the call would have cost."},"retry_after_seconds":{"type":"integer","description":"Present when a key is paused for repeated failures."}},"required":["error"]},"Error":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string"},"retryable":{"type":"boolean"},"message":{"type":"string"}},"required":["code","retryable"]}},"required":["ok","error"]},"ProfileData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"displayName":{"type":"string"},"url":{"type":"string","minLength":1},"followerCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isPartner":{"type":"boolean"},"isAffiliate":{"type":"boolean"},"profileImageUrl":{"type":"string","minLength":1},"bannerImageUrl":{"type":"string","minLength":1},"team":{"type":"object","properties":{"name":{"type":"string","minLength":1},"displayName":{"type":"string"}},"required":["name","displayName"],"additionalProperties":false},"socialLinks":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"url":{"type":"string","minLength":1}},"required":["platform","url"],"additionalProperties":false}},"followingCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"postCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"verified":{"type":"boolean"},"description":{"type":"string"},"category":{"type":"string"}},"required":["platform","fetchedAt","handle","displayName","url"],"additionalProperties":false},"StatsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"author":{"type":"string"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"shareCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["platform","fetchedAt","id","url"],"additionalProperties":false},"CommentsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"string","minLength":1},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"author":{"type":"string"},"text":{"type":"string"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","author","text"],"additionalProperties":false}}},"required":["platform","fetchedAt","id","comments"],"additionalProperties":false},"ChannelStatsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"subscriberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"videoCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalViews":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalLikes":{"type":"integer","minimum":0,"maximum":9007199254740991},"isLive":{"type":"boolean"},"live":{"type":"object","properties":{"title":{"type":"string"},"viewers":{"type":"integer","minimum":0,"maximum":9007199254740991},"game":{"type":"string"},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"language":{"type":"string"}},"required":["title"],"additionalProperties":false},"latestBroadcast":{"type":"object","properties":{"title":{"type":"string"},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"game":{"type":"string"}},"required":["title"],"additionalProperties":false}},"required":["platform","fetchedAt","handle","url"],"additionalProperties":false},"ChannelPostsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"caption":{"type":"string"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"thumbnail":{"type":"string","minLength":1}},"required":["id","url","caption"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","handle","url","posts"],"additionalProperties":false},"ChannelReelsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"reels":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"caption":{"type":"string"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"thumbnail":{"type":"string","minLength":1}},"required":["id","url","caption"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","handle","url","reels"],"additionalProperties":false},"ChannelVideosData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"videos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"durationSeconds":{"type":"number"},"thumbnail":{"type":"string","minLength":1},"publishedText":{"type":"string"}},"required":["id","url","title"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","handle","url","videos"],"additionalProperties":false},"ChannelClipsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"clips":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"durationSeconds":{"type":"number"},"thumbnail":{"type":"string","minLength":1},"publishedText":{"type":"string"}},"required":["id","url","title"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","handle","url","clips"],"additionalProperties":false},"TweetsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"handle":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"tweets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"text":{"type":"string"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"replyCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"retweetCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"quoteCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","url","text"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","handle","url","tweets"],"additionalProperties":false},"TranscriptData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"language":{"type":"string","minLength":1},"source":{"type":"string","enum":["caption","asr"]},"durationSeconds":{"type":"number"},"segments":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["start","end","text"],"additionalProperties":false}},"text":{"type":"string"}},"required":["platform","fetchedAt","id","url","language","source","durationSeconds","segments","text"],"additionalProperties":false},"SummarizeData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sourceId":{"type":"string","minLength":1},"summary":{"type":"string"},"keyPoints":{"type":"array","items":{"type":"string"}},"depth":{"type":"string","enum":["brief","chaptered"]},"chapters":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1},"startSeconds":{"type":"number","minimum":0},"summary":{"type":"string","minLength":1},"keyPoints":{"type":"array","items":{"type":"string"}}},"required":["title","startSeconds","summary","keyPoints"],"additionalProperties":false}},"tone":{"type":"string"},"targetAudience":{"type":"string"},"aiAnalysis":{"type":"string"},"disclaimer":{"type":"string","minLength":1}},"required":["platform","fetchedAt","sourceId","summary","keyPoints","depth","disclaimer"],"additionalProperties":false},"SearchData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"query":{"type":"string"},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"durationSeconds":{"type":"number"},"thumbnail":{"type":"string","minLength":1},"publishedText":{"type":"string"}},"required":["id","url","title"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","query","results"],"additionalProperties":false},"HashtagSearchData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"hashtag":{"type":"string","minLength":1},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"durationSeconds":{"type":"number"},"thumbnail":{"type":"string","minLength":1},"publishedText":{"type":"string"}},"required":["id","url","title"],"additionalProperties":false}},"nextCursor":{"type":"string"}},"required":["platform","fetchedAt","hashtag","results"],"additionalProperties":false},"TrendsData":{"type":"object","properties":{"platform":{"type":"string","minLength":1},"fetchedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"region":{"type":"string"},"category":{"type":"string"},"trends":{"type":"array","items":{"type":"object","properties":{"term":{"type":"string","minLength":1},"rank":{"type":"integer","minimum":0,"maximum":9007199254740991},"score":{"type":"number"}},"required":["term","rank"],"additionalProperties":false}},"videos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"title":{"type":"string"},"author":{"type":"string"},"publishedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isVideo":{"type":"boolean"},"likeCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"commentCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"viewCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"durationSeconds":{"type":"number"},"thumbnail":{"type":"string","minLength":1},"publishedText":{"type":"string"}},"required":["id","url","title"],"additionalProperties":false}}},"required":["platform","fetchedAt"],"additionalProperties":false}}},"paths":{"/api/v1/{platform}/profile":{"post":{"operationId":"profile","summary":"Profile — 1 credit","description":"Profile (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost). Twitch only: alongside the shared fields, a Twitch profile also returns createdAt (when the channel was created), isPartner and isAffiliate (Twitch programme status), profileImageUrl and bannerImageUrl, team (the channel's primary Twitch team, when it belongs to one), and socialLinks — the channel's own links to other major public platforms, each as {platform, url}. Links to destinations outside that set (link aggregators, chat invites, shorteners, personal sites) are not returned, and when any were dropped the response carries a note saying how many. Each of these fields is omitted when Twitch does not publish it for that channel.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","x","twitch","threads"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["profile"]},"data":{"$ref":"#/components/schemas/ProfileData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/stats":{"post":{"operationId":"stats","summary":"Stats — 1 credit","description":"Stats (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","x","twitch","threads"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["stats"]},"data":{"$ref":"#/components/schemas/StatsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/comments":{"post":{"operationId":"comments","summary":"Comments — 1 credit","description":"Comments (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost). Facebook: reads publicly available, logged-out comment data; because that data comes from Facebook's own public surfaces and rate controls — which vary request-to-request and are outside our control — a request may occasionally return no comments even for a video that has them; we retry automatically to maximise success; when we cannot retrieve the data the request is NOT charged (fail-closed); a request that succeeds but finds no public comments is returned as an honest empty result. Twitch: returns a past broadcast's (VOD) chat replay, capped to a recent window of messages; pass a VOD URL for a specific stream or a channel handle for its latest broadcast (Twitch deletes VODs after a few weeks, so an expired stream returns not-found).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["comments"]},"data":{"$ref":"#/components/schemas/CommentsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/channel_stats":{"post":{"operationId":"channel_stats","summary":"Channel Stats — 1 credit","description":"Channel Stats (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost). Twitch only: alongside the shared fields, a Twitch channel also returns videoCount, isLive, live (the stream currently on air — title, viewers, game, startedAt, language) and latestBroadcast (title, startedAt, game). Live figures change minute to minute; each answer is a snapshot taken at `fetchedAt`. Note that on Twitch subscriberCount holds the channel's PUBLIC FOLLOWER count: Twitch does not expose paid-subscriber totals to public requests, and every successful response says so in a note rather than leaving the shared field name to be read as a paid-subscriber number.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["channel_stats"]},"data":{"$ref":"#/components/schemas/ChannelStatsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/channel_posts":{"post":{"operationId":"channel_posts","summary":"Channel Posts — 1 credit","description":"Channel Posts (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["instagram","facebook"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["channel_posts"]},"data":{"$ref":"#/components/schemas/ChannelPostsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/channel_reels":{"post":{"operationId":"channel_reels","summary":"Channel Reels — 1 credit","description":"Channel Reels (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["instagram"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["channel_reels"]},"data":{"$ref":"#/components/schemas/ChannelReelsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/channel_videos":{"post":{"operationId":"channel_videos","summary":"Channel Videos — 1 credit","description":"Channel Videos (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","facebook","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["channel_videos"]},"data":{"$ref":"#/components/schemas/ChannelVideosData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/channel_clips":{"post":{"operationId":"channel_clips","summary":"Channel Clips — 1 credit","description":"Channel Clips (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost). Twitch: returns a channel's most-watched public clips for the requested period (day/week/month/all-time), most-recent page first.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["channel_clips"]},"data":{"$ref":"#/components/schemas/ChannelClipsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/tweets":{"post":{"operationId":"tweets","summary":"Tweets — 1 credit","description":"Tweets (in production validation). Costs 1 credit. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["x"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["tweets"]},"data":{"$ref":"#/components/schemas/TweetsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/transcript":{"post":{"operationId":"transcript","summary":"Transcript — 1 credit per started minute","description":"Transcript (in production validation). Costs 1 credit per started minute. Cached responses still charge (credits price the answer, not our cost). Billed per started minute of the video. A single call is capped at 60 credits by default to prevent an unexpectedly large charge; a longer video is declined with HTTP 402 (code spend_limit_exceeded, 0 charge) unless you raise the ceiling by sending a higher `maxCredits` value in the request.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","x","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["transcript"]},"data":{"$ref":"#/components/schemas/TranscriptData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/summarize":{"post":{"operationId":"summarize","summary":"Summarize — 2 credits","description":"Summarize (in production validation). Costs 2 credits. Cached responses still charge (credits price the answer, not our cost). Flat price regardless of video length.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","x","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["summarize"]},"data":{"$ref":"#/components/schemas/SummarizeData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/search":{"post":{"operationId":"search","summary":"Search — 2 credits","description":"Search (in production validation). Costs 2 credits. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube","tiktok","instagram","facebook","twitch"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["search"]},"data":{"$ref":"#/components/schemas/SearchData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/hashtag_search":{"post":{"operationId":"hashtag_search","summary":"Hashtag Search — 2 credits","description":"Hashtag Search (in production validation). Costs 2 credits. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["tiktok"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["hashtag_search"]},"data":{"$ref":"#/components/schemas/HashtagSearchData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/{platform}/trends":{"post":{"operationId":"trends","summary":"Trends — 2 credits","description":"Trends (in production validation). Costs 2 credits. Cached responses still charge (credits price the answer, not our cost).","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["youtube"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"object"},"opts":{"type":"object","properties":{"maxCredits":{"type":"integer","minimum":1,"description":"Per-call credit ceiling. If this call would cost more (only a long transcript can), it is declined at 0 charge with code spend_limit_exceeded. Defaults to 60."}}}}}}}},"responses":{"200":{"description":"Normalized result","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"platform":{"type":"string"},"endpoint":{"type":"string","enum":["trends"]},"data":{"$ref":"#/components/schemas/TrendsData"},"meta":{"$ref":"#/components/schemas/Meta"},"notes":{"type":"array","items":{"$ref":"#/components/schemas/Note"}}},"required":["ok","platform","endpoint","data","meta"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"402":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Insufficient credits (flat shape, no message, carries credits_remaining and cost), OR the call exceeds the per-call spend limit (envelope shape, code spend_limit_exceeded — resend with a higher maxCredits). Nothing is charged either way.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Temporarily unavailable. Flat shape when a service or binding is unavailable before routing; an envelope WITHOUT a guaranteed `retryable` when the failure happens after it.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/LegacyEnvelopeError"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/billing/receipts/{receipt_id}":{"get":{"operationId":"getBillingReceipt","summary":"Look up what one request did to your credits. Costs 0 credits.","description":"Every API response carries an `x-request-id` header. For a metered call that id is also the billing identifier, so passing it here returns the durable outcome of that one call: whether it is still open, what it settled for, or that it was released with no charge. An id that is still open reports `credits_charged: null` — meaning not yet decided, NOT zero. If the billing status cannot be established, this answers 503 rather than implying no charge. Receipts are scoped to the authenticated key's owner; another account's id is indistinguishable from one that does not exist.","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string"},"description":"The `x-request-id` from the response you are asking about."}],"responses":{"200":{"description":"The durable billing outcome of that request.","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"receipt_id":{"type":"string"},"status":{"type":"string","enum":["open","settled","released","cancelled_unreserved"]},"credits_charged":{"type":["integer","null"],"description":"Credits actually taken. `null` while the call is still open — not yet known, not zero."},"credits_held":{"type":"integer","description":"Credits reserved while the call runs."}},"required":["ok","receipt_id","status","credits_charged","credits_held"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"404":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"No receipt with that id for this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Receipts are read-only; use GET","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"description":"The billing status cannot be confirmed right now. This is NOT a statement that you were not charged. Flat shape if the gateway was unavailable before the lookup ran; envelope shape from the lookup itself.","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/account/credits":{"get":{"operationId":"getAccountCredits","summary":"Your remaining credit balance. Costs 0 credits.","description":"Returns the authenticated key owner's current credit balance — the same figure every metered call is judged against. It is scoped to the key you authenticate with; there is no parameter that could name another account. A `0` here is a real answer meaning you are out of credits. If the balance cannot be established, this answers 503 rather than reporting a zero it did not read.","responses":{"200":{"description":"The current balance.","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"credits_remaining":{"type":"integer","description":"Credits available now. Zero is a real answer, never a placeholder for an unknown."}},"required":["ok","credits_remaining"]}}}},"401":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"403":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The key exists but is revoked or suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"405":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"The balance is read-only; use GET","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusalError"}}}},"503":{"description":"The balance cannot be established right now. This is NOT a statement that you have no credits. Flat shape if the gateway was unavailable before the read ran; envelope shape from the read itself.","headers":{"x-request-id":{"description":"Server-generated identifier for this request. For a metered call it is also the billing identifier — pass it to /api/v1/billing/receipts/{receipt_id} to see what the call did to your credits. A value you send is ignored; we always generate our own.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RefusalError"},{"$ref":"#/components/schemas/Error"}]}}}}},"security":[{"bearerAuth":[]}]}}}}