Appearance
API reference — conventions
This section documents every endpoint. Read this page first — it covers the base URL, auth, request formats, the response and error envelopes, and the shared object shapes every endpoint reuses.
Base URL
https://api-ghost.fluidvip.com/apiEvery path below is relative to that base. So POST /jobs is POST https://api-ghost.fluidvip.com/api/jobs.
Authentication
Send your API key as a bearer token on every request:
Authorization: Bearer fg_sk_live_…See Authentication. Missing/invalid → 401 unauthorized.
Request formats
- Job creation and inspection accept
multipart/form-data(to carry the file upload). Non-file fields likerecipeId,copies,delivery,options, andrecipeConfigare form fields; object fields (options,recipeConfig) are JSON-encoded strings in multipart. - File-free job creation (using a pre-uploaded
inputKey) also acceptsapplication/json, where object fields are real JSON objects. - Reads (
GET) take no body.
Success responses
Endpoints return their payload directly as JSON, with a conventional HTTP status:
POST /jobs→202 Acceptedwith{ jobId, statusUrl }.GETreads →200 OKwith the resource.
Error envelope
Errors return a flat JSON body:
json
{
"error": "insufficient_balance",
"message": "Not enough balance for this job.",
"details": { "balance": 0.4, "required": 3 }
}error— a machine-readable code that maps to the HTTP status.message— a human-readable explanation.details— present on some errors (validation findings, balance shortfall). Optional.
The full code table is in Errors.
Shared object shapes
These appear across multiple endpoints.
Variant
One produced result within a job.
| Field | Type | Notes |
|---|---|---|
index | integer | 0-based position in the batch. |
status | processing | completed | failed | Per-variant state. |
fileName | string | Device-authentic download name (e.g. IMG_4827.HEIC). Absent on older results. |
url | string | Persistent served URL (drive delivery). |
downloadUrl | string | One-time download link (ephemeral delivery). Deletes on successful download. |
expiresAt | string (ISO-8601) | Fallback purge time for an ephemeral variant. |
error | string | Failure reason (present when status: failed). |
previewKey / previewUrl | string | Browser-playable H.264 preview for a video result. |
videoUrl / videoMp4Url / contentIdentifier | string | Live Photo companion video(s) + pairing UUID (live captures). |
detectionRisk | number 0–100 | Similarity-vs-original score; higher = more detectable. |
riskBand | low | medium | high | Coarse band. |
riskAudit | object | Per-hash distances behind the score. |
metadataRisk | object | { severity, tells[] } — lingering metadata tells. |
copyCollision | boolean | true if this copy couldn't be fully separated from a sibling (its distinctness ceiling was hit). |
Progress
| Field | Type | Notes |
|---|---|---|
done | integer | Variants settled (succeeded or failed). |
total | integer | Variants this job will produce (= copies). |
stoppedEarly | boolean | Ultra Safe circuit breaker tripped; done < total valid variants produced. |
stoppedReason | string | Human-readable reason when stoppedEarly. |
Job status
| Field | Type | Notes |
|---|---|---|
jobId | string | The job's id. |
status | queued | processing | completed | partial | failed | Lifecycle state; the last three are terminal. |
progress | Progress | See above. |
variants | Variant[] | Per-variant results, filled in as they settle. |
error | string | Present when the whole job failed. |
Endpoints at a glance
| Method & path | Purpose |
|---|---|
POST /jobs | Submit a spoof job (photo, video, or a carousel slide). |
GET /jobs | List your recent jobs. |
GET /jobs/{id} | Poll a job's status. |
GET /jobs/{id}/download/{variant} | Download a one-time (ephemeral) variant. |
GET /options | The option vocabulary + limits + starter recipes. |
GET /me | Your account balance + tier. |