Developer documentation
Retouch AI REST API
Everything in the studio is this API. Sign up for a free key, POST a photo, download the result — no demo call, no contract, no SDK required. Credits are reserved when a job is created and automatically refunded if the job fails, so a crash can never cost you money.
Authentication
Every request carries your key in the Authorization header. Keys start with rtai_ and are shown once at creation — we store only a hash.
Authorization: Bearer rtai_<your key>
Endpoints
POST/api/retouch-ai/signup
Create an account: { "email": "you@studio.com" }. Returns your API key (once) and a free-tier credit grant. Rate-limited per IP.
GET/api/retouch-ai/ops
The live operation catalog: key, label, price in credits, availability. 1 credit = $0.01. Public — no auth needed. Each op also carries its combination rules: alone: true means it can never be combined with another op in one job, and gpu: true means it counts toward the one-GPU-op-per-job limit — use these to prevent invalid job requests up front instead of handling the 400.
POST/api/retouch-ai/jobs
Create a job. Body: { "ops": ["auto_correct","look_warm"], "contentType": "image/jpeg", "contentLength": 1234567, "params": { ... } }
Rules: 1–3 operations per job; at most one GPU-class operation; video / reel / eraser / 3D / generate / quality-score run alone. Credits are reserved atomically — the response includes creditsCharged and a presigned upload URL (PUT your bytes straight to storage; they never pass through our web servers). Reel jobs return one presigned URL per photo (assetCount 3–20); Magic Eraser returns a second URL for the painted mask; text-to-image jobs skip upload entirely.
Common params: style (ai_portrait / ai_art), background (replacement preset or #hex), prompt (ai_edit / generate — content-screened before any charge), skin/eyes/teeth/catchlights/contour/lips + skinTone (−100..100) for the face suite, fidelity (0–100, photo_rescue / face_restore — high keeps the REAL face), model: "general" (upscales without the face pass), lutStrength (custom_look), template/format/title (reels), format: "stl" (3D print export), styleTwin: "off" (per-job Style Twin opt-out).
POST/api/retouch-ai/jobs/{id}/process
Run the job after your upload completes. Photo jobs are synchronous — the call returns when done. Reel and video jobs may render asynchronously in our cloud: the call returns status: "processing" and you poll GET /jobs/{id} until it succeeds (usually a few minutes; a failed render refunds automatically).
GET/api/retouch-ai/jobs/{id}
Status + signed resultUrl (1h TTL) when succeeded. Extras where earned: resultUrls (reel pack: 9x16 / 1x1 / 16x9), stlUrl (print-ready 3D export), scene + sceneLabel (the content-aware verdict the grade used), rescue (which repair legs the Photo Rescue triage ran), error with automatic refund on failure.
POST/api/retouch-ai/preview
Free live preview: POST downscaled JPEG bytes (≤4MB) with slider params or ?effect=<preset>&w=<px>. Identical math to the paid render — what you preview is exactly what you buy.
Tool previews: ?op=photo_rescue (runs the real triage chain — the response's X-Preview-Legs header names the repairs it chose), ?op=blemish_removal, ?op=auto_crop. GPU-model tools have no free preview by design — their before/after comes from the paid run, which refunds automatically on failure.
Face-suite preview: ?face=1 plus any of skin/eyes/teeth/catchlights/contour/lips (0–100) and skinTone (−100..100) runs the exact face_retouch engine on your preview bytes, free (its own limit: 60/min). A photo with no detectable face returns a clear 400 instead of a silent no-op.
POST/api/retouch-ai/billing/topup
Body { "pack": "starter" | "pro" | "volume" } → Stripe Checkout URL. Bigger packs carry bonus credits.
GET/api/retouch-ai/ledger
Your full credit history: charges, refunds, top-ups, grants. Refund guarantee: a job that fails refunds immediately, and a job that never finishes (interrupted upload, dead run) is failed + refunded automatically within ~30 minutes — you never lose credits to a job that produced nothing.
GET/api/retouch-ai/looks
Your saved LOOKs (named slider recipes) + whether a Style Twin profile is learned. PUT replaces the list (≤20 looks, names ≤40 chars, params clamped server-side).
GET/api/retouch-ai/keys
List keys; POST mints a new one (max 5 active), DELETE revokes — the last active key cannot be revoked.
Complete example
# 1. Sign up (once) — save the key, it is shown only once
curl -s -X POST https://www.fotiqo.com/api/retouch-ai/signup \
-H "Content-Type: application/json" -d '{"email":"you@studio.com"}'
# 2. Create a job
curl -s -X POST https://www.fotiqo.com/api/retouch-ai/jobs \
-H "Authorization: Bearer rtai_..." -H "Content-Type: application/json" \
-d '{"ops":["auto_correct"],"contentType":"image/jpeg","contentLength":2048000}'
# → { "jobId": "...", "upload": { "url": "..." }, ... }
# 3. Upload the photo bytes directly to storage
curl -s -X PUT "<upload.url>" -H "Content-Type: image/jpeg" --data-binary @photo.jpg
# 4. Process
curl -s -X POST https://www.fotiqo.com/api/retouch-ai/jobs/<jobId>/process \
-H "Authorization: Bearer rtai_..."
# 5. Download
curl -s https://www.fotiqo.com/api/retouch-ai/jobs/<jobId> \
-H "Authorization: Bearer rtai_..."
# → { "status": "succeeded", "resultUrl": "https://...", "scene": "SUNSET", ... }Batch automation — hot-folder channels
Whole-shoot automation is one loop: watch a folder, create a job per new file, PUT the bytes, process, download. The API allows 120 job creations per minute per account — comfortably above a tethered camera's pace. For multi-pipeline setups, run named CHANNELS: each channel watches its own folder with its own operations and parameters (the enterprise hot-folder-server pattern, as one JSON file):
// channels.json
{
"key": "rtai_...",
"channels": [
{ "name": "weddings", "in": "D:/shoots/in",
"ops": ["auto_correct","face_retouch"], "params": { "skin": "40" } },
{ "name": "rescue", "in": "D:/bad-photos",
"ops": ["photo_rescue"], "params": { "fidelity": "85" } },
{ "name": "products", "in": "D:/products",
"ops": ["upscale_2x"], "params": { "model": "general" } }
]
}
// one process, all channels, status table every 30s:
node retouch-ai-hotfolder.mjs --config channels.jsonFailures retry three times and are never deleted from your source folder; a per-channel done/failed/pending line prints every 30 seconds.
Start free
Free credits at signup — enough to test every operation before spending a cent.
Get your API key