{"openapi": "3.1.0", "info": {"title": "Product Information API Core", "version": "1.0.0", "description": "Direct, best-effort scrape API. Clients own cadence; this API does not promise scheduled monitoring freshness. Delivery depends on configured tenant, method, source, proxy, and cache capacity."}, "servers": [{"url": "https://api.productinformationapi.com"}], "components": {"securitySchemes": {"tenantBearer": {"type": "http", "scheme": "bearer"}}, "schemas": {"ScrapeRequest": {"type": "object", "required": ["source"], "properties": {"source": {"type": "string", "example": "amazon_gb"}, "method": {"type": "string", "enum": ["checkStock", "getProductInformation"], "default": "checkStock"}, "externalId": {"type": "string", "description": "Canonical Amazon ASIN."}, "url": {"type": "string", "format": "uri", "description": "Approved product URL alternative."}, "maxAgeS": {"type": "integer", "minimum": 0, "maximum": 86400, "description": "0 bypasses cache; omitted uses the deployment TTL."}, "idempotencyKey": {"type": "string"}}, "oneOf": [{"required": ["externalId"]}, {"required": ["url"]}]}, "BulkScrapeItem": {"type": "object", "properties": {"externalId": {"type": "string", "description": "Canonical Amazon ASIN."}, "url": {"type": "string", "format": "uri", "description": "Approved product URL alternative."}, "maxAgeS": {"type": "integer", "minimum": 0, "maximum": 86400, "description": "0 bypasses cache; omitted uses the deployment TTL."}}, "oneOf": [{"required": ["externalId"]}, {"required": ["url"]}]}, "StockOffer": {"type": "object", "properties": {"isBuybox": {"type": "boolean"}, "price": {"type": ["number", "null"]}, "currency": {"type": ["string", "null"]}, "priceMinor": {"type": ["integer", "null"]}, "quantity": {"type": ["integer", "null"]}, "quantityUnknown": {"type": "boolean"}, "offerKey": {"type": ["string", "null"]}, "condition": {"type": ["string", "null"]}, "seller": {"type": ["string", "null"]}, "fulfilment": {"type": "string"}, "dispatchesFrom": {"type": ["string", "null"]}, "prime": {"type": "boolean"}, "deliveryDays": {"type": ["integer", "null"]}}}, "StockScrapeResponse": {"type": "object", "properties": {"externalId": {"type": "string"}, "source": {"type": "string"}, "method": {"type": "string"}, "outcome": {"type": "string"}, "inStock": {"type": "boolean"}, "offerCount": {"type": "integer"}, "offers": {"type": "array", "items": {"$ref": "#/components/schemas/StockOffer"}}, "scrapedAt": {"type": "number"}, "fromCache": {"type": "boolean"}, "cachedAt": {"type": "number"}, "cacheAgeS": {"type": "integer"}, "creditsCharged": {"type": "integer"}, "creditsRemaining": {"type": "integer"}}}, "ProductInformationResponse": {"type": "object", "properties": {"externalId": {"type": "string"}, "source": {"type": "string"}, "method": {"type": "string"}, "outcome": {"type": "string"}, "productInformation": {"type": ["object", "null"], "properties": {"title": {"type": ["string", "null"]}, "brand": {"type": ["string", "null"]}, "manufacturer": {"type": ["string", "null"]}, "images": {"type": "array", "items": {"type": "string"}}, "features": {"type": "array", "items": {"type": "string"}}, "attributes": {"type": "object", "additionalProperties": {"type": "string"}}, "categoryPath": {"type": "array", "items": {"type": "string"}}, "description": {"type": ["string", "null"]}, "ratings": {"type": "object"}, "salesRank": {"type": ["integer", "null"]}, "categoryRanks": {"type": "array", "items": {"type": "object"}}, "badges": {"type": "array", "items": {"type": "string"}}, "sourceFreshness": {"type": "object"}, "confidence": {"type": ["number", "null"]}}}, "scrapedAt": {"type": "number"}, "fromCache": {"type": "boolean"}, "cachedAt": {"type": "number"}, "cacheAgeS": {"type": "integer"}, "creditsCharged": {"type": "integer"}, "creditsRemaining": {"type": "integer"}}}, "ScrapeResult": {"oneOf": [{"$ref": "#/components/schemas/StockScrapeResponse"}, {"$ref": "#/components/schemas/ProductInformationResponse"}]}, "BulkScrapeRequest": {"type": "object", "required": ["source", "items"], "properties": {"source": {"type": "string", "example": "amazon_gb"}, "method": {"type": "string", "enum": ["checkStock", "getProductInformation"], "default": "checkStock"}, "items": {"type": "array", "minItems": 1, "items": {"$ref": "#/components/schemas/BulkScrapeItem"}}, "idempotencyKey": {"type": "string"}}}, "BulkScrapeResponse": {"type": "object", "properties": {"requestId": {"type": "string"}, "source": {"type": "string"}, "method": {"type": "string"}, "total": {"type": "integer"}, "succeeded": {"type": "integer"}, "failed": {"type": "integer"}, "retryable": {"type": "integer"}, "results": {"type": "array", "items": {"type": "object", "properties": {"index": {"type": "integer"}, "httpStatus": {"type": "integer"}, "result": {"oneOf": [{"$ref": "#/components/schemas/ScrapeResult"}, {"$ref": "#/components/schemas/Error"}]}}}}}}, "UsageResponse": {"type": "object", "properties": {"clientCode": {"type": "string"}, "rateClass": {"type": "string"}, "scrapeLimits": {"type": "object", "properties": {"maxInFlightPerClient": {"type": "integer"}, "maxInFlightPerToken": {"type": "integer"}}}, "creditsRemaining": {"type": "integer"}, "recent": {"type": "array", "items": {"type": "object"}}}}, "Error": {"type": "object", "required": ["error"], "properties": {"error": {"type": "object", "required": ["code", "message", "requestId", "retryable"], "properties": {"code": {"type": "string"}, "message": {"type": "string"}, "requestId": {"type": "string"}, "retryable": {"type": "boolean"}, "retryAfterS": {"type": "integer", "minimum": 1}}, "additionalProperties": true}}}}}, "security": [{"tenantBearer": []}], "paths": {"/v1/scrape": {"post": {"summary": "Scrape one product now", "description": "Returns public product data only. Use maxAgeS=0 for live-only. Successful OK/NO_OFFERS results charge credits; retryable capacity/source failures do not.", "parameters": [{"name": "Idempotency-Key", "in": "header", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScrapeRequest"}, "examples": {"stock": {"value": {"source": "amazon_gb", "method": "checkStock", "externalId": "B0EXAMPLE1", "maxAgeS": 120}}, "productInfo": {"value": {"source": "amazon_gb", "method": "getProductInformation", "url": "https://www.amazon.co.uk/dp/B0EXAMPLE1", "maxAgeS": 0}}}}}}, "responses": {"200": {"description": "Scrape result", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScrapeResult"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid bearer token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Token scope is not allowed for this route", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "402": {"description": "Credit balance exhausted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Tenant, method, source, or capacity limit reached", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Source capacity unavailable or cooling down", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/v1/scrape/bulk": {"post": {"summary": "Scrape a bounded batch", "description": "Partial success is normal. Each item has its own httpStatus and retryable error body when applicable.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkScrapeRequest"}, "example": {"source": "amazon_gb", "method": "checkStock", "items": [{"externalId": "B0EXAMPLE1"}, {"url": "https://www.amazon.co.uk/dp/B0EXAMPLE2", "maxAgeS": 0}]}}}}, "responses": {"200": {"description": "Per-item scrape results", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkScrapeResponse"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid bearer token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Token scope is not allowed for this route", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "402": {"description": "Credit balance exhausted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Tenant, method, source, or capacity limit reached", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Source capacity unavailable or cooling down", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/v1/usage": {"get": {"summary": "Credit balance and recent usage for the caller", "description": "Recent usage rows include ledger deltas and reasons. Live successes use scrape_charge; cache hits use scrape_cache; capacity/source failures are not charged.", "parameters": [{"name": "recent", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100}}], "responses": {"200": {"description": "Usage summary", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UsageResponse"}}}}, "400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"description": "Missing or invalid bearer token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Token scope is not allowed for this route", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "402": {"description": "Credit balance exhausted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Tenant, method, source, or capacity limit reached", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Source capacity unavailable or cooling down", "headers": {"Retry-After": {"description": "Seconds before retrying when retryable is true.", "schema": {"type": "integer", "minimum": 1}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}}, "x-core-contract": {"cadenceOwnedBy": "client", "delivery": "best_effort", "identityInputs": ["externalId", "url"], "cacheKey": ["source", "method", "externalId"], "cacheTtlEnv": "API_SCRAPE_CACHE_TTL_S", "liveCreditCostEnv": "API_SCRAPE_CREDIT_COST", "cacheCreditCostEnv": "API_SCRAPE_CACHE_CREDIT_COST", "billableOutcomes": ["OK", "NO_OFFERS"], "amazonExamples": {"GB": {"source": "amazon_gb", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.co.uk/dp/B0EXAMPLE1"}, "DE": {"source": "amazon_de", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.de/dp/B0EXAMPLE1"}, "IT": {"source": "amazon_it", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.it/dp/B0EXAMPLE1"}, "FR": {"source": "amazon_fr", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.fr/dp/B0EXAMPLE1"}, "ES": {"source": "amazon_es", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.es/dp/B0EXAMPLE1"}, "US": {"source": "amazon_us", "externalId": "B0EXAMPLE1", "url": "https://www.amazon.com/dp/B0EXAMPLE1"}}}}