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 exposes two processing pipelines: convert (format/codec re-encoding with optional trim and crop) and compress (size-targeting via two-pass H.264 encoding or CRF quality mode). Both pipelines support two upload strategies: a simple multipart upload for files small enough to fit in a single HTTP request, and a chunked upload flow for large files that need to be reassembled server-side before processing. After chunked assembly — or for files already on the internet — you can use POST /api/fetch-url to pull a URL directly into server storage and receive a file token, which can then be passed to /api/convert-chunked or /api/compress-chunked.
The synchronous endpoints (/api/convert, /api/compress) stream the result directly back in the HTTP response. The chunked endpoints (/api/convert-chunked, /api/compress-chunked) return a jobId immediately; you must poll GET /api/job/{jobId}/status and fetch the result from GET /api/job/{jobId}/download when status is complete.

POST /api/convert

Re-encodes an uploaded file to a target format. For video formats, the codec is copied when compatible (reencode=auto) and only re-encoded when necessary or explicitly requested. For audio formats, the source audio is always re-encoded.
POST /api/convert
Content-Type: multipart/form-data

Form Fields

file
file
required
The video or audio file to convert. Supported input extensions: mp4, webm, mkv, mov, avi, flv, wmv, mp3, m4a, wav, flac, ogg, opus, aac, wma, ts, m4v, 3gp, mpg, mpeg. Maximum size is 8 GB.
format
string
required
Target output format. Video: mp4, webm, mkv, mov. Audio: mp3, m4a, opus, wav, flac.
quality
string
default:"medium"
CRF quality preset when re-encoding video. One of high (CRF 18), medium (CRF 23), low (CRF 28).
reencode
string
default:"auto"
Re-encode strategy. auto copies the codec when it is already compatible with the target container, otherwise re-encodes. always forces a full re-encode regardless. never always copies — conversion will fail if the codec is incompatible.
startTime
string
Optional trim start point. Accepts seconds (e.g. 30) or HH:MM:SS (e.g. 00:00:30).
endTime
string
Optional trim end point. Same format as startTime. Must be greater than startTime.
audioBitrate
string
default:"192"
Audio encoding bitrate in kbps. One of 64, 96, 128, 192, 256, 320.
cropRatio
string
Aspect-ratio crop applied before encoding. One of 16:9, 9:16, 1:1, 4:3, 4:5. The crop is centre-aligned. Providing this field forces a re-encode even when reencode=auto.
clientId
string
Optional session identifier for per-client job limiting (max 3 concurrent).

Response

Streams the converted binary file on success with appropriate Content-Type and Content-Disposition: attachment headers.

curl Example

curl -X POST https://yoink.example.com/api/convert \
  -F "file=@video.mkv" \
  -F "format=mp4" \
  -F "quality=high" \
  -F "startTime=10" \
  -F "endTime=90" \
  -o converted.mp4

POST /api/compress

Compresses a video to a target file size using two-pass H.264 encoding, or to a target quality using CRF mode. Always outputs MP4.
POST /api/compress
Content-Type: multipart/form-data

Form Fields

file
file
required
The video file to compress. Same supported extensions as /api/convert.
targetSize
string
default:"50"
Target output size in megabytes. Used when mode=size. The encoder calculates the required bitrate to hit this target.
duration
string
default:"0"
Video duration hint in seconds. If 0 (or omitted), the server probes the file with ffprobe. Providing an accurate value slightly speeds up bitrate calculation.
mode
string
default:"size"
Compression strategy. size targets a specific file size via two-pass encoding. quality uses a CRF value from the chosen preset.
quality
string
default:"medium"
Quality level used in both modes. One of high, medium, low. In quality mode this maps directly to a CRF value.
preset
string
default:"balanced"
ffmpeg encoding speed/quality tradeoff. One of fast (ultrafast), balanced (medium), quality (slow).
denoise
string
default:"auto"
Noise reduction filter. auto applies light denoising for high-bitrate sources. none, light, moderate, heavy override the automatic selection.
downscale
boolean
default:"false"
When true, the encoder automatically downscales the resolution when the target bitrate is too low to sustain the source resolution with acceptable quality.
progressId
string
Pre-generated UUID for Server-Sent Events progress tracking via GET /api/progress/{progressId}.
clientId
string
Session identifier for per-client job limiting.

