A photo is your input.
A listing is your output.
Create product drafts from photos with a small, asynchronous REST API. Upload references, poll the result and bring the structured data into your own application.
Quickstart
Set BASE_URL to your deployment origin. Submit multiple photos of the same product as one group; single-item or wholesale packaging is detected automatically.
curl "$BASE_URL/api/v1/listings" \ -H "Authorization: Bearer $SHOPSNAP_KEY" \ -H "Idempotency-Key: product-001-attempt-1" \ -F 'files=@front.jpg' \ -F 'files=@label.jpg' \ -F 'groups=[[0,1]]'
The API returns 202 Accepted with a listing ID for each product. Poll every 10 seconds until the status is completed, needs_input or failed.
curl "$BASE_URL/api/v1/listings/LISTING_ID" \ -H "Authorization: Bearer $SHOPSNAP_KEY"
Authentication
Every API request, including image downloads, requires your ShopSnap key in the Authorization: Bearer header. Request a test key from the operator. Do not use your model-provider key.
Keys access only their own account’s products. Keep keys on your server in production. The playground and sample app hold your key in memory for the current page session.
Create listings
/api/v1/listingsSend multipart/form-data. Up to 50 photos per batch, 5 reference photos per product, 10 MB per photo and 100 MB per request. Use still JPEG, PNG or WebP images.
| Field / header | Required | Description |
|---|---|---|
files | Yes | One or more image files. Repeat the field for each photo. |
groups | No | JSON array of zero-based image-index arrays. Every photo must belong to exactly one group. |
Idempotency-Key | Yes | Unique request header, 8–128 letters, digits, dots, colons, underscores or hyphens. |
[[0,1],[2]] creates two products: photos 0 and 1 describe the first; photo 2 describes the second. Without groups, every photo is a separate product. A pack of 12 items is one product.
Repeat the same key, files and grouping to safely recover from a timeout. The original request is reused. A different payload with the same key returns 409. Identical reference files in the same account and workflow revision reuse the existing product, even with a new key or reordered photos. This includes failed results. Submit improved references to create a new attempt; contact support for a workflow repair. Mixed batches reserve credits only for new products.
Read results and download images
/api/v1/listings/{id}Returns { schemaVersion, listing }. The listing contains progress, billing state and a product draft with English copy, category, source evidence, label-price tiers and image roles.
| Status | Meaning |
|---|---|
processing | Queued or running. Keep polling. |
completed | All required image roles passed automated checks. Merchant review is still required. |
needs_input | A complete image set could not be confirmed. Review partial results and submit clearer references with a new key. |
failed | Processing failed. Reserved credits are returned. |
New listings request three generated images plus the original: packaged_product (actual packaging on white), clean_product for a single product or single_item for one complete unit from a pack (unpackaged on white), and lifestyle (ordinary use, with people where appropriate). The labelled pack quantity is unchanged. Existing listings retain their original image roles, including legacy clean_group. Missing images retain their role and an explicit status.
Every draft has publishable: false. Unknown sale units, stock and online selling prices stay null. Label prices are observations, not confirmed listing prices. Generated images are not evidence of hidden physical details.
Provide useful references
Group up to five photos of the same product: the actual package, a clear unpackaged view and relevant close-ups. Manufacturer images must match the exact model and variant. When configured, unclear product views trigger one Serper image search using the product name, readable identifiers, South Africa (gl=za) and English. Up to three candidates are compared once. Only a model-matched identifier and compatible geometry can supply a reference; similar results remain unconfirmed. Results include webResearch with source links. Web references do not change extracted facts or label prices. A generic product name cannot establish socket geometry or hidden parts. If packaging or a key visible feature cannot be verified, the affected images remain ungenerated and the incomplete set returns its reserved credits.
Browse your catalogue
curl "$BASE_URL/api/v1/listings?limit=20&offset=0&category=Home%20%26%20Kitchen" \ -H "Authorization: Bearer $SHOPSNAP_KEY"
Use nextOffset to paginate. The limit is 1–50. Image URLs are relative to your API origin and require the same Bearer key. Download using GET /api/v1/listings/{id}/assets/{filename}.
Credits and pricing
600 credits provide US$6.00 in processing value: 21 completed products, with 12 credits left. Single and wholesale products both cost US$0.28. Multiple reference photos of one product do not add a product charge.
Credits are reserved atomically when a batch is accepted, captured when all image roles pass automated checks, and returned for incomplete or failed image sets. The same idempotent request is never charged twice. Recoverable errors are retried automatically within saved attempt and budget limits, without additional credits. Completed images are kept. During recovery, status remains processing and recovery.message describes the current step. Polling and downloads do not consume credits.
/api/v1/accountReturns available, reserved and consumed credits plus pricing. These are test balances during the preview; checkout and real-money payments are not enabled.
Errors and limits
Errors use { error: { code, message } }. Honor Retry-After when rate limited.
| HTTP status | Meaning |
|---|---|
400 | Invalid parameters or product grouping |
401 | Missing, invalid or revoked API key |
402 | Insufficient credits; no jobs in the batch were queued |
404 | Missing resource or a resource belonging to another account |
409 | Idempotency key reused with a different payload |
413 / 415 | Upload too large or unsupported / invalid image |
429 | Rate limit, daily product limit or full queue |
500 | Internal error; retry with the same idempotency key |
Preview limits: 180 read requests and 10 upload requests per minute per account; 25 pending products per account; 100 product attempts per rolling 24 hours, including refunded attempts. Repeated failures and generation allowances can pause new processing. Existing results and downloads remain available. Follow the error code and any Retry-After header; do not repeatedly resubmit. Use server-to-server integration; permissive cross-origin browser requests and remote image-URL uploads are not supported.