Skip to main content
Shelf analysis is the core capability of the Shelfforce API. You submit an image of a retail shelf, and Shelfforce returns structured data for every product detected — including brand, description, category, facing count, price, promotional status, confidence score, and fixture type. This guide walks through the full analysis workflow.

How it works

Shelfforce uses a multi-step vision pipeline to analyze shelf images:
  1. Extraction — Identifies unique SKUs visible on the shelf.
  2. Product Detail — Determines facing counts and shelf positions for each product.
  3. Price Attribution — Reads all price tags and matches them to the correct products using spatial reasoning.
  4. Summary — Computes brand-level share-of-shelf metrics and totals.
The entire pipeline runs automatically when you submit an image. You receive the complete results when the analysis finishes.

The analysis lifecycle

Analysis is asynchronous. Here is exactly what happens from submission to results:
┌─────────────────────────────────────────────────────────────┐
│  1. POST /api/v1/analyses                                   │
│     You submit an image URL                                 │
│     → Response: { status: "processing", id: "an_..." }      │
│                                                             │
│  2. Processing (10-30 seconds)                              │
│     Shelfforce runs extraction → detail → pricing → summary │
│                                                             │
│  3. Results ready                                           │
│     ┌─ Option A: Poll GET /api/v1/analyses/:id              │
│     │  Loop every 3-5s until status = "completed"           │
│     │  Best for: quick testing, scripts, simple integrations│
│     │                                                       │
│     └─ Option B: Webhook notification                       │
│        Register for analysis.completed event                │
│        Best for: production systems, high volume            │
│                                                             │
│  4. Read the products array from the completed response     │
└─────────────────────────────────────────────────────────────┘
Typical processing time: 10-30 seconds, depending on image complexity (number of products, price tag legibility, image resolution). High-resolution images with many products may take up to 45 seconds.
Which result method should I use?
  • Polling is simpler and great for scripts, CLI tools, and quick testing. Poll every 3-5 seconds.
  • Webhooks are more efficient for production. No wasted requests, instant notification. See Webhooks.

Step 1: Submit an image

Send a POST request to the analyses endpoint with the URL of a shelf image:
curl -X POST https://shelfforce.ai/api/v1/analyses \
  -H "Authorization: Bearer sf_live_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/shelf.jpg"
  }'

Request parameters

ParameterTypeRequiredDescription
imageUrlstringYesPublicly accessible URL of the shelf image. JPEG, PNG, and WebP are supported.
placeIdstringNoShelfforce place ID to associate with this analysis.
taskIdstringNoShelfforce task ID to associate with this analysis.

Response

The response comes back immediately. The status is processing while the analysis runs.
{
  "data": {
    "id": "an_g7h8j9k0",
    "status": "processing",
    "createdAt": "2026-02-23T10:30:00Z"
  }
}
One credit is consumed per analysis submission. See Credits for details.

Step 2: Get the results

Option A: Polling

Poll the analysis endpoint until the status is completed:
curl https://shelfforce.ai/api/v1/analyses/an_g7h8j9k0 \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."

Option B: Webhooks

Register a webhook for analysis.completed and Shelfforce will POST the result to your URL as soon as processing finishes. No polling needed.
# Register once
curl -X POST https://shelfforce.ai/api/v1/webhooks \
  -H "Authorization: Bearer sf_live_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/shelfforce",
    "events": ["analysis.completed", "analysis.failed"]
  }'
When the analysis completes, you receive a POST like this:
{
  "event": "analysis.completed",
  "data": {
    "generationId": "an_g7h8j9k0",
    "status": "completed",
    "productCount": 12,
    "createdAt": "2026-02-23T10:30:00Z"
  },
  "timestamp": "2026-02-23T10:32:00Z",
  "webhookId": "wh_abc123"
}
Then fetch the full results using the generationId:
curl https://shelfforce.ai/api/v1/analyses/an_g7h8j9k0 \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."
See the Webhooks guide for full setup, payload examples, signature verification, and receiver code.

Completed response

{
  "data": {
    "id": "an_g7h8j9k0",
    "status": "completed",
    "totalRuns": 1,
    "completedRuns": 1,
    "failedRuns": 0,
    "productCount": 12,
    "createdAt": "2026-02-23T10:30:00Z",
    "completedAt": "2026-02-23T10:32:00Z",
    "products": [
      {
        "id": "prd_k1l2m3",
        "sku": "CC-330ML-CAN",
        "brand": "Coca-Cola",
        "description": "Coca-Cola Original 330ml Can",
        "category": "Beverages",
        "subcategory": "Carbonated Soft Drinks",
        "price": 1.49,
        "currency": "USD",
        "onSale": false,
        "units": 4,
        "confidence": 0.95,
        "shelfPosition": "eye-level",
        "fixtureType": "shelf"
      }
    ]
  }
}

Step 3: Work with product data

Product fields

Each product in the products array includes:
FieldTypeDescription
idstringUnique product detection identifier
skustring | nullMatched SKU from your inventory, if identified
brandstringDetected brand name
descriptionstringFull product description as detected on shelf
categorystring | nullProduct category
subcategorystring | nullProduct subcategory
pricenumber | nullDetected shelf price. Null if no price tag was found
discountedPricenumber | nullPromotional/sale price if on sale
currencystring | nullISO 4217 currency code
onSaleboolean | nullWhether the product appears to be on promotion
unitsnumberNumber of visible facings on the shelf
confidencenumber | nullDetection confidence score (0.0 to 1.0)
shelfPositionstring | nullVertical position: top, eye-level, middle, bottom
fixtureTypestring | nullWhere the product was found: shelf, fridge, floor-display, other

Query products across analyses

To retrieve products across multiple analyses, use the products endpoint with optional filters:
# By analysis
curl "https://shelfforce.ai/api/v1/products?analysisId=an_g7h8j9k0" \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."

# By brand
curl "https://shelfforce.ai/api/v1/products?brand=Coca-Cola" \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."

# With pagination
curl "https://shelfforce.ai/api/v1/products?limit=50" \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."

Step 4: View reports

Query aggregated share-of-shelf reports:
curl "https://shelfforce.ai/api/v1/reports/share-of-shelf?days=30&brands=Coca-Cola,Pepsi" \
  -H "Authorization: Bearer sf_live_a1b2c3d4..."
{
  "data": {
    "brands": [
      {
        "brand": "Coca-Cola",
        "units": 342,
        "sharePercent": 28.5,
        "productCount": 8
      },
      {
        "brand": "Pepsi",
        "units": 288,
        "sharePercent": 24.0,
        "productCount": 6
      }
    ],
    "totalUnits": 1200,
    "periodDays": 30,
    "periodStart": "2026-01-24T00:00:00Z",
    "periodEnd": "2026-02-23T23:59:59Z"
  }
}

Image requirements

For best results, follow these guidelines when capturing shelf images:

Do

  • Capture the full shelf section in frame
  • Ensure products and price tags are legible
  • Use good lighting with minimal glare
  • Shoot from directly in front of the shelf

Avoid

  • Blurry or out-of-focus images
  • Extreme angles that distort product labels
  • Heavy shadows or reflections obscuring products
  • Partial shelf captures that cut off products
Supported formats: JPEG, PNG, WebP Recommended resolution: 1920x1080 or higher. Higher resolution images produce more accurate results, especially for reading price tags.

Analysis statuses

StatusDescription
processingThe analysis is running. Poll again or wait for a webhook.
completedThe analysis finished successfully. Products and summary are available.
failedThe analysis could not produce results. Check the error field for details.

Next steps