Response

Streams the compressed MP4 file on success.

curl Example

curl -X POST https://yoink.example.com/api/compress \
  -F "file=@big_video.mp4" \
  -F "targetSize=25" \
  -F "mode=size" \
  -F "preset=balanced" \
  -F "downscale=true" \
  -o compressed.mp4

Chunked Upload Flow

Use the chunked upload API when the file is too large to upload in a single multipart request, or when you need resumable uploads. The flow has three steps:
1. POST /api/upload/init            → { uploadId }
2. POST /api/upload/chunk/{uploadId}/{chunkIndex}   → { received, total, complete }
3. POST /api/upload/complete/{uploadId}             → { success, filePath, fileName }
Once you have a filePath token from step 3, pass it to /api/convert-chunked or /api/compress-chunked. File tokens are single-use — they are consumed on the first chunked processing call.
The server enforces a maximum of 200 chunks per upload. Each chunk must be at most ChunkSize bytes (default 50 MB), giving a theoretical maximum upload of 10 GB per session — but note the server-wide file size limit is 8 GB.

POST /api/upload/init

POST /api/upload/init
Content-Type: application/json
{
  "fileName": "my_video.mp4",
  "fileSize": 524288000,
  "totalChunks": 10
}
uploadId
string
UUID to use in subsequent chunk and complete calls.

POST /api/upload/chunk//

POST /api/upload/chunk/{uploadId}/{chunkIndex}
Content-Type: multipart/form-data
Send the binary chunk in a form field named chunk. chunkIndex is zero-based.
received
number
Number of chunks received so far.
total
number
Total number of expected chunks.
complete
boolean
true when all chunks have been received and you may call /api/upload/complete.

POST /api/upload/complete/

Assembles all chunks into a single file and returns a secure token.
success
boolean
true on successful assembly.
filePath
string
Opaque token representing the assembled file. Pass this as filePath in convert/compress-chunked requests.
fileName
string
Original filename provided during init.

POST /api/convert-chunked

Starts an async conversion job for a previously uploaded file. Returns a jobId immediately.
POST /api/convert-chunked
Content-Type: application/json

Body Fields

filePath
string
required
Token from POST /api/upload/complete or POST /api/fetch-url.
format
string
default:"mp4"
Target output format. Same options as /api/convert.
fileName
string
Original filename hint, used to derive the output filename.
quality
string
default:"medium"
CRF quality preset. high, medium, or low.
reencode
string
default:"auto"
Re-encode strategy. auto, always, or never.
startTime
string
Trim start in seconds or HH:MM:SS.
endTime
string
Trim end in seconds or HH:MM:SS. Must be greater than startTime.
audioBitrate
string
default:"192"
Audio bitrate in kbps. One of 64, 96, 128, 192, 256, 320.
cropRatio
string
Aspect-ratio crop. One of 16:9, 9:16, 1:1, 4:3, 4:5.
cropX
integer
Pixel-precise crop: left edge. All four raw crop fields (cropX, cropY, cropW, cropH) must be provided together. Takes precedence over cropRatio.
cropY
integer
Pixel-precise crop: top edge.
cropW
integer
Pixel-precise crop: width. Must be a positive even integer.
cropH
integer
Pixel-precise crop: height. Must be a positive even integer.
segments
array
Array of { start: number, end: number } objects for multi-segment extraction. Maximum 20 segments. Each segment’s end must be greater than start.
clientId
string
Session identifier for per-client job limiting.

Response

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

Polling the Job

