Skip to content

Shoot frames and poll for results

A frame is one generated photo: your product photo, worn by a scene’s model, in the scene’s style. Starting a shoot uses one frame from your plan.

Make an idempotency key for the shoot once, then send it with the request:

Terminal window
SHOOT_KEY=$(uuidgen)
Terminal window
curl https://api.shootika.com/v1/frames \
-H "Authorization: Bearer $SHOOTIKA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SHOOT_KEY" \
-d "{\"product_id\": \"$PRODUCT_ID\", \"source_image_id\": \"$IMAGE_ID\", \"scene_id\": \"$SCENE_ID\", \"garment_photo_type\": \"flat-lay\"}"
Field Required What it is
product_id yes The product.
source_image_id yes A photo of that product, from product.images.
scene_id yes A scene whose status is ready. See Models, styles and scenes.
garment_photo_type no What the photo shows: flat-lay (the garment laid flat) or model (the garment worn).
regenerate_of no The id of an earlier frame, to record that this frame is a retry of it.

The answer is 202 with the frame in status queued. One frame is used from your allowance when the shoot starts.

Send an Idempotency-Key with every shoot, so that a retry after a network error does not cost you a second frame. To retry, send the same request with the same SHOOT_KEY; never make a new key for a retry. See Idempotency and retries.

Results are not pushed to you. Ask for the frame until it is finished:

Terminal window
curl https://api.shootika.com/v1/frames/$FRAME_ID \
-H "Authorization: Bearer $SHOOTIKA_API_KEY"

Poll every few seconds until status is ready, failed or canceled. Each poll counts toward the key’s rate limit. To follow many shoots at once, list them instead: GET /v1/frames?status=queued and GET /v1/frames?status=processing show the ones not finished yet.

status Meaning
queued Waiting to start.
processing Being made.
ready Finished.
failed Could not be made, and refunded.
canceled Stopped.

A ready frame has:

  • image: the picture, with its url, width and height;
  • ready_at: when it finished;
  • expires_at: when it is deleted unless you approve it.

Approve the frames you want to keep before expires_at. Once a frame has expired, image is null and approving it answers 409 result_purged. See Approval.

A failed frame carries an error with a code and a message. The code is one of generation_failed, generation_timeout or service_busy. A failed frame is always refunded, and credit_refunded is true.

To try again, start a new shoot and pass the failed frame’s id as regenerate_of. That is a new shoot and uses a frame.

Status Code What to do
402 quota_exceeded No frames are left. details describes the allowance. Wait for your plan to refill or change plan.
402 daily_cap_reached The store reached today’s limit. GET /v1/account shows it in quota.daily.
404 not_found The product, the photo, the scene or the regenerate_of frame is not in your store.
409 scene_generating The scene is still being prepared. Wait until it is ready.
409 scene_failed The scene could not be prepared. Request it again.
409 family_unsupported The product is not clothing.
422 source_image_too_small The photo’s short side is under 600 pixels.
422 scene_unsupported The scene does not suit this product. Pick another scene.
422 validation_error A field is missing or wrong. details names it.

The full list is on Errors and limits.

Terminal window
curl "https://api.shootika.com/v1/frames?product_id=$PRODUCT_ID&status=ready" \
-H "Authorization: Bearer $SHOOTIKA_API_KEY"

Frames are listed newest first. Filter with status, approved (true or false) and product_id; status and approved are not case sensitive. A product_id that is not a valid id answers 422 validation_error, and one that is not in your store answers 404 not_found. A product you deleted still lists its frames. The list is paged with page and page_size.