Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/coah80/yoink/llms.txt

Use this file to discover all available pages before exploring further.

Yoink integrates OpenAI Whisper for speech-to-text transcription. You upload a video or audio file, choose an output mode and model, and receive an async job ID. When the job completes you can download the result — a .txt transcript, an .srt / .ass subtitle file, or an MP4 with burned-in captions. Transcription happens entirely on your server using local Whisper models (tiny through medium). The large model is also supported, but requires a valid OPENAI_API_KEY environment variable — it routes through the OpenAI API rather than running locally.
POST /api/transcribe accepts a direct multipart upload (same size limits as /api/convert). For large files use the chunked upload flow to get a filePath token, then call POST /api/transcribe-chunked with that token.

POST /api/transcribe

Uploads a media file and starts an async transcription job.
POST /api/transcribe
Content-Type: multipart/form-data

Form Fields

file
file
required
The video or audio file to transcribe. Any format with an audio stream is accepted. Maximum size is 8 GB.
outputMode
string
default:"text"
What to produce from the transcription. One of:
  • text — plain .txt file containing the raw transcript
  • subtitles — an SRT or ASS subtitle file (set subtitleFormat to choose)
  • captions — a new MP4 with subtitles burned into the video frames using ASS rendering
model
string
default:"base"
Whisper model to use. Local models (no API key needed): tiny, base, small, medium. Remote model (requires OPENAI_API_KEY): large. Larger models are slower but more accurate.
subtitleFormat
string
default:"srt"
Subtitle file format. One of srt, ass. Only used when outputMode=subtitles. For outputMode=captions the server always uses ASS internally for burn-in rendering.
language
string
ISO 639-1 language code (2–5 letters, e.g. en, es, ja, zh-CN). Leave empty for automatic language detection. Invalid codes return an error.
captionSize
integer
default:"72"
Font size for burned-in captions (outputMode=captions or subtitles). Must be between 40 and 120. Has no effect on outputMode=text.
maxWordsPerCaption
integer
Maximum words per caption line. Must be between 1 and 20 when set. Leave unset (or 0) for no limit. Has no effect on outputMode=text.
maxCharsPerLine
integer
Maximum characters per caption line. Must be between 10 and 80 when set. Leave unset (or 0) for no limit. Has no effect on outputMode=text.
minDuration
number
Minimum duration in seconds for a caption segment. Segments shorter than this are merged with the next. Must be between 0.1 and 5.0 when set. Has no effect on outputMode=text.
captionGap
number
Minimum gap in seconds between consecutive caption segments. Must be between 0 and 1 when set. Has no effect on outputMode=text.
clientId
string
Session identifier for per-client job limiting (max 3 concurrent).

Response

{ "jobId": "550e8400-e29b-41d4-a716-446655440000" }

Errors

StatusMeaning
400File missing, unsupported type, or invalid parameters
429Too many concurrent jobs for this client

POST /api/transcribe-chunked

Starts an async transcription job for a file previously assembled via the chunked upload flow. This endpoint always uses outputMode=text and model=base — for other modes use the direct upload endpoint.
POST /api/transcribe-chunked
Content-Type: application/json

Body Fields

filePath
string
required
Token from POST /api/upload/complete.
fileName
string
Original filename hint used to derive the output filename. Defaults to "media".
clientId
string
Session identifier for per-client job limiting.

Response

{ "jobId": "550e8400-e29b-41d4-a716-446655440000" }

Polling and Downloading

After starting a job with either endpoint, poll the status and retrieve the result using the shared job endpoints documented in the Convert & Compress page.

GET /api/job//status

status
string
One of processing, complete, error.
progress
number
Completion percentage, 0–100. The pipeline reports: 1% (analyzing), 2% (extracting audio), 5–85% (transcription), 86–99% (burn-in, captions mode only), 100% (complete).
message
string
Human-readable status message (e.g. "Transcribing... 42%", "Burning captions... 67%").
error
string
Error message, present only when status is error.
textContent
string
Present only when outputMode=text and status=complete. Contains the full plain-text transcript inline — you do not need to call the download endpoint for text output, though you may.

GET /api/job//download

Downloads the output file when status is complete. The Content-Disposition filename uses the input file’s base name with an appropriate suffix:
Output modeFilename suffixMIME type
text_transcript.txttext/plain
subtitles (SRT).srtapplication/x-subrip
subtitles (ASS).asstext/x-ssa
captions_captioned.mp4video/mp4
The large model requires an OPENAI_API_KEY to be configured on the server. If you request model=large without a key, the job fails immediately with the error: "Large model requires API configuration. Use a local model (tiny/base/small/medium)." — even before file processing begins.

curl Examples

# Upload and start transcription
JOB_ID=$(curl -s -X POST https://yoink.example.com/api/transcribe \
  -F "file=@interview.mp3" \
  -F "outputMode=text" \
  -F "model=small" \
  -F "language=en" \
  | jq -r .jobId)

# Poll until complete
while true; do
  RESP=$(curl -s "https://yoink.example.com/api/job/${JOB_ID}/status")
  STATUS=$(echo "$RESP" | jq -r .status)
  echo "Status: $(echo "$RESP" | jq -r .message)"
  [ "$STATUS" = "complete" ] && break
  [ "$STATUS" = "error" ] && echo "Error: $(echo "$RESP" | jq -r .error)" && exit 1
  sleep 3
done

# Print transcript inline (available in textContent for text mode)
curl -s "https://yoink.example.com/api/job/${JOB_ID}/status" | jq -r .textContent

Build docs developers (and LLMs) love