{"openapi":"3.1.0","info":{"title":"Vidaio API","description":"API for Vidaio video compression and upscaling. Use `X-API-Key` or `Authorization: Bearer <api_key>` on protected endpoints. Start a job with a source video URL, check status with the returned task ID, and fetch the output URL when processing is complete. Starting jobs requires available credits.","version":"1.0.0"},"paths":{"/health":{"get":{"tags":["system"],"summary":"Health check","description":"Lightweight liveness check for load balancers and uptime monitors. This confirms the HTTP app is running; use `/ready` to verify database readiness.","operationId":"health_health_get","responses":{"200":{"description":"The API process is alive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemStatusResponse"}}}}}}},"/ready":{"get":{"tags":["system"],"summary":"Readiness check","description":"Checks whether the API can reach its backing database before receiving traffic.","operationId":"ready_ready_get","responses":{"200":{"description":"The API is ready to serve authenticated workflow requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemStatusResponse"}}}},"503":{"description":"Database connection is not ready.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemStatusResponse"},"example":{"status":"unavailable"}}}}}}},"/rate_limits":{"get":{"tags":["account"],"summary":"Get API key rate limits","description":"Returns the configured workflow-start and read-rate buckets for the authenticated API key. Read requests include status, result, and account endpoints.","operationId":"get_api_key_rate_limits_rate_limits_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Rate-limit settings for the authenticated API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRateLimitsResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/available_credits":{"get":{"tags":["account"],"summary":"Get available credits","description":"Returns the current credit balance for the authenticated API key owner. Starting workflows requires a positive balance.","operationId":"get_available_credits_available_credits_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Available credit balance for the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailableCreditsResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/compression":{"post":{"tags":["compression"],"summary":"Start compression","description":"Uploads a source video URL to Vidaio and queues a compression workflow. The API accepts the request immediately, stores the selected compression preset, uses the tier to choose the local worker fallback or subnet miners, and starts processing after video validation is complete. Poll `GET /compression/{task_id}` until the task reaches a terminal status.","operationId":"start_compression_compression_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompressionStartRequest"}}}},"responses":{"202":{"description":"Compression workflow accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartWorkflowResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"The API key owner has no available credits.","content":{"application/json":{"example":{"detail":"API key owner has no available credits"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A task with this ID is already being tracked for this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Workflow start rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/compression/{task_id}":{"get":{"tags":["compression"],"summary":"Get compression status","description":"Returns the latest compression workflow status for a task owned by the authenticated user. When video validation is complete, Vidaio starts compression with the stored preset. If the video is not eligible for compression, the response uses `trigger_failed` with the validation message.","operationId":"get_compression_status_compression__task_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Current compression workflow status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"400":{"description":"Processing could not start because the source video is not eligible for this workflow.","content":{"application/json":{"example":{"operation":"compression","task_id":"b1234567-1234-1234-1234-123456789012","status":"trigger_failed","message":"source video is already well compressed"},"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No task with this ID and operation belongs to the authenticated user.","content":{"application/json":{"example":{"detail":"compression task task-123 was not found"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/compression/{task_id}/result":{"get":{"tags":["compression"],"summary":"Get compression result","description":"Fetches the completed compression result from Vidaio for a task owned by the authenticated user. The response includes result fields whose names include `id` or `url`, such as `task_id` and `download_url`. Credits are consumed when a completed result is fetched.","operationId":"get_compression_result_compression__task_id__result_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Filtered compression result fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResultResponse"}}}},"400":{"description":"Processing could not start because the source video is not eligible for this workflow.","content":{"application/json":{"example":{"operation":"compression","task_id":"b1234567-1234-1234-1234-123456789012","status":"trigger_failed","message":"source video is already well compressed"},"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No task with this ID and operation belongs to the authenticated user.","content":{"application/json":{"example":{"detail":"compression task task-123 was not found"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/upscaling":{"post":{"tags":["upscaling"],"summary":"Start upscaling","description":"Uploads a source video URL to Vidaio and queues an upscaling workflow. The API accepts the request immediately, stores the selected upscaling multiplier, uses the tier to choose Video2X or subnet miners, and starts processing after video validation is complete. Poll `GET /upscaling/{task_id}` until the task reaches a terminal status.","operationId":"start_upscaling_upscaling_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpscalingStartRequest"}}}},"responses":{"202":{"description":"Upscaling workflow accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartWorkflowResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"The API key owner has no available credits.","content":{"application/json":{"example":{"detail":"API key owner has no available credits"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A task with this ID is already being tracked for this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Workflow start rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/upscaling/{task_id}":{"get":{"tags":["upscaling"],"summary":"Get upscaling status","description":"Returns the latest upscaling workflow status for a task owned by the authenticated user. When video validation is complete, Vidaio starts upscaling with the stored multiplier. If the video is not eligible for upscaling, the response uses `trigger_failed` with the validation message.","operationId":"get_upscaling_status_upscaling__task_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Current upscaling workflow status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"400":{"description":"Processing could not start because the source video is not eligible for this workflow.","content":{"application/json":{"example":{"operation":"compression","task_id":"b1234567-1234-1234-1234-123456789012","status":"trigger_failed","message":"source video is already well compressed"},"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No task with this ID and operation belongs to the authenticated user.","content":{"application/json":{"example":{"detail":"compression task task-123 was not found"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/upscaling/{task_id}/result":{"get":{"tags":["upscaling"],"summary":"Get upscaling result","description":"Fetches the completed upscaling result from Vidaio for a task owned by the authenticated user. The response includes result fields whose names include `id` or `url`, such as `task_id` and `download_url`. Credits are consumed when a completed result is fetched.","operationId":"get_upscaling_result_upscaling__task_id__result_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Filtered upscaling result fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResultResponse"}}}},"400":{"description":"Processing could not start because the source video is not eligible for this workflow.","content":{"application/json":{"example":{"operation":"compression","task_id":"b1234567-1234-1234-1234-123456789012","status":"trigger_failed","message":"source video is already well compressed"},"schema":{"$ref":"#/components/schemas/WorkflowStatusResponse"}}}},"401":{"description":"API key is missing, invalid, expired, or revoked.","content":{"application/json":{"example":{"detail":"Invalid or missing API key"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No task with this ID and operation belongs to the authenticated user.","content":{"application/json":{"example":{"detail":"compression task task-123 was not found"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Read rate limit exceeded for this API key. Retry later.","content":{"application/json":{"example":{"detail":"Rate limit exceeded"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vidaio could not complete the request or returned an invalid response.","content":{"application/json":{"example":{"detail":"Vidaio service returned an invalid response"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ApiKeyRateLimitsResponse":{"properties":{"start_rate_limit_requests":{"type":"integer","title":"Start Rate Limit Requests","description":"Maximum workflow start requests per window."},"start_rate_limit_window_seconds":{"type":"integer","title":"Start Rate Limit Window Seconds","description":"Workflow start rate-limit window size."},"read_rate_limit_requests":{"type":"integer","title":"Read Rate Limit Requests","description":"Maximum status, result, and account requests per window."},"read_rate_limit_window_seconds":{"type":"integer","title":"Read Rate Limit Window Seconds","description":"Read rate-limit window size."}},"type":"object","required":["start_rate_limit_requests","start_rate_limit_window_seconds","read_rate_limit_requests","read_rate_limit_window_seconds"],"title":"ApiKeyRateLimitsResponse","examples":[{"read_rate_limit_requests":6,"read_rate_limit_window_seconds":60,"start_rate_limit_requests":3,"start_rate_limit_window_seconds":60}]},"AvailableCreditsResponse":{"properties":{"available_credits":{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$","title":"Available Credits","description":"Current credit balance for the authenticated API key owner."}},"type":"object","required":["available_credits"],"title":"AvailableCreditsResponse","examples":[{"available_credits":"12.5"}]},"CompressionStartRequest":{"properties":{"video_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Video Url","description":"Public or pre-signed URL for the source video to compress."},"compression_type":{"type":"string","enum":["Low","Medium","High"],"title":"Compression Type","description":"Compression preset. Low favors smaller files, Medium is balanced, and High preserves more quality.","default":"High"},"tier":{"type":"string","enum":["Standard","Premium"],"title":"Tier","description":"Compression processing tier. Standard uses the local worker fallback; Premium uses subnet miners.","default":"Standard"}},"additionalProperties":false,"type":"object","required":["video_url"],"title":"CompressionStartRequest","examples":[{"compression_type":"High","tier":"Standard","video_url":"https://storage.example.com/input.mp4?signature=example"}]},"ErrorResponse":{"properties":{"detail":{"title":"Detail","description":"Error detail returned by the API."}},"type":"object","required":["detail"],"title":"ErrorResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"StartWorkflowResponse":{"properties":{"operation":{"type":"string","enum":["compression","upscaling"],"title":"Operation","description":"Workflow type that was started."},"task_id":{"type":"string","title":"Task Id","description":"Vidaio task ID returned when the workflow starts."},"status":{"type":"string","title":"Status","description":"Initial workflow status. Start routes return queued."},"message":{"type":"string","title":"Message","description":"Human-readable status detail."}},"type":"object","required":["operation","task_id","status","message"],"title":"StartWorkflowResponse","examples":[{"message":"compression upload accepted; processing will start after video validation is complete","operation":"compression","status":"queued","task_id":"b1234567-1234-1234-1234-123456789012"}]},"SystemStatusResponse":{"properties":{"status":{"type":"string","enum":["ok","unavailable"],"title":"Status","description":"Service health or readiness state."}},"type":"object","required":["status"],"title":"SystemStatusResponse"},"UpscalingStartRequest":{"properties":{"video_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Video Url","description":"Public or pre-signed URL for the source video to upscale."},"upscaling_type":{"type":"string","enum":["2x","4x"],"title":"Upscaling Type","description":"Upscaling multiplier to apply after the source video passes validation.","default":"2x"},"tier":{"type":"string","enum":["Standard","Premium"],"title":"Tier","description":"Upscaling quality tier. Standard uses the Video2X backend; Premium uses subnet miners.","default":"Standard"}},"additionalProperties":false,"type":"object","required":["video_url"],"title":"UpscalingStartRequest","examples":[{"tier":"Standard","upscaling_type":"2x","video_url":"https://storage.example.com/input.mp4?signature=example"}]},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WorkflowResultResponse":{"properties":{"task_id":{"type":"string","title":"Task Id","description":"Vidaio task ID for the completed workflow."}},"additionalProperties":true,"type":"object","required":["task_id"],"title":"WorkflowResultResponse","examples":[{"download_url":"https://storage.example.com/output.mp4?signature=example","task_id":"b1234567-1234-1234-1234-123456789012"}]},"WorkflowStatusResponse":{"properties":{"operation":{"type":"string","enum":["compression","upscaling"],"title":"Operation","description":"Workflow type for the tracked task."},"task_id":{"type":"string","title":"Task Id","description":"Vidaio task ID returned when the workflow starts."},"status":{"type":"string","title":"Status","description":"Current workflow status. Common values include queued, processing, completed, failed, cancelled, and trigger_failed."},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"Human-readable status detail when available."}},"type":"object","required":["operation","task_id","status"],"title":"WorkflowStatusResponse","examples":[{"message":"compression processing started","operation":"compression","status":"processing","task_id":"b1234567-1234-1234-1234-123456789012"}]}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}},"tags":[{"name":"compression","description":"Start video compression jobs, check their status, and fetch completed output URLs."},{"name":"upscaling","description":"Start video upscaling jobs, check their status, and fetch completed output URLs."},{"name":"account","description":"Check API key limits and available credits."},{"name":"system","description":"Health and readiness checks for service monitors."}]}