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.

The Yoink API is a JSON-over-HTTP interface served by a self-hosted Go server. All endpoints are accessible over plain HTTP on the configured port (default 3001). Every response body is a JSON object, download streams are delivered as binary responses, and real-time progress is pushed over Server-Sent Events. This page covers the baseline facts you need before calling any endpoint.

Base URL

http://your-server:3001
The port is controlled by the PORT environment variable. If PORT is not set, the server defaults to 3001. Replace your-server with the hostname or IP address of the machine running Yoink.
# Verify the server is reachable
curl http://your-server:3001/health

Authentication

Yoink uses a two-tier authentication model depending on which route group you are targeting.

Web Endpoints

Routes under /api/* (download, convert, compress, progress, etc.) require no authentication by default. They are rate-limited per IP instead.

Bot Endpoints

Routes under /api/bot/* require an Authorization: Bearer {BOT_SECRET} header. Set the BOT_SECRET environment variable on the server to enable this.
If BOT_SECRET is not set on the server, checkBotAuth always returns false, which means all bot endpoint requests will be rejected with 401 Unauthorized. The bot API will be completely non-functional until BOT_SECRET is configured. Always set BOT_SECRET in production deployments.

Bot Authorization Header

Authorization
string
required
Bearer token required for all /api/bot/* endpoints. Format: Bearer {BOT_SECRET}.
curl -H "Authorization: Bearer mysecrettoken" \
  http://your-server:3001/api/bot/download

Rate Limiting

All requests are subject to a sliding-window rate limit enforced per client IP address. The rate limiter runs before any route handler, so even unauthenticated requests count against the limit.
ParameterValue
Window60 seconds (RateLimitWindow)
Max requests60 per window (RateLimitMax)
ScopePer IP address
Header: limitX-RateLimit-Limit
Header: remainingX-RateLimit-Remaining
Header: resetX-RateLimit-Reset (seconds, only on 429)
When a client exceeds the limit the server responds with HTTP 429 and a JSON body:
{
  "error": "Too many requests. Please slow down.",
  "resetIn": 42
}
resetIn is the number of seconds until the oldest request in the current window expires and a new request will be permitted.

CORS

CORS is enabled via the go-chi/cors middleware. Behaviour depends on whether a cors-origins.txt file is present on the server:
  • With cors-origins.txt: Only the origins listed in the file are allowed, and credentials: true is set. This is the recommended configuration for production.
  • Without cors-origins.txt: All origins (*) are allowed, but credentials are disabled. A warning is printed to the server log at startup.
Allowed methods for all origins: GET, POST, PUT, DELETE, OPTIONS. The MaxAge for preflight caches is set to 86400 seconds (24 hours).
Create a cors-origins.txt file in the server’s working directory and list one allowed origin per line (lines starting with # are treated as comments). This enables credentialed cross-origin requests from your front-end domain.

Response Format

All API responses return Content-Type: application/json. Success and error bodies follow the same envelope pattern: Success
{ "key": "value" }
Error
{ "error": "Human-readable message" }
Some endpoints return an explicit success boolean alongside a message string for operations that may partially succeed (e.g. cancel and finish-early).

Security Headers

Every response includes the following security headers regardless of route:
HeaderValue
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Referrer-Policystrict-origin-when-cross-origin

Route Groups

GroupPath PrefixAuth Required
Core/health, /api/connect, /api/heartbeat, /api/queue-status, /api/limits, /api/progress, /api/cancel, /api/finish-earlyNo
Download/api/downloadNo
Playlist/api/playlistNo
Convert/api/convertNo
Gallery/api/galleryNo
Transcribe/api/transcribeNo
Bot/api/bot/*Yes — Bearer token

Global Job Limits

Yoink enforces concurrency limits on background job types to prevent resource exhaustion. These limits are fixed at compile time and can be inspected at runtime via GET /api/limits.
Job TypeConcurrent Slots
playlist2
convert2
compress1
transcribe1
fetchUrl2
Additional queue constraints:
ConstraintValue
Max jobs per client3
Queue size limit50
Max file size15 GB
Max playlist videos1,000
Max video duration14,400 seconds (4 hours)
When the queue is full (50 pending jobs) the server will reject new job requests with an error response. Poll GET /api/queue-status to check current queue depth before submitting long-running jobs.

Health Check

Use GET /health to verify the server is running and inspect the current queue state. This endpoint is not rate-limited and does not require a session.
curl http://your-server:3001/health
Response
{
  "status": "ok",
  "version": "1.0.0",
  "queue": {
    "active": 2,
    "waiting": 5
  }
}
status
string
Always "ok" when the server is healthy.
version
string
Server version string.
queue
object
Current queue state object returned by the internal queue service. Shape may include active job counts and per-type breakdowns.

Limits Endpoint

GET /api/limits returns the server’s current concurrency limits and content constraints in a single call — useful for client-side validation before submitting jobs.
curl http://your-server:3001/api/limits
Response
{
  "limits": {
    "playlist": 2,
    "convert": 2,
    "compress": 1,
    "transcribe": 1,
    "fetchUrl": 2
  },
  "maxFileSize": 16106127360,
  "maxPlaylistVideos": 1000,
  "maxVideoDuration": 14400
}
limits
object
Map of job type to the maximum number of concurrent workers for that type.
maxFileSize
integer
Maximum output file size in bytes (15 GB = 16,106,127,360).
maxPlaylistVideos
integer
Maximum number of videos that can be included in a single playlist download.
maxVideoDuration
integer
Maximum video duration in seconds (14,400 = 4 hours).

Build docs developers (and LLMs) love