Documentation
GTIN to product page in four requests.
Everything below runs as printed with a test key. Test keys behave exactly like live ones against a frozen snapshot; behavior parity is a contract, not an aspiration.
Quickstart
Four requests from a barcode to a rendered product page. Each one returns in well under a second; the last one returns HTML you can ship.
Resolve the identifier
Send whatever you have. The verdict is honest; nothing is force-matched.
$ curl https://api.getproductdata.com/v1/resolve \ -H "Authorization: Bearer gpd_test_51Hx…" -d gtin=4012345678901 → "verdict": "exact_variant", "confidence": 0.99
Fetch the dossier
Every attribute with provenance; depth and expansion are yours to shape.
$ curl ".../v1/products/gpd:family:sharp.a155u?depth=standard&locale=de-DE"Add the context
Percentiles and ready-made comparison sentences, evidence attached.
$ curl ".../v1/products/gpd:family:sharp.a155u/context" → "population": 1842, "highlights": [ "share_beaten": 0.82 ]
Render the page
Formats are renderings of one canonical dossier. The HTML is the same specimen component this site uses.
$ curl ".../v1/products/gpd:family:sharp.a155u.html?units=regional&market=de"Authentication
Bearer tokens, environment-scoped. The plaintext is shown once; revocation is global within one minute.
| Prefix | Environment | Behavior |
|---|---|---|
| gpd_live_ | Production | The live record, billed usage |
| gpd_test_ | Sandbox | Frozen snapshot, deterministic seeds, identical code paths |
Scopes: read, resolve, ingest, render:pdf, account:manage. The default key carries read and resolve; requests with insufficient scope return 403 insufficient_scope.
Versioning
Two things version independently. The API version (header GPD-Version: 2026-06-01) pins request and response shapes; breaking changes only ever ship as a new dated version. The schema release (schema_release in every payload) is the living vocabulary; it evolves additively and never breaks a parser.
Follow the vocabulary as it grows by subscribing to schema.attribute.promoted events.
API reference
The complete surface, with credit cost per call. Generated from the OpenAPI artifact in production docs; abbreviated here.
| Endpoint | Purpose | Credits |
|---|---|---|
| POST /v1/resolve | Identity from GTIN, MPN, title, or URL | 1 |
| GET /v1/products/{id} | The dossier; depth, expand, locale, units, at | 1 |
| GET /v1/products/{id}/context | Percentiles, badges, comparison sentences | 1 |
| GET /v1/products/{id}/history | Every canonical value over time | 1 |
| GET /v1/search | Lexical, semantic, structured; one endpoint | 2 |
| POST /v1/compare | 2 to 8 products, aligned under equal conditions | 2 |
| POST /v1/ingestions | Deep research: scan, standard, deep | 25 / 100 / 400 |
| POST /v1/batch | NDJSON fan-out, results as a signed file | sum · −10% ≥ 1k |
Formats: json, md, html, csv, pdf (+3 credits). Suffix sugar works everywhere: /v1/products/{id}.md.
Errors
Errors state the fact and the fix, machine-readable, with a documentation URL and request id.
| Code | Meaning |
|---|---|
| 400 qualifier_required | Filter on an attribute without pinning its required conditions; the message names the missing qualifier and a working example |
| 402 credits_exhausted | Balance below the price of the attempted call; the price is in the body |
| 409 resolve_ambiguous | Multiple candidates above threshold; candidates returned, never auto-merged |
| 410 product_merged | Identity was merged; follow superseded_by, your stored IDs keep working |
| 422 market_unsupported | No market execution for the requested market |
| 429 rate_limited | The body names the exceeded layer: burst, plan_rps, or concurrency |
Webhooks
Signed (HMAC, 5-minute tolerance), delivered at least once, ordered per resource. The events that matter:
- ingestion.completed, with what was built and its quality scores
- product.updated, diff included
- product.value_contested, the moment evidence disagrees
- product.identity_corrected, when a merge or split executes
- schema.attribute.promoted, the vocabulary growing under you, safely
Rate limits
| Plan | Sustained | Burst, 10 s | Concurrent research |
|---|---|---|---|
| Free | 5 rps | 20 | 1 |
| Pro | 50 rps | 200 | 5 |
| Scale | 250 rps | 1,000 | 25 |
Every 429 carries the limit, the remainder, the reset time, and the exceeded layer by name.
SDKs
Generated from the OpenAPI artifact; hand-written code in SDKs: zero.
$ npm install @getproductdata/sdk $ pip install getproductdata
For machines
Agents read what humans read. Every documentation page has a markdown twin; the index lives at /llms.txt and is maintained like an API surface. The OpenAPI document is the build artifact the SDKs and these docs are generated from; structured data is on every page of the site.
Crawl permissions are explicit, the bot identity is signed, and the markdown mirrors are the supported path; scraping the HTML is the slow way to get the same bytes.