Skip to content

API Endpoints

Complete API reference for the Subtide backend.


http://localhost:5001

Check if the backend is running.

GET /health
{
"status": "healthy"
}
Terminal window
curl http://localhost:5001/health

Translate a video’s subtitles (batch mode).

POST /api/translate
Content-Type: application/json
FieldTypeRequiredDescription
video_urlstringYesYouTube URL or video identifier
target_languagestringYesTarget language code (e.g., es, ja)
source_languagestringNoSource language (auto-detect if omitted)
api_keystringTier 1/2Your LLM API key
api_urlstringNoCustom API endpoint
modelstringNoLLM model name
tiernumberNoOperation tier (1-4)
force_whisperbooleanNoForce Whisper transcription
{
"success": true,
"job_id": "abc123",
"subtitles": [
{
"start": 0.0,
"end": 2.5,
"text": "Translated text here"
}
],
"source_language": "en",
"target_language": "es"
}
Terminal window
curl -X POST http://localhost:5001/api/translate \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"target_language": "es",
"api_key": "sk-xxx",
"model": "gpt-4o-mini"
}'

Translate with real-time streaming (Tier 4).

POST /api/stream
Content-Type: application/json

Same as /api/translate.

Server-Sent Events (SSE) stream:

data: {"type": "subtitle", "start": 0.0, "end": 2.5, "text": "First subtitle"}
data: {"type": "subtitle", "start": 2.5, "end": 5.0, "text": "Second subtitle"}
data: {"type": "complete", "total_subtitles": 42}
TypeDescription
subtitleA translated subtitle segment
progressProgress update
errorError occurred
completeTranslation finished
Terminal window
curl -X POST http://localhost:5001/api/stream \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"target_language": "ja"
}'

Get the status of a translation job.

GET /api/status/{job_id}
{
"job_id": "abc123",
"status": "completed",
"progress": 100,
"subtitles_count": 42,
"error": null
}
StatusDescription
pendingJob queued
processingCurrently translating
completedTranslation finished
failedError occurred
Terminal window
curl http://localhost:5001/api/status/abc123

All endpoints return errors in this format:

{
"success": false,
"error": "Error message here",
"code": "ERROR_CODE"
}
CodeHTTP StatusDescription
INVALID_URL400Invalid video URL
MISSING_API_KEY400API key required but not provided
INVALID_LANGUAGE400Unsupported language code
VIDEO_NOT_FOUND404Video not accessible
TRANSCRIPTION_FAILED500Whisper transcription error
TRANSLATION_FAILED500LLM translation error
API_ERROR502External API error

Supported target languages:

LanguageCode
Englishen
Spanishes
Frenchfr
Germande
Portuguesept
Russianru
Italianit
Japaneseja
Koreanko
Chinese (Simplified)zh-CN
Chinese (Traditional)zh-TW
Arabicar
Hindihi

The backend does not implement rate limiting by default. For production deployments, consider adding:

  • Reverse proxy with rate limiting (nginx, Traefik)
  • Application-level rate limiting
  • API key quotas

By default, CORS is configured to allow all origins (*).

Restrict with environment variable:

Terminal window
CORS_ORIGINS=https://youtube.com,https://www.youtube.com

API key is passed in the request body. The backend proxies to the LLM provider.

API key is stored on the server. No client-side key required.

When using RunPod serverless, include the RunPod API key in the header:

Authorization: Bearer {RUNPOD_API_KEY}