Base URL https://api.commonspecs.com. All /v1 endpoints require an API token. JSON in, JSON out. Every read response also carries a context block — user_goal (your saved buying goals as a ready-to-apply directive), user_market, contribution_mode — resolved server-side from your account preferences.
Authentication
Send your token as a bearer header (or X-API-Token):
Authorization: Bearer cs_live_… Requests must arrive through the edge; the origin rejects direct traffic. Missing/invalid token → 401.
POST /v1/get_product
Resolve one product by exactly one of id, url, ean, or brand + model.
curl -X POST https://api.commonspecs.com/v1/get_product \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"brand":"<brand>","model":"<model>"}' status is hit, candidates (several variants matched), or miss. A hit returns product, missing_fields, the offers list (priced for the buyer's market, best offer first — lowest landed price softened by recency), fields, low_confidence_fields, and enrichment_opportunities. Each field has value, confidence, disputed, needs_corroboration, and (when disputed) alternate_claims. Low-confidence fields always ride along in their own bucket — enrichment_opportunities names what to confirm.
POST /v1/search_products
Find products by query and/or browse a category (a category alone returns its leaderboard), ranked by quality score (best first). Paginated: page, page_size (default 10, ≤ 20).
curl -X POST https://api.commonspecs.com/v1/search_products \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"query":"<brand, model, or need>","category":"<slug from a prior response>","page_size":10}' Returns { count, page, page_size, has_more, results: [product] }, best-first — the ordering is the only quality signal; no score is serialized. A hit also carries matched_categories; a miss carries did_you_mean. Results prefer products with a confirmed offer in your market; when none has one, the same candidates return spec-ranked with top-level availability: "unconfirmed" — availability there still needs checking.
POST /v1/compare_products
Compare up to 5 products side by side.
curl -X POST https://api.commonspecs.com/v1/compare_products \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_ids":["…","…"]}' Returns products, ordered best-documented first (products[0] is the winner — no separate verdict field), and a comparison matrix ([{ field, cells: { product_id: { value, confidence } | null } }]). Scores, per-dimension winners and a rationale are deliberately not returned — reason about the trade-off from the facts.
POST /v1/submit_contribution
Submit verified specs (fields) and/or a dated price observation (offer) — at least one of the two. Identify the product as in lookup; brand+model creates it if new. Each field should carry the source_url and the verbatim snippet you read it from — that evidence earns confidence. A price never goes in fields; it is an offer.
curl -X POST https://api.commonspecs.com/v1/submit_contribution \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"brand":"<brand>","model":"<model>","source":"web",
"fields":[{"field_name":"<schema field>","value":"<value as printed>",
"source_url":"https://…","snippet":"<verbatim text>"}],
"offer":{"store":"<shop domain>","country":"<ISO 3166-1>","price":<number>,
"currency":"<ISO 4217>","availability":"in_stock","source_url":"https://…"}
}' POST /v1/flag_stale
Flag a fact or price that looks stale, wrong, or disputed. Records a review signal for curation — it never mutates the product. field_name and reason are optional.
curl -X POST https://api.commonspecs.com/v1/flag_stale \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_id":"…","field_name":"<schema field>","reason":"<what looks wrong and what you saw>"}' Account endpoints
GET /v1/categories/{slug}/schema— the public field shape of a resolved category (names, units, types); scoring weights are never exposed. There is no full category list — discover slugs via search’smatched_categories/did_you_mean.GET /v1/tokens·POST /v1/tokens·DELETE /v1/tokens/{id}— your API tokens: list (prefix + metadata only), issue (plaintext returned once), revoke.GET /v1/usage— your account usage: tier, active tokens, today’s submissions against the daily cap, lifetime contributions.GET /v1/user/preferences·PUT /v1/user/preferences— read and update the buying preferences the server applies to every read (market, quality/locality strategy, contribution mode, language).
Errors
Errors are JSON: { "error": { "code", "message" } }. Common codes: 400 invalid_request, 401 unauthorized, 403 forbidden, 404 not_found. Internal-only fields (reputation, dimension scores, scoring rules) are never present in any response.