{"openapi":"3.0.3","info":{"title":"Toucora API","version":"1.0.0","description":"Extract structured YouTube transcripts, batches, playlists, channels, async jobs and AI results.\n\nAuthenticate with an API key via `Authorization: Bearer YOUR_API_KEY` (or `X-API-Key`). Account, key and webhook management use a session cookie created by `POST /api/auth/login`. Job webhooks deliver `job.completed` and `job.failed` events and are signed with `X-Toucora-Signature`.","contact":{"name":"Toucora"}},"servers":[{"url":"https://toucora.com","description":"This deployment"}],"tags":[{"name":"Transcripts"},{"name":"AI"},{"name":"Jobs"},{"name":"Playlists"},{"name":"Channels"},{"name":"Usage"},{"name":"Account"},{"name":"Auth"},{"name":"Meta"},{"name":"MCP"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key: Authorization: Bearer YOUR_API_KEY"},"sessionCookie":{"type":"apiKey","in":"cookie","name":"session","description":"Session cookie set by /api/auth/login."}},"schemas":{"Transcript":{"type":"object","properties":{"video_id":{"type":"string"},"title":{"type":"string","nullable":true},"channel":{"type":"string","nullable":true},"channel_id":{"type":"string","nullable":true},"url":{"type":"string"},"duration":{"type":"integer","nullable":true},"language":{"type":"string","nullable":true},"requested_language":{"type":"string","nullable":true},"source":{"type":"string","enum":["manual","youtube_auto","translated","asr"]},"segment_count":{"type":"integer"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}}},"Segment":{"type":"object","properties":{"text":{"type":"string"},"start":{"type":"number","description":"Start time in seconds"},"duration":{"type":"number"}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"object","nullable":true,"additionalProperties":true}}}}},"Job":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["batch","playlist","channel"]},"status":{"type":"string","enum":["queued","processing","completed","completed_with_errors","failed","cancelled"]},"total_items":{"type":"integer"},"completed_items":{"type":"integer"},"failed_items":{"type":"integer"},"webhook_url":{"type":"string","nullable":true},"created_at":{"type":"string"},"updated_at":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/JobItem"}}}},"JobItem":{"type":"object","properties":{"id":{"type":"string"},"job_id":{"type":"string"},"video_id":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"status":{"type":"string","enum":["queued","processing","complete","failed","cancelled"]},"language":{"type":"string","nullable":true},"error_code":{"type":"string","nullable":true},"error_message":{"type":"string","nullable":true},"attempts":{"type":"integer"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key_prefix":{"type":"string"},"created_at":{"type":"string"},"last_used_at":{"type":"string","nullable":true},"revoked_at":{"type":"string","nullable":true},"fullKey":{"type":"string","description":"Only returned once, at creation time."}}},"Plan":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"monthly_price_cents":{"type":"integer"},"price_label":{"type":"string"},"credits":{"type":"integer"},"rate_limit_per_min":{"type":"integer"},"features":{"type":"array","items":{"type":"string"}}}},"UsageSummary":{"type":"object","properties":{"requests":{"type":"integer"},"successful":{"type":"integer"},"failed":{"type":"integer"},"credits_used":{"type":"integer"},"by_kind":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"count":{"type":"integer"},"credits":{"type":"integer"}}}},"daily":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"count":{"type":"integer"}}}}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["job.completed","job.failed"]}},"active":{"type":"boolean"},"created_at":{"type":"string"}}}}},"security":[{"bearerAuth":[]}],"paths":{"/v1/transcripts/{videoId}":{"get":{"tags":["Transcripts"],"summary":"Get a single transcript","parameters":[{"name":"videoId","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","schema":{"type":"string"},"description":"Language code, e.g. en, es, de"},{"name":"format","in":"query","schema":{"type":"string","enum":["json","txt","srt","vtt","markdown","md"]}},{"name":"timestamps","in":"query","schema":{"type":"boolean","default":false},"description":"Prefix each txt line with its timestamp. txt drops timestamps by default."},{"name":"clean","in":"query","schema":{"type":"boolean","default":false},"description":"Strip musical note symbols and non-speech cues like [Music], (laughs)."},{"name":"body","in":"query","schema":{"type":"boolean"},"description":"Set to true to force the formatted body."}],"responses":{"200":{"description":"Transcript as JSON (default) or the requested text format.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transcript"}},"text/plain":{"schema":{"type":"string"}},"application/x-subrip":{"schema":{"type":"string"}},"text/vtt":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}}},"headers":{"X-Transcript-Language":{"schema":{"type":"string"}},"X-Transcript-Source":{"schema":{"type":"string"}},"X-Credits-Charged":{"schema":{"type":"integer"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found or no transcript","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transcripts/{videoId}/raw":{"get":{"tags":["Transcripts"],"summary":"Get the raw internal transcript object","parameters":[{"name":"videoId","in":"path","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","schema":{"type":"string"},"description":"Language code, e.g. en, es, de"}],"responses":{"200":{"description":"Raw transcript","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transcripts/{videoId}/languages":{"get":{"tags":["Transcripts"],"summary":"List available caption languages","parameters":[{"name":"videoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Available languages","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"available":{"type":"array","items":{"type":"string"}},"default":{"type":"string","nullable":true},"has_captions":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transcripts":{"post":{"tags":["Transcripts"],"summary":"Batch transcripts (max 50)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"},"maxItems":50},"lang":{"type":"string"},"clean":{"type":"boolean","description":"Strip musical note symbols and non-speech cues from each transcript."}},"required":["ids"]}}}},"responses":{"200":{"description":"Per-item results","content":{"application/json":{"schema":{"type":"object","properties":{"requested":{"type":"integer"},"succeeded":{"type":"integer"},"failed":{"type":"integer"},"credits_charged":{"type":"integer"},"results":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ai/status":{"get":{"tags":["AI"],"summary":"Whether AI-backed responses are enabled","responses":{"200":{"description":"AI status","content":{"application/json":{"schema":{"type":"object","properties":{"ai_enabled":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/ask":{"post":{"tags":["AI"],"summary":"Ask a question grounded in the transcript","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"question":{"type":"string"},"output_lang":{"type":"string","description":"Language to write the AI response in (mirrors the consumer site), e.g. en, es, de."}},"required":["question"]}}}},"responses":{"200":{"description":"Answer with timestamp citations","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"question":{"type":"string"},"answer":{"type":"string"},"citations":{"type":"array","items":{"type":"object","additionalProperties":true}},"grounded":{"type":"boolean"},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/summarize":{"post":{"tags":["AI"],"summary":"Summarize a transcript","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"length":{"type":"string","enum":["short","medium","detailed"]},"output_lang":{"type":"string","description":"Language to write the AI response in (mirrors the consumer site), e.g. en, es, de."}},"required":[]}}}},"responses":{"200":{"description":"Summary","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"length":{"type":"string"},"summary":{"type":"string"},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/chapters":{"post":{"tags":["AI"],"summary":"Generate timestamped chapters","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"output_lang":{"type":"string","description":"Language to write the AI response in (mirrors the consumer site), e.g. en, es, de."}},"required":[]}}}},"responses":{"200":{"description":"Chapters","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"chapters":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"timestamp":{"type":"string"},"title":{"type":"string"}}}},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/search":{"post":{"tags":["AI"],"summary":"Search within a transcript","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"query":{"type":"string"},"limit":{"type":"integer"}},"required":["query"]}}}},"responses":{"200":{"description":"Timestamped matches","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"query":{"type":"string"},"results":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"timestamp":{"type":"string"},"text":{"type":"string"},"score":{"type":"number"}}}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/quotes":{"post":{"tags":["AI"],"summary":"Extract notable quotes","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"}},"required":[]}}}},"responses":{"200":{"description":"Quotes","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"timestamp":{"type":"string"},"text":{"type":"string"}}}},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/repurpose":{"post":{"tags":["AI"],"summary":"Repurpose a transcript into another format","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"format":{"type":"string","enum":["blog","newsletter","linkedin","x_thread","youtube_description","show_notes"]},"output_lang":{"type":"string","description":"Language to write the AI response in (mirrors the consumer site), e.g. en, es, de."}},"required":[]}}}},"responses":{"200":{"description":"Repurposed content","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"format":{"type":"string"},"content":{"type":"string"},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/clips":{"post":{"tags":["AI"],"summary":"Find candidate short-form clips","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"}},"required":[]}}}},"responses":{"200":{"description":"Clips","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"clips":{"type":"array","items":{"type":"object","additionalProperties":true}},"model":{"type":"string","nullable":true},"fallback":{"type":"boolean"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/translate":{"post":{"tags":["AI"],"summary":"Translate a transcript and preserve segment timings","description":"Translate a transcript into one of the supported languages. `mode`: \"original\" returns the source text, \"translated\" returns only the translation, and \"bilingual\" returns both aligned to the same timestamps. When no AI provider is configured the response is a clean FEATURE_UNAVAILABLE fallback carrying the original transcript.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string","description":"YouTube video id or URL."},"videoId":{"type":"string"},"url":{"type":"string"},"lang":{"type":"string"},"language":{"type":"string"},"target_lang":{"type":"string","enum":["en","es","de","fr","it","pt","ro","ja","zh","ko"]},"mode":{"type":"string","enum":["original","translated","bilingual"],"default":"translated"}},"required":["video_id","target_lang"]}}}},"responses":{"200":{"description":"Timestamped translated segments, or a FEATURE_UNAVAILABLE fallback","content":{"application/json":{"schema":{"type":"object","properties":{"video_id":{"type":"string"},"translated":{"type":"boolean"},"mode":{"type":"string"},"target_lang":{"type":"string"},"source_language":{"type":"string","nullable":true},"fallback":{"type":"boolean"},"code":{"type":"string"},"message":{"type":"string"},"segment_count":{"type":"integer"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}},"model":{"type":"string","nullable":true}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs":{"post":{"tags":["Jobs"],"summary":"Create an asynchronous job","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}},"video_ids":{"type":"array","items":{"type":"string"}},"urls":{"type":"array","items":{"type":"string"}},"kind":{"type":"string","enum":["batch","playlist","channel"]},"webhook_url":{"type":"string","format":"uri"}},"required":["ids"]}}}},"responses":{"202":{"description":"Job created","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string"},"total_items":{"type":"integer"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Jobs"],"summary":"List jobs","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Jobs","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{jobId}":{"get":{"tags":["Jobs"],"summary":"Get job status","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{jobId}/results":{"get":{"tags":["Jobs"],"summary":"Get job results","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Results","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string"},"completed_items":{"type":"integer"},"failed_items":{"type":"integer"},"results":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{jobId}/cancel":{"post":{"tags":["Jobs"],"summary":"Cancel a queued or processing job","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{jobId}/retry":{"post":{"tags":["Jobs"],"summary":"Re-queue failed items in a job","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/playlists/{playlistId}":{"get":{"tags":["Playlists"],"summary":"List playlist videos","parameters":[{"name":"playlistId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}}],"responses":{"200":{"description":"Playlist videos","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/playlists/{playlistId}/transcripts":{"post":{"tags":["Playlists"],"summary":"Create a playlist job","parameters":[{"name":"playlistId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"webhook_url":{"type":"string","format":"uri"}}}}}},"responses":{"202":{"description":"Job created","content":{"application/json":{"schema":{"type":"object","properties":{"playlist_id":{"type":"string"},"videos_found":{"type":"integer"},"job_id":{"type":"string"},"status":{"type":"string"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/channels/{channelId}":{"get":{"tags":["Channels"],"summary":"List channel videos","parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Channel videos","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/channels/{channelId}/transcripts":{"post":{"tags":["Channels"],"summary":"Create a channel job","parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"webhook_url":{"type":"string","format":"uri"}}}}}},"responses":{"202":{"description":"Job created","content":{"application/json":{"schema":{"type":"object","properties":{"channel_id":{"type":"string"},"videos_found":{"type":"integer"},"job_id":{"type":"string"},"status":{"type":"string"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/usage":{"get":{"tags":["Usage"],"summary":"Get account usage","parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":30}}],"responses":{"200":{"description":"Usage summary","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"plan":{"type":"string"},"credits_remaining":{"type":"integer"},"rate_limit_per_min":{"type":"integer","nullable":true},"period_days":{"type":"integer"}}},{"$ref":"#/components/schemas/UsageSummary"}]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/captcha":{"get":{"tags":["Auth"],"summary":"Issue a signup CAPTCHA challenge","description":"Key-free by default: returns a short-lived signed `token` and a plain-language `question` to answer in `captcha_answer`, plus `min_solve_ms`. When hCaptcha/reCAPTCHA is configured, returns `provider` and `site_key` instead and expects the widget token in `captcha_response`.","security":[],"responses":{"200":{"description":"Challenge","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/auth/register":{"post":{"tags":["Auth"],"summary":"Register a consumer account","description":"Requires a valid CAPTCHA (see GET /api/auth/captcha) and leaves the hidden honeypot fields empty. Registrations are rate-limited per IP, per email domain and per canonical mailbox; blocked requests return a generic 429.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"name":{"type":"string"},"captcha_token":{"type":"string","description":"Signed token from GET /api/auth/captcha (internal provider)."},"captcha_answer":{"type":["string","integer"],"description":"Answer to the internal challenge question."},"captcha_response":{"type":"string","description":"Widget token when hCaptcha/reCAPTCHA is enabled."}},"required":["email","password"]}}}},"responses":{"201":{"description":"Registered","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid input or failed CAPTCHA","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Registration temporarily blocked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Log in and set a session cookie","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}}},"responses":{"200":{"description":"Logged in","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Incorrect credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/logout":{"post":{"tags":["Auth"],"summary":"Log out","security":[{"sessionCookie":[]}],"responses":{"204":{"description":"Logged out"}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Current session","security":[],"responses":{"200":{"description":"Session","content":{"application/json":{"schema":{"type":"object","properties":{"authenticated":{"type":"boolean"},"user":{"type":"object","nullable":true,"additionalProperties":true},"plan":{"type":"object","nullable":true,"additionalProperties":true}}}}}}}}},"/api/account/me":{"get":{"tags":["Account"],"summary":"Current account","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/account/keys":{"get":{"tags":["Account"],"summary":"List API keys","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Account"],"summary":"Create an API key","security":[{"sessionCookie":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Created key (fullKey shown once)","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"}}}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/account/keys/{id}":{"delete":{"tags":["Account"],"summary":"Revoke an API key","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/account/usage":{"get":{"tags":["Account"],"summary":"Account usage summary","security":[{"sessionCookie":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":30}}],"responses":{"200":{"description":"Usage","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"object","nullable":true,"additionalProperties":true},"credits_remaining":{"type":"integer"},"credits":{"type":"object","description":"Free-credit state used to drive the in-dashboard upgrade nudge.","properties":{"included":{"type":"integer"},"remaining":{"type":"integer"},"threshold":{"type":"integer"},"low":{"type":"boolean"},"exhausted":{"type":"boolean"},"upgrade_available":{"type":"boolean"},"upgrade_nudge":{"type":"string","nullable":true}}}},"additionalProperties":true}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/account/plans":{"get":{"tags":["Account"],"summary":"List plans and billing status","security":[],"responses":{"200":{"description":"Plans","content":{"application/json":{"schema":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"billing_configured":{"type":"boolean"}}}}}}}}},"/api/account/webhooks":{"get":{"tags":["Account"],"summary":"List registered webhooks","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Account"],"summary":"Register a webhook","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["job.completed","job.failed"]}}},"required":["url"]}}}},"responses":{"201":{"description":"Webhook registered","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"}}}}}},"400":{"description":"Invalid URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/account/webhooks/{id}":{"delete":{"tags":["Account"],"summary":"Delete a webhook","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/plans":{"get":{"tags":["Meta"],"summary":"Plans, languages and formats","security":[],"responses":{"200":{"description":"Plans","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/api/health":{"get":{"tags":["Meta"],"summary":"Health check","security":[],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"service":{"type":"string"},"time":{"type":"string"}}}}}}}}},"/api/config":{"get":{"tags":["Meta"],"summary":"Public runtime config","security":[],"responses":{"200":{"description":"Config","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/mcp":{"post":{"tags":["MCP"],"summary":"MCP Streamable HTTP endpoint","description":"Model Context Protocol server (JSON-RPC 2.0 over HTTP). Authenticate with the same API key as the REST API (`Authorization: Bearer YOUR_API_KEY`). Supports `initialize`, `tools/list`, `tools/call` and `ping`. Tools: get_transcript, summarize, ask, chapters, search, quotes, clips, repurpose, translate. Connect from Claude Code, Codex or Claude Desktop using this URL.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"method":{"type":"string","enum":["initialize","tools/list","tools/call","ping","notifications/initialized"]},"params":{"type":"object","additionalProperties":true}},"required":["jsonrpc","method"]}}}},"responses":{"200":{"description":"JSON-RPC response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"202":{"description":"Notification accepted (no response body)"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["MCP"],"summary":"No SSE stream (405)","responses":{"405":{"description":"This stateless MCP server does not offer a server-sent event stream."}}}}}}