Generations

Create a generation, follow it, and download the result.

A generation is one job: one photo in, one finished image out.

Create a generation

Terminal
curl https://api.foodshot.ai/v1/generations \
  -H "Authorization: Bearer $FOODSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f0c2b7e-9a4d-4c1b-8e3f-6d2a1b9c7e40" \
  -d '{
    "image_url": "https://docs.foodshot.ai/samples/dish.jpg",
    "style_id": "pure-shot",
    "metadata": { "dish_id": "d_456" }
  }'
FieldWhat to send
image_url or image_base64The photo: an https URL, or the file in base64. JPEG, PNG, WebP or HEIC.
style_idA style id from GET /v1/styles.
instructionOptional. A short note in plain words, such as Keep the blue bowl. See Instructions.
aspect_ratioOptional. 1:1 (default), 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 or 21:9.
resolutionOptional. 4k (default) or 2k. Both cost 1 credit. See the result sizes.
formatOptional. jpeg (default) or png: the file type of the result.
metadataOptional. Up to 10 string pairs, such as your dish id. We send them back with the result.

Send one of image_url or image_base64, and a style_id, an instruction or both.

The answer is 202 Accepted with the new generation, in queued status. It usually comes within seconds. Use a client timeout of 60 seconds.

Idempotency

Every create needs an Idempotency-Key header: one new UUID per photo.

  • Retry with the same key and the same body. Within 24 hours you get the same generation back, and nothing is charged again.
  • The same key with a different body gets 409 idempotency_conflict.
  • After a failed job, use a new key to try again.

Statuses

queued → processing → succeeded or failed

succeeded and failed are final. A failed job is refunded, and error.code says why.

Our objective is about 30-40 seconds once a job starts; it is an objective, not a promise, and 4K jobs usually take a little longer than 2K. Up to 5 jobs per account run at the same time; the others wait in your queue.

Get the result

The best way is a webhook. To poll instead, get the generation about 20 seconds after you created it, then every 5 seconds until it is final.

Terminal
curl https://api.foodshot.ai/v1/generations/$GENERATION_ID \
  -H "Authorization: Bearer $FOODSHOT_API_KEY"

A succeeded generation, shortened:

JSON
{
  "id": "gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw",
  "status": "succeeded",
  "metadata": { "dish_id": "d_456" },
  "output": {
    "url": "https://api.foodshot.ai/v1/files/gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw/image.jpg?exp=…&sig=…",
    "content_type": "image/jpeg",
    "width": 4096,
    "height": 4096
  },
  "error": null
}

The fields you need most:

  • output.url is a link to the file. It needs no key and works for 24 hours; every GET returns a fresh one.
  • output.content_type is image/jpeg or image/png. Name the file by it.
  • error.code says why a job failed. See Errors.
  • metadata is what you sent.

Download the file from your server and keep your own copy: we delete it after 30 days. A download is cut off after 60 seconds, and an expired link answers 403 permission_denied: get the generation again for a fresh link. Every field is in the API reference.

To catch up after downtime, list your generations by status and created_gte.

Instructions

instruction is a short note in plain words, such as Keep the blue bowl or Make the background darker.

  • With a style_id, it adjusts the style.
  • Without a style_id, it describes the whole look. Results are less predictable than with a style.
  • Don't use it to add food that isn't in the photo, or for personal information.

On this page