GET /api/job/{jobId}/status
status
string
One of processing, complete, error.
progress
number
Completion percentage, 0–100.
message
string
Human-readable status message.
error
string
Error message, present only when status is error.
textContent
string
Transcript text content, present only for transcription jobs in text mode.
When status is complete, download the result with:
GET /api/job/{jobId}/download

curl Example

# 1. Init upload
UPLOAD_ID=$(curl -s -X POST https://yoink.example.com/api/upload/init \
  -H "Content-Type: application/json" \
  -d '{"fileName":"input.mp4","fileSize":104857600,"totalChunks":2}' \
  | jq -r .uploadId)

# 2. Upload chunks (simplified — split the file first)
curl -X POST "https://yoink.example.com/api/upload/chunk/${UPLOAD_ID}/0" \
  -F "chunk=@chunk_0.bin"
curl -X POST "https://yoink.example.com/api/upload/chunk/${UPLOAD_ID}/1" \
  -F "chunk=@chunk_1.bin"

# 3. Complete assembly
FILE_TOKEN=$(curl -s -X POST "https://yoink.example.com/api/upload/complete/${UPLOAD_ID}" \
  | jq -r .filePath)

# 4. Start async conversion
JOB_ID=$(curl -s -X POST https://yoink.example.com/api/convert-chunked \
  -H "Content-Type: application/json" \
  -d "{\"filePath\":\"${FILE_TOKEN}\",\"format\":\"mp4\",\"quality\":\"high\"}" \
  | jq -r .jobId)

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

# 6. Download result
curl -L -o output.mp4 "https://yoink.example.com/api/job/${JOB_ID}/download"

POST /api/compress-chunked

Starts an async compression job for a previously uploaded file. Same token-based flow as /api/convert-chunked.
POST /api/compress-chunked
Content-Type: application/json

Body Fields

filePath
string
required
Token from POST /api/upload/complete or POST /api/fetch-url.
fileName
string
Original filename hint.
targetSize
string
default:"50"
Target output size in MB (used when mode=size).
duration
string
default:"0"
Duration hint in seconds (0 = probe automatically).
mode
string
default:"size"
size or quality.
quality
string
default:"medium"
high, medium, or low.
preset
string
default:"balanced"
fast, balanced, or quality.
denoise
string
default:"auto"
auto, none, light, moderate, or heavy.
downscale
boolean
default:"false"
Auto-downscale resolution when bitrate is insufficient for source resolution.
clientId
string
Session identifier for per-client job limiting.

Response

{ "jobId": "550e8400-e29b-41d4-a716-446655440000" }
Poll and download using the same GET /api/job/{jobId}/status and GET /api/job/{jobId}/download pattern described above.

POST /api/fetch-url

Downloads a public URL via yt-dlp to server temporary storage and returns a file token. The token can be passed directly to /api/convert-chunked or /api/compress-chunked without needing to upload the file yourself.
POST /api/fetch-url
Content-Type: application/json

Body

{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }

Response

filePath
string
Opaque file token to pass as filePath in subsequent processing calls.
fileName
string
Filename of the downloaded file (derived from yt-dlp output).
fileSize
number
File size in bytes.
duration
number
Video duration in seconds (from ffprobe).
width
number
Video width in pixels.
height
number
Video height in pixels.

curl Example

# Fetch the URL to server storage
RESP=$(curl -s -X POST https://yoink.example.com/api/fetch-url \
  -H "Content-Type: application/json" \
  -d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}')

FILE_TOKEN=$(echo $RESP | jq -r .filePath)

# Immediately start a compression job
JOB_ID=$(curl -s -X POST https://yoink.example.com/api/compress-chunked \
  -H "Content-Type: application/json" \
  -d "{\"filePath\":\"${FILE_TOKEN}\",\"targetSize\":\"50\",\"preset\":\"fast\"}" \
  | jq -r .jobId)

Build docs developers (and LLMs) love