Skip to content

One-time results (delete on download) ​

By default the web Studio saves every variant to your FluidGhost Drive. The API can do the opposite: run a job whose results never touch your Drive and exist only as one-time download links that delete the moment you download them. This guide covers that flow end to end.

When to use it ​

Reach for ephemeral delivery when you want the result and nothing else — no archive, no cleanup, no footprint in your Drive. You uniquify a photo, pull it into your pipeline, and the link is spent. If you'd rather keep a browsable history, use drive delivery instead (see Delivery modes).

How it works ​

Add delivery: ephemeral to the job. Three rules govern the result's lifetime:

  1. Delete on successful download. Each variant's downloadUrl streams the bytes and, only after a fully successful transfer, deletes the object. The link is one-time.
  2. Interrupted downloads survive. If the connection drops mid-transfer, the object is not deleted — you can retry within the hour. Deletion is gated on a complete download, so a half-download never costs you the result.
  3. One-hour fallback. Anything never downloaded is purged after one hour, whichever comes first. Nothing lingers even if you never fetch it.

For a multi-copy job, each variant gets its own link and deletes on its own download — grabbing variant 0 doesn't affect variants 1 and 2.

Job (delivery: ephemeral)
├── variant 0 → downloadUrl ──(successful GET)──▶ bytes returned, object deleted
├── variant 1 → downloadUrl ──(never fetched)───▶ purged at T+1h
└── variant 2 → downloadUrl ──(GET drops mid-stream)─▶ kept; retry OK until T+1h

Submit an ephemeral job ​

bash
API="https://api-ghost.fluidvip.com/api"

curl -s -X POST "$API/jobs" \
  -H "Authorization: Bearer $FLUIDGHOST_KEY" \
  -F "[email protected]" \
  -F "recipeId=full-refresh" \
  -F "copies=3" \
  -F "delivery=ephemeral"
json
{ "jobId": "8f3c…", "statusUrl": "/jobs/8f3c…" }

Poll GET /jobs/{id} as usual. For ephemeral jobs, each completed variant carries a downloadUrl instead of a persistent url:

json
{
  "jobId": "8f3c…",
  "status": "completed",
  "progress": { "done": 3, "total": 3 },
  "variants": [
    { "index": 0, "status": "completed", "fileName": "IMG_4827.JPG", "downloadUrl": ".../jobs/8f3c…/download/0", "expiresAt": "2026-07-03T15:04:00Z" },
    { "index": 1, "status": "completed", "fileName": "IMG_4828.JPG", "downloadUrl": ".../jobs/8f3c…/download/1", "expiresAt": "2026-07-03T15:04:00Z" },
    { "index": 2, "status": "completed", "fileName": "IMG_4829.JPG", "downloadUrl": ".../jobs/8f3c…/download/2", "expiresAt": "2026-07-03T15:04:00Z" }
  ]
}

expiresAt is the one-hour fallback deadline for that variant.

Download each variant ​

Fetch the downloadUrl with your API key. A 200 returns the bytes; on success the object is deleted server-side.

bash
curl -s "$API/jobs/8f3c…/download/0" \
  -H "Authorization: Bearer $FLUIDGHOST_KEY" \
  -o IMG_4827.JPG

The response sets Content-Disposition with the variant's device-authentic fileName, so a browser or curl -OJ names the file correctly.

What you get back ​

StatusMeaningWhat to do
200Bytes streamed; object deleted on completion.You're done.
410 GoneAlready downloaded (or expired).The result is spent — resubmit the job if you need it again.
404 not_foundNo such job/variant, or not yours.Check the id; results also 404 after the 1h purge.

Handle retries correctly ​

Because deletion is gated on a successful transfer, a dropped download is safe to retry:

python
import requests

def fetch_once(url, key, path):
    with requests.get(url, headers={"Authorization": f"Bearer {key}"}, stream=True) as r:
        if r.status_code == 410:
            raise RuntimeError("already downloaded — result is spent")
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(1 << 16):
                f.write(chunk)   # object is deleted only after this completes

# a network blip raises before completion → the object still exists → retry is fine

Do not retry on a 410 — that means a previous download already completed and consumed the result. Only retry on network errors or 5xx.

Notes & limits ​

  • Cost is the same as drive delivery — you pay per variant for the uniquify compute, not for storage. Ephemeral just skips the Drive write.
  • No history. Ephemeral results don't appear in your Drive or the dashboard. GET /jobs still lists the job itself while it's live, but the bytes are gone once downloaded or expired.
  • Keep the ids. Once you have a downloadUrl, download promptly — there's no way to re-issue a link for a purged result. If you need durability, use drive.

FluidGhost API — part of the Fluidvip ecosystem.