Pricing
The Retail Digitals Image API is priced in credits. Buy credits up front, spend them on API calls. No monthly base fee for Standard tier — pay only for what you use.
Cost formula
Every GET /products/{barcode} charges the sum of two independent parts:
credits = Σ(scope_rate × scopes_with_data) + (per_image_rate × image_variants_that_exist)
Two query parameters control what the API attempts to return:
-
include=picks metadata scopes to request. Each scope has an independent, admin-set price. Valid values:info,hechshers,nutrition,ingredients,catalog_meta,image_meta,images.product_metais a legacy alias for all 5 fine-grained scopes at once — it is not a flat bundle rate; it simply requests those 5 scopes and each is billed independently, same as listing them explicitly.Omit
include=and every scope is requested — same asinfo,hechshers,nutrition,ingredients,catalog_meta,image_meta,images. -
variants=picks which image variants to request. Valid values:front,back,front_clean,back_clean. Omitvariants=and every available variant is requested.
Per-scope billing
You are only billed for a scope or image variant if it actually returns data for that
barcode. A requested scope that comes back empty (null, an empty array, or no active
image row) costs nothing — the cost above is computed from what was found, not from what
was asked for. Catalogue coverage is partial (roughly 20–37% of barcodes per scope), so
this matters: a ?include=nutrition call on a barcode with no nutrition data is always free,
whether or not you checked first.
This is unconditional — it applies the same way whether or not you use the metadata availability endpoints. Those endpoints exist to save you a wasted network round-trip on a sync of thousands of barcodes, not to change what you're charged on any single call.
All rates are admin-set. Fetch GET /pricing at daemon startup
and cache the values by action key. Never hard-code prices.
Metadata scope pricing keys
include= value | Rate key in /pricing | What you get |
|---|---|---|
info | products.get.info | brand, product_name, description, category, weight, country of origin, manufacturer, distributor, bracha, boolean dietary flags |
hechshers | products.get.hechshers | Array of kosher certifications with agency, logo slug, dairy/meat/pareve, extra designations |
nutrition | products.get.nutrition | Full nutrition facts (serving size, calories, macros, vitamins, DVs) |
ingredients | products.get.ingredients | Ingredient text, contains/may-contain statements, structured allergens list |
catalog_meta | products.get.catalog_meta | Catalog-authored: department, subcategory, web_description. Also delivers catalog overrides for category and product_description when set. |
product_meta (legacy alias) | — | Requests all 5 fine-grained scopes above; each is billed independently at its own rate, same as listing them explicitly. Kept for back-compat, not a discount. |
image_meta | products.get.image_meta | Per-variant availability metadata: photo date, resolution, ownership |
images | products.get.per_image | Signed image URL, charged per URL returned |
Metadata availability pricing keys
Coverage is partial — roughly 20–37% of barcodes carry any given scope — so a large sync benefits from checking what exists before fetching it. These endpoints tell you what exists first. They return booleans only, never metadata values. See Metadata availability.
| Endpoint | Rate key in /pricing | What you get |
|---|---|---|
GET /metadata/{barcode} | metadata.get.per_barcode | Field-level availability for one barcode, plus worth_requesting — the exact include= scopes that would return data |
POST /metadata/bulk-check | metadata.bulk_check.per_barcode | Scope-level availability for up to 500 barcodes per call |
POST /metadata/bulk-check with fields: true | metadata.bulk_check.fields.per_barcode | As above, broken down to individual fields |
GET /metadata/products | metadata.products.list | Barcodes filtered by metadata they have (has=) or lack (missing=), by scope or by field |
GET /metadata-fields | metadata.fields.catalogue | Catalogue of every valid scope and field, with optional coverage counts |
GET /products/{barcode} never charges for a scope that comes back empty, so prefiltering
doesn't change what a sync costs. What it saves is the network round-trip: on a 500-barcode
nutrition sync where only ~22% of the catalogue has nutrition, prefiltering with
POST /metadata/bulk-check means you make roughly 110 follow-up calls instead of 500 — the
other ~390 would have been free include=nutrition responses, but still a full HTTP
round-trip each.
Cheapest patterns for common use cases
| I want... | Call | Cost |
|---|---|---|
| Text-only sync of just nutrition | ?include=nutrition | 1 × nutrition rate |
| Category + brand for a POS index | ?include=info | 1 × info rate |
| E-commerce PDP with catalog copy + hechshers | ?include=info,hechshers,catalog_meta | info + hechshers + catalog_meta rates |
| One image URL (front only) | ?include=images&variants=front | 1 × per_image_rate |
| Full record (default) | (no params) | Sum of every scope and image variant that actually has data — never more, never a flat bundle rate |
?include=info charges at most the products.get.info rate, and nothing if that barcode has
no info data. Listing only the scopes you actually consume keeps response payloads smaller and
requests faster, even though an unneeded scope that comes back empty wouldn't have cost you
anything either.
variants= alone does nothing without include=imagesSending variants=front without include=images doesn't request any image URLs at all —
variants= only filters an images request that's already present. And since include=
defaults to every scope when omitted, dropping include= entirely still requests (and bills
for, if data exists) every metadata scope alongside the image.
Verify meta.credits_debited on every response.
Tiers
| Tier | Monthly base | Included credits | Rate limits | Support |
|---|---|---|---|---|
| Standard | $0 | Pay as you go | 60 rpm · 10k rpd | Email, 48h SLA |
| Enterprise | Custom | Custom bundle | Custom | Dedicated Slack, 4h SLA, uptime credits |
All delivered images carry the same globally-configured commercial watermark.
Credit prices
100 credits = $1.00 USD. Volume discounts:
| Package | Price | Effective rate |
|---|---|---|
| 500 credits | $5.00 | 100 / $1.00 |
| 5,000 credits | $45.00 | 111 / $1.00 (10% off) |
| 50,000 credits | $375.00 | 133 / $1.00 (25% off) |
| 500,000 credits | $3,000.00 | 166 / $1.00 (40% off) |
Credits do not expire. Refunds available within 30 days of purchase for unused credits — contact api@retaildigitals.com for the details.
Per-action costs
Live prices — fetched from /api/v1/pricing in real time. Admin changes are reflected here immediately on reload.
Failed calls (4xx / 5xx) are not charged. Live prices always available at
GET /pricing — we recommend hitting this at daemon startup
rather than hard-coding.
Sample cost calculations
These worked examples use the current live prices above. Update as you like.
Tip: For catalog sync, cache aggressively. Product metadata changes rarely — a weekly full
refresh + hourly bulk-check for new arrivals typically runs under $10/month.
Only pay for what you display
?include=images returns URLs for every available variant by default — up to 4 per
barcode (front, back, front_clean, back_clean). Add ?variants=front to fetch only the
variant you actually render. What each call charges (at current admin-set rates):
| Call | Available variants | Charged |
|---|---|---|
?include=images | 4 | 4 × per_image_rate |
?include=images&variants=front | 4 available, front requested | 1 × per_image_rate |
?include=images&variants=front,back | 4 available, 2 requested | 2 × per_image_rate |
?include=product_meta,images&variants=front | metadata + front only | per_scope_rate + per_image_rate |
If your integration only ever renders one image variant, adding variants= cuts your
per-product cost by up to 75%.
Enterprise: fixed-price contracts
Enterprise customers can convert to fixed monthly pricing based on projected volume, with included credit bundles + uptime credits + dedicated support. Contact api@retaildigitals.com to discuss.
Pricing change policy
We rarely change prices, and when we do:
- Base credit price: 60-day notice via email + changelog
- Per-action prices: 30-day notice
- Grandfathering: Prepaid credits keep their purchase-time redemption rate
We commit to never raising prices during your prepaid credit balance's redemption window.
Buying credits
- Dashboard: images.retaildigitals.com/billing
- Payment methods: Visa, MC, Amex, ACH (Enterprise only)
- Auto-recharge available — set a floor, top up automatically to a target balance
- Invoices generated monthly; NET-30 available for Enterprise