Appearance
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:
- Delete on successful download. Each variant's
downloadUrlstreams the bytes and, only after a fully successful transfer, deletes the object. The link is one-time. - 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.
- 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+1hSubmit 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, then read the links
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.JPGThe 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
| Status | Meaning | What to do |
|---|---|---|
200 | Bytes streamed; object deleted on completion. | You're done. |
410 Gone | Already downloaded (or expired). | The result is spent — resubmit the job if you need it again. |
404 not_found | No 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 fineDo 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
drivedelivery — 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 /jobsstill 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, usedrive.