OpenStock API

OpenStock is the commerce API Checkmate provides to partners and agents for access to merchant discovery, merchant discount/offer codes, and shopper purchase history across the Checkmate network of 284,000+ merchants. All endpoints are POST with batched request/response shapes; authenticate with an Authorization Bearer API key issued by a partner representative. The same network is also exposed as a Model Context Protocol (MCP) server.

OpenAPI Specification

checkmate-openstock-openapi-original.json Raw ↑
{"openapi":"3.1.0","info":{"version":"1.0.0","title":"OpenStock API","description":"API provided by Checkmate to partners to provide access to merchant codes and shopper purchase history. All endpoints are POST with batched request/response shapes. Authenticate with `Authorization: Bearer <api_key>`. Ask partner representative for the API key."},"servers":[{"url":"https://api.openstock.sh","description":"Current environment"}],"components":{"schemas":{"HealthResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true,"description":"Whether the service is healthy"},"environment":{"type":"string","example":"local","description":"Deployment environment name"}},"required":["ok","environment"]},"MerchantSearchResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/MerchantSearchResult"}}},"required":["results"]},"MerchantSearchResult":{"type":"object","properties":{"query_id":{"type":"string","example":"q1"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MerchantSearchItem"},"minItems":1,"description":"Matched merchants for this query. Always contains at least one entry. Misses return a single entry with `id: null`; name queries with `limit > 1` may return multiple entries."}},"required":["query_id","items"]},"MerchantSearchItem":{"type":"object","properties":{"id":{"type":["string","null"],"example":"01hz4vdrcnxhfmfcvy3rfqk1fp","description":"Checkmate merchant ID, or null when not found"},"name":{"type":["string","null"],"example":"Acme Corp","description":"Merchant display name, or null when no match"},"domains":{"type":"array","items":{"type":"string"},"example":["acme.com","acme.co.uk"],"description":"Merchant domains"},"estimated_shipping":{"$ref":"#/components/schemas/EstimatedShipping"}},"required":["id","name","domains","estimated_shipping"]},"EstimatedShipping":{"type":["object","null"],"properties":{"unit":{"type":"string","enum":["days"],"example":"days","description":"Unit for all shipping time values in this object"},"median":{"type":"number","example":6,"description":"Median days to deliver"},"q1":{"type":["number","null"],"example":3,"description":"First quartile (25th percentile) days to deliver, or null when unknown"},"q3":{"type":["number","null"],"example":10,"description":"Third quartile (75th percentile) days to deliver, or null when unknown"}},"required":["unit","median","q1","q3"],"description":"Estimated shipping time statistics, or null when unknown"},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request body is invalid"}},"required":["code","message"]}},"required":["error"]},"MerchantSearchRequest":{"type":"object","properties":{"queries":{"type":"array","items":{"$ref":"#/components/schemas/MerchantSearchQuery"},"minItems":1,"maxItems":50,"description":"Batch of search queries (1–50). Each query returns a result with an `items` array. Name queries with `limit > 1` may yield multiple items. Misses return an `items` array with a single entry where `id` is null."}},"required":["queries"]},"MerchantSearchQuery":{"type":"object","properties":{"query_id":{"type":"string","minLength":1,"example":"q1","description":"Caller-supplied opaque identifier correlated back in results"},"type":{"type":"string","enum":["name","domain"],"example":"name","description":"\"name\" triggers fuzzy search; \"domain\" is an exact-match lookup"},"value":{"type":"string","minLength":1,"example":"Acme","description":"Search term: merchant name fragment or bare domain"},"region":{"type":"string","example":"US","description":"Optional ISO 3166-1 alpha-2 region filter (name queries only)"},"limit":{"type":"integer","minimum":1,"maximum":20,"default":5,"example":5,"description":"Maximum number of results to return for this query (name queries only, domain queries always return at most one result). Defaults to 5."}},"required":["query_id","type","value"]},"MerchantCodesResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/MerchantCodesResult"}}},"required":["results"]},"MerchantCodesResult":{"type":"object","properties":{"query_id":{"type":"string","example":"q1"},"items":{"type":"array","items":{"$ref":"#/components/schemas/OfferCode"},"description":"Ranked list of offer codes (minted / static / codeless / partnership / public). Empty array on miss."}},"required":["query_id","items"]},"OfferCode":{"type":"object","properties":{"code":{"type":["string","null"],"example":"SAVE10","description":"Promo code string, or null for codeless offers"},"probability":{"type":"number","minimum":0,"maximum":1,"example":0.92,"description":"Estimated probability (0–1) that the code will work at checkout"},"single_use":{"type":"boolean","example":false,"description":"True when the code expires after one redemption"},"value_type":{"type":"string","enum":["percent","fixed","free_shipping","unknown"],"example":"percent","description":"How the discount value is expressed"},"value_amount":{"type":["number","null"],"example":10,"description":"Numeric discount amount; semantics depend on value_type (e.g. 10 = 10% or $10)"},"currency":{"type":["string","null"],"example":"USD","description":"ISO 4217 currency code, present when value_type is \"fixed\""},"conditions":{"type":"array","items":{"type":"string"},"example":["minimum_subtotal"],"description":"Machine-readable condition tags (e.g. minimum_subtotal, product_restricted, applies_on_subscription)"},"redirect_url":{"type":["string","null"],"example":"https://go.checkmate.com/r/acme?code=SAVE10&ref=ck_partner_api","description":"Checkmate affiliate-attributed deep-link; null when unavailable"},"expires_at":{"type":["number","null"],"example":null,"description":"Unix timestamp (ms) when the code expires, or null when it does not expire"},"last_success":{"type":["string","null"],"example":"2026-06-16T17:00:00.000Z","description":"ISO 8601 UTC timestamp of the most recent successful checkout with this code, or null when never observed"},"description":{"type":["string","null"],"example":"10% off your first order","description":"Human-readable description of the offer or null"},"apply_count":{"type":["number","null"],"example":1280,"description":"Number of times this code has been applied at checkout, or null when not tracked (e.g. campaign/minted codes)"},"success_count":{"type":["number","null"],"example":940,"description":"Number of times this code applied successfully (yielded a saving), or null when not tracked (e.g. campaign/minted codes)"}},"required":["code","probability","single_use","value_type","value_amount","currency","conditions","redirect_url","expires_at","last_success","description","apply_count","success_count"]},"MerchantCodesRequest":{"type":"object","properties":{"queries":{"type":"array","items":{"$ref":"#/components/schemas/MerchantCodesQuery"},"minItems":1,"maxItems":20,"description":"Batch of codes queries (1–20)"}},"required":["queries"]},"MerchantCodesQuery":{"type":"object","properties":{"query_id":{"type":"string","minLength":1,"example":"q1","description":"Caller-supplied opaque identifier correlated back in results"},"merchant_id":{"type":"string","minLength":1,"example":"01hz4vdrcnxhfmfcvy3rfqk1fp","description":"Checkmate merchant ID obtained from the search endpoint"},"idempotency_key":{"type":"string","minLength":1,"example":"a3f1e2d4b5c6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2","description":"Deduplication key for this query. We suggest using `sha256(user_email + date)` or similar."}},"required":["query_id","merchant_id","idempotency_key"]},"ShopperHistoryResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/ShopperHistoryResult"}}},"required":["results"]},"ShopperHistoryResult":{"type":"object","properties":{"query_id":{"type":"string","example":"q1"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ShopperActivity"},"description":"Flat list of merchant interactions for this shopper. Empty array when the shopper is unknown."}},"required":["query_id","items"]},"ShopperActivity":{"type":"object","properties":{"merchant_id":{"type":"string","example":"01hz4vdrcnxhfmfcvy3rfqk1fp","description":"Checkmate merchant ID"},"merchant_name":{"type":"string","example":"Acme Corp"},"type":{"type":"string","enum":["visited","purchased"],"example":"purchased","description":"Activity type: \"visited\" or \"purchased\""}},"required":["merchant_id","merchant_name","type"]},"ShopperHistoryRequest":{"type":"object","properties":{"queries":{"type":"array","items":{"$ref":"#/components/schemas/ShopperHistoryQuery"},"minItems":1,"maxItems":20,"description":"Batch of shopper-history queries (1–20)"}},"required":["queries"]},"ShopperHistoryQuery":{"type":"object","properties":{"query_id":{"type":"string","minLength":1,"example":"q1","description":"Caller-supplied opaque identifier correlated back in results"},"email_sha256":{"type":"string","pattern":"^[0-9a-f]{64}$","example":"b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576e50e46a7d3f5a4b8","description":"SHA-256 of the lowercase-trimmed email address; never send the raw email"}},"required":["query_id","email_sha256"]}},"parameters":{}},"paths":{"/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Returns the current health status of the Openstock API.","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/merchants/search":{"post":{"tags":["Merchants"],"summary":"Batch merchant search","description":"Search for merchants by name (fuzzy) or domain (exact match). Up to 20 queries per request. Each query carries its own `query_id` that is echoed back so callers can correlate responses. Each result contains an `items` array with matched merchants. Name queries return up to `limit` items per result (default 5, max 20). Misses return a single item with `id: null` — there are no 404s.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantSearchRequest"}}}},"responses":{"200":{"description":"Per-query results. Each result has an `items` array. A name query with limit > 1 may produce multiple items. Misses have id: null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantSearchResponse"}}}},"400":{"description":"Invalid request body or query cap exceeded (max 50 queries)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Rate limits are determined on a per partner basis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/merchants/codes":{"post":{"tags":["Merchants"],"summary":"Batch merchant offer codes","description":"Retrieve ranked offer codes for a set of merchants. Up to 20 queries per request. Each result contains an `items` array of codes; misses return an empty `items` array. Add an `idempotency_key` to deduplicate requests; we suggest using `sha256(user_email + date)` or similar.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantCodesRequest"}}}},"responses":{"200":{"description":"Per-query results. Each result has an `items` array of codes. Misses return an empty `items` array.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantCodesResponse"}}}},"400":{"description":"Invalid request body, missing idempotency_key, or query cap exceeded (max 20)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Rate limits are determined on a per partner basis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/shoppers/history":{"post":{"tags":["Shoppers"],"summary":"Batch shopper purchase history","description":"Look up purchase history for one or more shoppers identified by SHA-256 hash of their normalised (lowercase-trimmed) email address. Never send raw email addresses. Up to 20 queries per request. Each result contains a flat `items` array of merchant interactions; unknown shoppers return an empty `items` array — there are no 404s.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopperHistoryRequest"}}}},"responses":{"200":{"description":"Per-query shopper history. Each result has a flat `items` array of merchant interactions. Unknown shoppers return an empty array.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopperHistoryResponse"}}}},"400":{"description":"Invalid request body, malformed email_sha256, or query cap exceeded (max 20)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Rate limits are determined on a per partner basis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}