API documentation
FatBaby API is a credit-based HTTP API for file, media, and developer utilities. Authenticate with an API key, follow the steps for each endpoint, and track usage from the dashboard.
Overview
| Base URL | https://thefatbaby.com/api |
|---|---|
| Auth | Authorization: Bearer fb_live_… or fb_test_… |
| Dashboard | /dashboard |
| Health | GET /health, /health/live, /health/ready |
Every response includes an X-Request-Id header (also returned as request_id in JSON bodies).
Authentication
- Create an account and open the dashboard.
- Create an API key (live or test). The full secret is shown once.
- Send it on every billable request:
Authorization: Bearer fb_live_YOUR_KEY
Dashboard login uses email/password with httpOnly session cookies. Public API products use API keys (fb_live_… / fb_test_…).
Credits & errors
- New accounts receive 100 free credits.
- Sync endpoints deduct credits after successful work.
- Async media jobs reserve credits on submit and capture them when the job completes.
- Failed validation before processing does not consume credits.
- Insufficient balance returns
402witherror: insufficient_credits.
Common error shape:
{
"error": "validation_error",
"message": "Request validation failed",
"request_id": "req_..."
}Billable responses also include X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining.
FFmpeg how-to (general)
FatBaby exposes two FFmpeg-related styles. Use Media Processing for normal convert/compress/trim/audio/GIF work (upload and start happen in one request). Use legacy /v1/render only when you need a validated rawffmpeg … command against job folders.
Media Processing (recommended)
Upload + process in one call, then poll /v1/jobs
- 1. Inspect (optional) — POST /v1/media/inspect with file=@…
- 2. Submit operation — POST /v1/video/convert (or compress, trim, audio/extract, …) with file + options
- 3. Save job.id — Response status is queued; credits are reserved
- 4. Poll job — GET /v1/jobs/:jobId until completed
- 5. Download — GET /v1/jobs/:jobId/download?filename=…
Legacy /v1/render
Create job → upload → run ffmpeg command → download
- 1. Create job — POST /v1/render/job → save job_id (1 credit)
- 2. Upload file — POST /v1/render/upload/:jobId with file=@… (2 credits)
- 3. Start render — POST /v1/render/render with job_id + command (5 credits)
- 4. Poll status — GET /v1/render/status/:renderJobId
- 5. Download — GET /v1/render/download/:jobId/:filename
Media Processing workflow
Allowlisted ops under /v1/video, /v1/audio, /v1/gif, /v1/stream,/v1/subtitles. Job lifecycle lives under /v1/jobs. There is no separate “create empty job” step — uploading the file is part of the operation POST.
- Get an API key from the dashboard. Every request needs Authorization: Bearer fb_live_… (or x-api-key).
- Optional first: POST /v1/media/inspect or /v1/media/validate with file=@clip.mp4 to check duration/codecs (sync, 1 credit).
- Submit work: POST an allowlisted route such as /v1/video/convert, /v1/video/compress, /v1/audio/extract, /v1/gif/from-video. Multipart field file is the input; add options as form fields (format, preset, start, …).
- Response returns job.id with status queued. Credits are reserved now; they are captured when the job completes.
- Poll GET /v1/jobs/:jobId until status is completed (also: failed, cancelled, expired). Progress is 0–100 while processing.
- Download: use job.output.downloads[].url or GET /v1/jobs/:jobId/download?filename=…. Auth required; only your jobs.
- Optional: pass webhook_url + webhook_ref on submit for HMAC callbacks. Cancel with POST /v1/jobs/:jobId/cancel.
- These routes never accept raw FFmpeg filters or shell commands — only allowlisted options.
# 0) Auth header used on every call
export API=https://thefatbaby.com/api
export KEY=fb_live_YOUR_KEY
# 1) (Optional) Inspect the file first — sync JSON
curl -X POST "$API/v1/media/inspect" \
-H "Authorization: Bearer $KEY" \
-F "file=@clip.mp4"
# 2) Create + upload + enqueue in ONE request (no separate job-create)
curl -X POST "$API/v1/video/convert" \
-H "Authorization: Bearer $KEY" \
-F "file=@clip.mp4" \
-F "format=mp4" \
-F "video_codec=libx264"
# → { "job": { "id": "JOB_ID", "status": "queued", ... } }
# 3) Poll until completed
curl "$API/v1/jobs/JOB_ID" -H "Authorization: Bearer $KEY"
# status: queued → downloading → processing → uploading → completed
# 4) Download the output
curl "$API/v1/jobs/JOB_ID/download?filename=converted.mp4" \
-H "Authorization: Bearer $KEY" \
--output converted.mp4
Legacy render workflow
Classic pipeline matching the original render API: create job → upload file(s) → start FFmpeg → poll → download. Paths in the command must stay under that job's input/ and output/ directories.
- Create job: POST /v1/render/job (alias /v1/render/jobs). Returns job_id plus server input/output/temp paths. Cost: 1 credit.
- Upload input(s): POST /v1/render/upload/:jobId with multipart field file=@clip.mp4 (alias /v1/render/jobs/:jobId/files). Repeat for more files. Cost: 2 credits per upload.
- Start FFmpeg: POST /v1/render/render with JSON { "job_id": "…", "command": "ffmpeg -y -i …/input/clip.mp4 …/output/out.mp4" }. Paths must stay inside that job’s folders. Cost: 5 credits when accepted.
- Poll: GET /v1/render/status/:renderJobId until status is completed or failed.
- Download: GET /v1/render/download/:jobId/:filename (e.g. out.mp4) with your API key. Free.
- Only the API-key owner can access the job. Commands are validated — arbitrary shell is rejected.
# Legacy render pipeline — create → upload → render → poll → download
export API=https://thefatbaby.com/api
export KEY=fb_live_YOUR_KEY
# 1) Create a job (folders on the server)
curl -X POST "$API/v1/render/job" -H "Authorization: Bearer $KEY"
# → { "job_id": "JOB_ID", "input_path": "/data/renders/jobs/JOB_ID/input", ... }
# 2) Upload your media into the job input folder
curl -X POST "$API/v1/render/upload/JOB_ID" \
-H "Authorization: Bearer $KEY" \
-F "file=@clip.mp4"
# → { "filename": "clip.mp4", "path": ".../input/clip.mp4" }
# 3) Start FFmpeg (paths must use this job's input/ and output/)
curl -X POST "$API/v1/render/render" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"job_id": "JOB_ID",
"command": "ffmpeg -y -i /data/renders/jobs/JOB_ID/input/clip.mp4 /data/renders/jobs/JOB_ID/output/out.mp4"
}'
# → { "render_job_id": "RENDER_ID", "status": "processing" }
# 4) Poll render status
curl "$API/v1/render/status/RENDER_ID" -H "Authorization: Bearer $KEY"
# 5) Download the output file
curl "$API/v1/render/download/JOB_ID/out.mp4" \
-H "Authorization: Bearer $KEY" \
--output out.mp4
Images
Resize, compress, convert and clean images with Sharp. Multipart field name is always file.
All image routes accept multipart/form-data with a file field. Max upload size: 20 MB. Supported inputs: JPEG, PNG, WebP, AVIF, GIF.
/v1/image/info1 creditLiveRead format, dimensions, color space and size
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- No extra fields required — upload only.
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/info \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.jpg"
{
"format": "jpeg",
"width": 4032,
"height": 3024,
"space": "srgb",
"channels": 3,
"depth": "uchar",
"density": 72,
"has_alpha": false,
"orientation": 1,
"size_bytes": 2456789,
"request_id": "req_…",
"credits_used": 1,
"credits_remaining": 99
}/v1/image/resize2 creditsLiveResize with fit modes; optional output format
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- Set width and/or height (1–10000). Optional: fit (cover|contain|fill|inside|outside), format, quality, enlarge.
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/resize \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.jpg" \ -F "width=1024" \ -F "height=768" \ -F "fit=inside" \ -F "format=webp" \ -F "quality=82" \ --output resized.webp
HTTP 200
Content-Type: image/webp
Content-Disposition: inline; filename="resized.webp"
X-Request-Id: req_…
X-FatBaby-Credits-Used: …
X-FatBaby-Credits-Remaining: …
<body = binary image bytes>
# Dashboard logs store metadata only, e.g.:
{
"kind": "image",
"content_type": "image/webp",
"filename": "resized.webp",
"size_bytes": 184320,
"credits_used": 2,
"credits_remaining": 98,
"note": "Binary image output is not stored in logs; metadata only."
}/v1/image/compress2 creditsLiveRe-encode with quality controls
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- Optional: format, quality (1–100, default 80).
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/compress \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.jpg" \ -F "format=jpeg" \ -F "quality=80" \ --output compressed.jpg
HTTP 200
Content-Type: image/jpeg
Content-Disposition: inline; filename="compressed.jpg"
X-Request-Id: req_…
X-FatBaby-Credits-Used: …
X-FatBaby-Credits-Remaining: …
<body = binary image bytes>
# Dashboard logs store metadata only, e.g.:
{
"kind": "image",
"content_type": "image/jpeg",
"filename": "compressed.jpg",
"size_bytes": 184320,
"credits_used": 2,
"credits_remaining": 98,
"note": "Binary image output is not stored in logs; metadata only."
}/v1/image/convert2 creditsLiveConvert between JPEG, PNG, WebP, AVIF
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- Required: format (jpeg|png|webp|avif). Optional: quality.
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/convert \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.png" \ -F "format=webp" \ -F "quality=82" \ --output converted.webp
HTTP 200
Content-Type: image/webp
Content-Disposition: inline; filename="converted.webp"
X-Request-Id: req_…
X-FatBaby-Credits-Used: …
X-FatBaby-Credits-Remaining: …
<body = binary image bytes>
# Dashboard logs store metadata only, e.g.:
{
"kind": "image",
"content_type": "image/webp",
"filename": "converted.webp",
"size_bytes": 184320,
"credits_used": 2,
"credits_remaining": 98,
"note": "Binary image output is not stored in logs; metadata only."
}/v1/image/thumbnail2 creditsLiveAttention-cropped square/rect thumbnails
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- Optional: width/height (default 320), format (default webp), quality.
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/thumbnail \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.jpg" \ -F "width=320" \ -F "height=320" \ -F "format=webp" \ -F "quality=80" \ --output thumb.webp
HTTP 200
Content-Type: image/webp
Content-Disposition: inline; filename="thumbnail.webp"
X-Request-Id: req_…
X-FatBaby-Credits-Used: …
X-FatBaby-Credits-Remaining: …
<body = binary image bytes>
# Dashboard logs store metadata only, e.g.:
{
"kind": "image",
"content_type": "image/webp",
"filename": "thumbnail.webp",
"size_bytes": 184320,
"credits_used": 2,
"credits_remaining": 98,
"note": "Binary image output is not stored in logs; metadata only."
}/v1/image/strip-metadata1 creditLiveRemove EXIF/IPTC/XMP by re-encoding
- Create an API key in the dashboard and copy the fb_live_… (or fb_test_…) secret.
- Send Authorization: Bearer <key> on every request to https://thefatbaby.com/api.
- POST multipart/form-data with field name file (max 20 MB; JPEG/PNG/WebP/AVIF/GIF).
- No extra fields — upload only; response is a re-encoded image without metadata.
- For transform endpoints, save the binary response body (--output). Image info returns JSON.
- Read X-FatBaby-Credits-Used and X-FatBaby-Credits-Remaining (or JSON credit fields).
curl -X POST https://thefatbaby.com/api/v1/image/strip-metadata \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@photo.jpg" \ --output clean.jpg
HTTP 200
Content-Type: image/jpeg
Content-Disposition: inline; filename="clean.jpg"
X-Request-Id: req_…
X-FatBaby-Credits-Used: …
X-FatBaby-Credits-Remaining: …
<body = binary image bytes>
# Dashboard logs store metadata only, e.g.:
{
"kind": "image",
"content_type": "image/jpeg",
"filename": "clean.jpg",
"size_bytes": 184320,
"credits_used": 2,
"credits_remaining": 98,
"note": "Binary image output is not stored in logs; metadata only."
}Media Processing
Safe async FFmpeg ops via /v1/video, /v1/audio, /v1/gif and job polling under /v1/jobs. No raw commands or filters.
See Media Processing workflow for the general submit → poll → download pattern. Most operations enqueue a job; /v1/media/inspect and /validate are synchronous.
/v1/capabilities0 creditsLiveList supported media operations, limits, presets and credit rates
- Create an API key in the dashboard.
- GET /v1/capabilities with Authorization: Bearer <key> (no body).
- Use sync_operations / async_operations, presets, and credits maps to drive your client UI.
- This call is free (0 credits) and does not create a job.
curl https://thefatbaby.com/api/v1/capabilities \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"version": "1.0",
"sync_operations": ["media.inspect", "media.validate"],
"async_operations": ["video.convert", "video.compress", "…"],
"compress_presets": ["low", "medium", "high", "archive"],
"credits": { "video.convert": 5, "media.inspect": 1 }
}/v1/media/inspect1 creditLiveSync ffprobe summary (format, streams, duration, dimensions)
- Create an API key and confirm at least 1 credit.
- POST multipart file (or url) to /v1/media/inspect with Authorization: Bearer <key>.
- Read the JSON media summary (format, duration, streams). This is sync — no job polling.
- Credits are deducted immediately on success.
curl -X POST https://thefatbaby.com/api/v1/media/inspect \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4"
{
"success": true,
"media": {
"format": "mov,mp4,m4a,3gp,3g2,mj2",
"duration_sec": 12.4,
"width": 1920,
"height": 1080,
"video_streams": [{ "codec": "h264", "width": 1920, "height": 1080 }],
"audio_streams": [{ "codec": "aac", "channels": 2 }]
},
"request_id": "req_…",
"credits_used": 1
}/v1/media/validate1 creditLiveSync check against duration, dimension and size limits before processing
- Create an API key.
- POST multipart file (or url) to /v1/media/validate.
- Check valid and any errors[] against platform limits before submitting a heavy async job.
- Sync response — no job id. 1 credit on success.
curl -X POST https://thefatbaby.com/api/v1/media/validate \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4"
{
"success": true,
"valid": true,
"errors": [],
"media": { "duration_sec": 12.4, "width": 1920, "height": 1080 },
"request_id": "req_…",
"credits_used": 1
}/v1/video/convert5 creditsLiveAsync convert to allowlisted container/codec. Poll GET /v1/jobs/:id
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set format (e.g. mp4) and optional video_codec (e.g. libx264).
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/convert \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mov" \ -F "format=mp4" \ -F "video_codec=libx264"
{
"success": true,
"job": {
"id": "…",
"operation": "video.convert",
"status": "queued",
"progress": 0,
"credits_reserved": 5
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/compress5 creditsLiveAsync compress with presets: low | medium | high | archive
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set preset to low, medium, high, or archive.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/compress \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "preset=medium"
{
"success": true,
"job": {
"id": "…",
"operation": "video.compress",
"status": "queued",
"progress": 0,
"credits_reserved": 5
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/resize4 creditsLiveAsync scale video to target width/height
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set width and/or height. Optional fit/scale options per capabilities.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/resize \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "width=1280" \ -F "height=720"
{
"success": true,
"job": {
"id": "…",
"operation": "video.resize",
"status": "queued",
"progress": 0,
"credits_reserved": 4
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/crop4 creditsLiveAsync crop to a rectangular region
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Provide crop region fields (width, height, x, y) as documented in capabilities.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/crop \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "width=1080" \ -F "height=1080" \ -F "x=420" \ -F "y=0"
{
"success": true,
"job": {
"id": "…",
"operation": "video.crop",
"status": "queued",
"progress": 0,
"credits_reserved": 4
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/trim3 creditsLiveAsync trim by start + duration/end (seconds or HH:MM:SS)
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set start and duration (or end). Values may be seconds or HH:MM:SS.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/trim \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "start=00:00:05" \ -F "duration=10"
{
"success": true,
"job": {
"id": "…",
"operation": "video.trim",
"status": "queued",
"progress": 0,
"credits_reserved": 3
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/merge6 creditsLiveAsync concatenate multiple inputs into one file
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Upload multiple files via multipart field files (or repeated file uploads) in the desired order.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/merge \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "files=@part1.mp4" \ -F "files=@part2.mp4"
{
"success": true,
"job": {
"id": "…",
"operation": "video.merge",
"status": "queued",
"progress": 0,
"credits_reserved": 6
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/thumbnail2 creditsLiveAsync extract a still frame as an image
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Optional: time/timestamp for the frame, output format/size.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/thumbnail \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "time=00:00:02"
{
"success": true,
"job": {
"id": "…",
"operation": "video.thumbnail",
"status": "queued",
"progress": 0,
"credits_reserved": 2
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/watermark5 creditsLiveAsync overlay an image watermark on video
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Upload video as file and watermark image as a second multipart file (e.g. watermark). Optional position/opacity.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/watermark \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "watermark=@logo.png" \ -F "position=bottom-right"
{
"success": true,
"job": {
"id": "…",
"operation": "video.watermark",
"status": "queued",
"progress": 0,
"credits_reserved": 5
},
"request_id": "req_…",
"credits_used": 0
}/v1/jobs0 creditsLiveList your async media jobs with optional status filter
- Authenticate with Authorization: Bearer <key>.
- GET /v1/jobs?limit=20&offset=0 (optional status=queued|processing|completed|failed|cancelled).
- Iterate jobs[] to build a dashboard or resume polling for in-flight work.
- Free (0 credits).
curl "https://thefatbaby.com/api/v1/jobs?limit=20" \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"success": true,
"jobs": [
{ "id": "…", "operation": "video.convert", "status": "completed", "progress": 100 }
]
}/v1/jobs/:jobId0 creditsLivePoll async media job status, progress and signed download URLs
- After submitting an async op, note job.id from the create response.
- GET /v1/jobs/:jobId with your API key every few seconds while status is queued or processing.
- When status is completed, use job.output.downloads[].url or the download endpoint.
- Free (0 credits).
curl https://thefatbaby.com/api/v1/jobs/JOB_ID \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"success": true,
"job": {
"id": "JOB_ID",
"status": "completed",
"progress": 100,
"output": {
"primary": "converted.mp4",
"files": ["converted.mp4"],
"downloads": [{ "filename": "converted.mp4", "url": "https://…/v1/jobs/JOB_ID/download?…" }]
}
}
}/v1/jobs/:jobId/download0 creditsLiveDownload an output file (API key or signed token query)
- Ensure the job status is completed and note the output filename.
- GET /v1/jobs/:jobId/download?filename=out.mp4 with Authorization, or use the signed token URL from the job payload.
- Without filename, the API returns a JSON list of available files and URLs.
- Save the binary body with curl --output. Free (0 credits).
curl "https://thefatbaby.com/api/v1/jobs/JOB_ID/download?filename=converted.mp4" \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ --output converted.mp4
HTTP 200
Content-Type: video/mp4
Content-Disposition: attachment; filename="converted.mp4"
<body = binary file bytes>
# Or without filename:
{
"success": true,
"job_id": "JOB_ID",
"files": [{ "filename": "converted.mp4", "url": "https://…" }]
}/v1/jobs/:jobId/cancel0 creditsLiveCancel a queued or processing job and release reserved credits
- Identify a job that is still queued or processing.
- POST /v1/jobs/:jobId/cancel with Authorization: Bearer <key>.
- Confirm status becomes cancelled; reserved credits are released.
- Jobs already completed or failed are not cancellable (409).
curl -X POST https://thefatbaby.com/api/v1/jobs/JOB_ID/cancel \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"success": true,
"job": { "id": "JOB_ID", "status": "cancelled", "progress": 0 }
}/v1/audio/extract3 creditsLiveAsync extract audio track (mp3/aac/wav/flac/…)
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set format (e.g. mp3, aac, wav, flac).
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/audio/extract \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "format=mp3"
{
"success": true,
"job": {
"id": "…",
"operation": "audio.extract",
"status": "queued",
"progress": 0,
"credits_reserved": 3
},
"request_id": "req_…",
"credits_used": 0
}/v1/audio/normalize3 creditsLiveAsync loudness / level normalization
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Upload audio or video with an audio track; optional target loudness if supported.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/audio/normalize \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@track.wav"
{
"success": true,
"job": {
"id": "…",
"operation": "audio.normalize",
"status": "queued",
"progress": 0,
"credits_reserved": 3
},
"request_id": "req_…",
"credits_used": 0
}/v1/gif/from-video4 creditsLiveAsync palette GIF from a short clip window
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Set start, duration, and optional width for the GIF window.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/gif/from-video \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "start=0" \ -F "duration=3" \ -F "width=480"
{
"success": true,
"job": {
"id": "…",
"operation": "gif.from-video",
"status": "queued",
"progress": 0,
"credits_reserved": 4
},
"request_id": "req_…",
"credits_used": 0
}/v1/stream/hls8 creditsLiveAsync HLS packaging (alias of /v1/video/hls)
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Upload source video; wait for completed job then download the HLS package / playlist artifacts.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/stream/hls \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4"
{
"success": true,
"job": {
"id": "…",
"operation": "video.hls",
"status": "queued",
"progress": 0,
"credits_reserved": 8
},
"request_id": "req_…",
"credits_used": 0
}/v1/video/subtitles/burn5 creditsLiveAsync hard-burn SRT/VTT into the video picture
- Create an API key and confirm your credit balance covers the operation.
- POST multipart/form-data (file and options) with Authorization: Bearer <key>.
- Upload video as file and subtitle file (e.g. subtitles=@captions.srt). Alias also under /v1/subtitles/burn.
- Read job.id from the JSON response (status is usually queued). Credits are reserved, not yet captured.
- Poll GET /v1/jobs/:jobId until status is completed (or failed / cancelled).
- Download via signed URLs in job.output.downloads, or GET /v1/jobs/:jobId/download?filename=…
- On success, reserved credits are captured; cancel/fail releases per policy.
curl -X POST https://thefatbaby.com/api/v1/video/subtitles/burn \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4" \ -F "subtitles=@captions.srt"
{
"success": true,
"job": {
"id": "…",
"operation": "video.subtitles.burn",
"status": "queued",
"progress": 0,
"credits_reserved": 5
},
"request_id": "req_…",
"credits_used": 0
}Developer
Fast utilities for common backend and automation tasks.
/v1/json/validate1 creditLiveValidate and parse JSON payloads
- Create an API key in the dashboard.
- POST application/json with a json string field, or send a raw JSON object/array as the body.
- Read valid and parsed. Invalid JSON still returns HTTP 200 with valid: false and consumes 1 credit.
- Use request_id and credit fields for logging.
curl -X POST https://thefatbaby.com/api/v1/json/validate \
-H "Authorization: Bearer fb_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"json":"{\"name\":\"FatBaby\",\"ok\":true}"}'{
"valid": true,
"parsed": {
"name": "FatBaby",
"ok": true
},
"request_id": "req_…",
"credits_used": 1,
"credits_remaining": 99
}Video & audio (FFmpeg)
Legacy async FFmpeg jobs: create a job, upload inputs, run a command, poll status, download outputs.
See Legacy render workflow: create job, upload file, start command, poll, download. Prefer Media Processing unless you need a custom allowlisted ffmpeg command.
/v1/render/job1 creditLiveCreate job folders (input/output/temp). Alias: POST /v1/render/jobs
- This is step 1 of the legacy pipeline (create → upload → render → poll → download).
- POST /v1/render/job with Authorization: Bearer <key> (no body required). Alias: POST /v1/render/jobs.
- Save job_id and the returned input/output/temp paths for later upload and render steps.
- Next: upload with POST /v1/render/upload/:jobId. Costs 1 credit to create the job workspace.
curl -X POST https://thefatbaby.com/api/v1/render/job \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"success": true,
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"input_path": "/data/renders/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/input",
"output_path": "/data/renders/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/output",
"temp_path": "/data/renders/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/temp",
"status": "created",
"request_id": "req_…",
"credits_used": 1,
"credits_remaining": 99
}/v1/render/upload/:jobId2 creditsLiveMultipart field file into job input/. Alias: POST /v1/render/jobs/:jobId/files
- Step 2 of the legacy pipeline — you already created a job and have job_id.
- POST multipart file to /v1/render/upload/:jobId (field name file). Alias: /v1/render/jobs/:jobId/files.
- Confirm the returned path under the job input/ folder. Repeat for extra inputs if needed.
- Next: POST /v1/render/render. Costs 2 credits per upload.
curl -X POST https://thefatbaby.com/api/v1/render/upload/JOB_ID \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ -F "file=@clip.mp4"
{
"success": true,
"job_id": "JOB_ID",
"filename": "clip.mp4",
"path": "/data/renders/jobs/JOB_ID/input/clip.mp4",
"request_id": "req_…",
"credits_used": 2,
"credits_remaining": 97
}/v1/render/render5 creditsLiveAsync ffmpeg via validated command; returns render_job_id
- Build a validated ffmpeg command that only reads/writes under the job input/output/temp paths.
- POST JSON { job_id, command } to /v1/render/render.
- Save render_job_id and poll status until completed.
- Costs 5 credits when the render starts.
curl -X POST https://thefatbaby.com/api/v1/render/render \
-H "Authorization: Bearer fb_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"job_id":"JOB_ID","command":"ffmpeg -y -i /data/renders/jobs/JOB_ID/input/clip.mp4 /data/renders/jobs/JOB_ID/output/out.mp4"}'{
"success": true,
"render_job_id": "r9f8e7d6-c5b4-3210-aaaa-bbbbccccdddd",
"parent_job_id": "JOB_ID",
"status": "processing",
"output_path": null,
"request_id": "req_…",
"credits_used": 5,
"credits_remaining": 92
}/v1/render/status/:renderJobId0 creditsLivePoll async render task. Also: /render/:id/status and /status/:id/logs
- After starting a render, poll GET /v1/render/status/:renderJobId.
- Wait until status is completed (or inspect error / stderr on failure).
- Then download files from the parent job output/ folder.
- Free (0 credits).
curl https://thefatbaby.com/api/v1/render/status/RENDER_JOB_ID \ -H "Authorization: Bearer fb_live_YOUR_KEY"
{
"success": true,
"render_job_id": "RENDER_JOB_ID",
"parent_job_id": "JOB_ID",
"status": "completed",
"command": "ffmpeg -y -i …/input/clip.mp4 …/output/out.mp4",
"output_path": null,
"started_at": "2026-09-07T12:00:00.000Z",
"completed_at": "2026-09-07T12:00:18.000Z",
"error": null,
"stdout": "",
"stderr": "…ffmpeg progress…",
"request_id": "req_…",
"credits_used": 0,
"credits_remaining": 92
}/v1/render/download/:jobId/:filename0 creditsLiveDownload a file from job output/. Alias: /jobs/:jobId/download/:filename
- When render status is completed, note the output filename under the parent job.
- GET /v1/render/download/:jobId/:filename with Authorization.
- Save the binary response. Free (0 credits).
curl https://thefatbaby.com/api/v1/render/download/JOB_ID/out.mp4 \ -H "Authorization: Bearer fb_live_YOUR_KEY" \ --output out.mp4
HTTP 200 Content-Type: video/mp4 Content-Disposition: attachment; filename="out.mp4" X-Request-Id: req_… X-FatBaby-Credits-Used: 0 X-FatBaby-Credits-Remaining: 92 <body = binary file bytes>
Limits
- Image upload size: 20 MB per request
- Image dimension cap: 10,000 px per side (configurable server-side)
- Image pixel budget: 40,000,000 pixels
- Media duration, resolution and upload caps apply — check
GET /v1/capabilities - IP and per-API-key rate limits apply
Roadmap
Same authentication and credits. Paths below are reserved so you can plan integrations.
- Compress —
/v1/pdf/compress - Merge —
/v1/pdf/merge - Split —
/v1/pdf/split - Extract pages —
/v1/pdf/extract-pages - PDF ↔ images —
/v1/pdf/pdf-images - Metadata —
/v1/pdf/metadata
More developer tools
- JSON format/minify —
/v1/tools/json-format-minify - CSV ↔ JSON —
/v1/tools/csv-json - Hashing —
/v1/tools/hashing - Base64 —
/v1/tools/base64 - QR codes —
/v1/tools/qr-codes - UUID —
/v1/tools/uuid
