{"openapi": "3.0.3", "info": {"title": "ytget API", "version": "0.1.0", "description": "YouTube -> MP3 / MP4 downloader. Jobs are asynchronous: create one, poll it, fetch the file. Protected endpoints need an HMAC-SHA256 request signature (headers X-Ytget-Timestamp, X-Ytget-Nonce, X-Ytget-Signature); see /docs for the algorithm."}, "servers": [{"url": "https://api.soundzilla.io", "description": "production"}, {"url": "/", "description": "same origin"}], "paths": {"/api/jobs": {"post": {"summary": "Create a download job", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "required": ["url"], "properties": {"url": {"type": "string", "description": "video URL or 11-char id"}, "mode": {"type": "string", "enum": ["mp3", "m4a", "opus", "audio", "mp4", "webm", "video"], "default": "mp3"}, "quality": {"type": "integer", "default": 1080, "description": "max height for mp4/webm (e.g. 360, 720, 1080)"}}}, "example": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "mode": "mp3"}}, "application/x-www-form-urlencoded": {"schema": {"type": "object", "properties": {"url": {"type": "string"}, "mode": {"type": "string"}}}}}}, "responses": {"202": {"description": "job accepted (status=queued)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Job"}}}}, "400": {"description": "missing url / unknown mode", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "missing or invalid signature", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "413": {"description": "body larger than 64 KB"}}}, "get": {"summary": "List the last 50 jobs (oldest first)", "responses": {"200": {"description": "jobs", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/Job"}}}}}}}}, "/api/jobs/{id}": {"get": {"summary": "Get job status / progress", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "job", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Job"}}}}, "404": {"description": "unknown job", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/files/{name}": {"get": {"summary": "Download a finished file (supports Range)", "description": "Use `file_url` from a done job: it carries `exp` and `sig`, so no headers are needed.", "security": [{}, {"YtgetTimestamp": [], "YtgetNonce": [], "YtgetSignature": []}], "parameters": [{"name": "name", "in": "path", "required": true, "schema": {"type": "string"}, "description": "the `filename` from a done job, URL-encoded (use `file_url`)"}, {"name": "exp", "in": "query", "schema": {"type": "integer"}, "description": "link expiry"}, {"name": "sig", "in": "query", "schema": {"type": "string"}, "description": "link signature"}], "responses": {"200": {"description": "file"}, "206": {"description": "partial content"}, "404": {"description": "not found"}}}, "head": {"summary": "File headers only", "responses": {"200": {"description": "ok"}, "404": {"description": "not found"}}}}, "/api/health": {"get": {"summary": "Liveness + queue size (public)", "security": [], "responses": {"200": {"description": "ok", "content": {"application/json": {"example": {"ok": true, "auth": true, "queued": 0, "jobs": 3}}}}}}}, "/openapi.json": {"get": {"summary": "This specification (public)", "security": [], "responses": {"200": {"description": "OpenAPI 3.0 document"}}}}, "/docs": {"get": {"summary": "Human-readable API documentation (public)", "security": [], "responses": {"200": {"description": "HTML"}}}}}, "security": [{"YtgetTimestamp": [], "YtgetNonce": [], "YtgetSignature": []}], "components": {"securitySchemes": {"YtgetTimestamp": {"type": "apiKey", "in": "header", "name": "X-Ytget-Timestamp", "description": "unix seconds, within 300 s of server time"}, "YtgetNonce": {"type": "apiKey", "in": "header", "name": "X-Ytget-Nonce", "description": "random, 8-128 chars [A-Za-z0-9_-], single use"}, "YtgetSignature": {"type": "apiKey", "in": "header", "name": "X-Ytget-Signature", "description": "hex HMAC-SHA256(secret, canonical request)"}}, "schemas": {"Job": {"type": "object", "properties": {"id": {"type": "string", "example": "0b72cf193680"}, "url": {"type": "string"}, "mode": {"type": "string", "enum": ["mp3", "m4a", "opus", "audio", "mp4", "webm", "video"]}, "quality": {"type": "integer", "nullable": true, "description": "max video height for video modes"}, "status": {"type": "string", "enum": ["queued", "running", "done", "error"]}, "stage": {"type": "string", "nullable": true, "enum": ["extracted", "audio", "video", "converting", "muxing", null], "description": "current step while running"}, "done": {"type": "integer", "description": "bytes downloaded in the current stage"}, "total": {"type": "integer", "nullable": true, "description": "bytes expected in the current stage"}, "title": {"type": "string", "nullable": true}, "client": {"type": "string", "nullable": true, "description": "InnerTube client that produced the URLs"}, "filename": {"type": "string", "nullable": true}, "size": {"type": "integer", "description": "final file size in bytes (done only)"}, "file_url": {"type": "string", "description": "relative download URL (done only)"}, "error": {"type": "string", "nullable": true}, "created": {"type": "number", "description": "unix timestamp"}, "finished": {"type": "number", "nullable": true, "description": "unix timestamp"}}}, "Error": {"type": "object", "properties": {"error": {"type": "string"}, "reason": {"type": "string", "description": "why auth failed (401 only)"}}}}}}