Skip to main content
When you need to analyze multiple shelf photos — for example, every aisle in a store or photos from a field team’s daily route — use the batch endpoint to submit up to 20 images in a single request.

When to use batch

  • Processing a set of photos from a single store visit
  • Analyzing images uploaded by field teams throughout the day
  • Running periodic audits across multiple locations
  • Any workflow where you have multiple images ready to submit at once

Submitting a batch

Send a POST request to the batch analyses endpoint with an array of images:
curl -X POST https://shelfforce.ai/api/v1/analyses/batch \
  -H "Authorization: Bearer sf_live_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      {
        "imageUrl": "https://example.com/store-42/aisle-1.jpg",
        "metadata": { "store": "store-42", "aisle": "1" }
      },
      {
        "imageUrl": "https://example.com/store-42/aisle-2.jpg",
        "metadata": { "store": "store-42", "aisle": "2" }
      },
      {
        "imageUrl": "https://example.com/store-42/aisle-3.jpg",
        "metadata": { "store": "store-42", "aisle": "3" }
      }
    ]
  }'

Request parameters

ParameterTypeRequiredDescription
imagesarrayYesArray of image objects (1-20 items).
images[].imageUrlstringYesPublicly accessible URL of the shelf image.
images[].metadataobjectNoArbitrary key-value pairs to attach to this analysis.
images[].idempotencyKeystringNoUnique key to prevent duplicate submissions (see below).
callbackUrlstringNoURL to receive a webhook for each completed analysis.

Response

{
  "batchId": "batch_1a2b3c4d",
  "analyses": [
    {
      "id": "an_001",
      "status": "processing",
      "imageUrl": "https://example.com/store-42/aisle-1.jpg",
      "metadata": { "store": "store-42", "aisle": "1" }
    },
    {
      "id": "an_002",
      "status": "processing",
      "imageUrl": "https://example.com/store-42/aisle-2.jpg",
      "metadata": { "store": "store-42", "aisle": "2" }
    },
    {
      "id": "an_003",
      "status": "processing",
      "imageUrl": "https://example.com/store-42/aisle-3.jpg",
      "metadata": { "store": "store-42", "aisle": "3" }
    }
  ],
  "creditsConsumed": 3,
  "createdAt": "2026-02-23T10:30:00Z"
}
Each image in the batch creates a separate analysis with its own ID. The analyses run in parallel.

Credit handling

Batch analysis uses an all-or-nothing credit check:
  • Each image costs 1 credit (same as a single analysis).
  • Before processing begins, Shelfforce verifies you have enough credits for the entire batch.
  • If you do not have enough credits, the entire request is rejected — no images are analyzed and no credits are consumed.
// Submitting 10 images with only 5 credits remaining:
{
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "message": "Insufficient credits. This batch requires 10 credits but you have 5 remaining.",
    "details": {
      "required": 10,
      "available": 5
    }
  }
}

Retrieving results

Each analysis in the batch has its own ID. Poll individual analyses for results:
curl https://shelfforce.ai/api/v1/analyses/an_001 \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."
Or use webhooks to be notified as each analysis completes. If you provided a callbackUrl in the batch request, you will receive a separate webhook for each image as it finishes.

Checking batch status

You can also query the batch endpoint to see the status of all analyses in the batch:
curl https://shelfforce.ai/api/v1/analyses/batch/batch_1a2b3c4d \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."
{
  "batchId": "batch_1a2b3c4d",
  "status": "partial",
  "total": 3,
  "completed": 2,
  "processing": 1,
  "failed": 0,
  "analyses": [
    { "id": "an_001", "status": "completed" },
    { "id": "an_002", "status": "completed" },
    { "id": "an_003", "status": "processing" }
  ]
}
The batch status is one of:
  • processing — All analyses are still running.
  • partial — Some analyses have completed, others are still running.
  • completed — All analyses have finished (either completed or failed).

Idempotency keys

Use idempotency keys to safely retry batch requests without creating duplicate analyses. If a request with the same idempotency key is submitted again, Shelfforce returns the existing analysis instead of creating a new one.
{
  "images": [
    {
      "imageUrl": "https://example.com/shelf.jpg",
      "idempotencyKey": "store-42-aisle-1-2026-02-23"
    }
  ]
}
Idempotency keys are scoped to your organisation and expire after 24 hours. Use a combination of store, location, and date to create meaningful keys.

Best practices

Group by store visit

Submit all photos from a single store visit in one batch. This makes it easy to correlate results and reduces API calls.

Use metadata

Attach store IDs, aisle numbers, and dates as metadata so you can filter and group results later.

Use idempotency keys

Always include idempotency keys, especially when retrying failed requests or when your pipeline might submit the same image twice.

Combine with webhooks

Set a callbackUrl on the batch or register a persistent webhook for analysis.completed to avoid polling each analysis individually.

Limits

ConstraintValue
Maximum images per batch20
Maximum image file size20 MB
Supported formatsJPEG, PNG, WebP
If you need to process more than 20 images, split them into multiple batch requests. Use idempotency keys to prevent duplicates if you are retrying.