{
  "openapi": "3.1.0",
  "info": {
    "title": "ASINSpotlight Scraping API",
    "summary": "Real-time Amazon product, search, and seller data via REST.",
    "description": "The ASINSpotlight Scraping API returns structured Amazon data on demand: product details, keyword search results, full seller offer panels, and arbitrary Amazon URL scrapes. Single API key, query-param style, JSON in/JSON out, 20 supported marketplaces.\n\n**Source of truth.** This spec is hand-maintained against the live NestJS controller and DTOs. Response field shapes are verified against shipping responses; if any field here diverges from the live JSON, treat the live response as authoritative and report the doc bug.\n\n**Quota awareness.** Every successful response carries `meta.usage.requests_remaining`. Use it to make quota-aware loops; don't poll a separate endpoint to find out how much credit you have left.",
    "version": "1.0.0",
    "contact": {
      "name": "ASINSpotlight Support",
      "email": "support@asinspotlight.com",
      "url": "https://www.asinspotlight.com/api"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.asinspotlight.com/api"
    }
  },
  "servers": [
    {
      "url": "https://api.asinspotlight.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Product",
      "description": "Product detail page (PDP) data — title, price, reviews, BSR, brand, images, more."
    },
    {
      "name": "Search",
      "description": "Keyword search result pages with paginated entries."
    },
    {
      "name": "Offers",
      "description": "Full Buy Box and seller offer panel for a product."
    },
    {
      "name": "Scrape",
      "description": "Submit an arbitrary Amazon URL; the API auto-detects the page type."
    }
  ],
  "paths": {
    "/product": {
      "get": {
        "tags": ["Product"],
        "summary": "Get product details by ASIN",
        "description": "Fetches the live product detail page for a given ASIN and marketplace. Returns 60+ fields including pricing, Buy Box owner, reviews, BSR, brand, category, and images. Sub-second response time on typical product pages.",
        "operationId": "getProduct",
        "parameters": [
          {
            "$ref": "#/components/parameters/Asin"
          },
          {
            "$ref": "#/components/parameters/Marketplace"
          }
        ],
        "responses": {
          "200": {
            "description": "Product detail data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                },
                "example": {
                  "success": true,
                  "page_type": "product",
                  "data": {
                    "asin": "B0B3ZD8QXJ",
                    "title": "Soundcore by Anker Q20i Hybrid Active Noise Cancelling Headphones",
                    "buybox": true,
                    "bb_price": 39.99,
                    "rating": 4.6,
                    "reviews": 58800,
                    "bsr": 12,
                    "in_stock": true,
                    "is_prime": true,
                    "brand": {"name": "Soundcore", "url": "/stores/Soundcore/page/..."},
                    "category": {"name": "Over-Ear Headphones", "url": "/b?node=172541"},
                    "image_url": "https://m.media-amazon.com/images/I/61abc...jpg",
                    "sellers_all": 1,
                    "bought_past_month": 20000
                  },
                  "meta": {
                    "marketplace": "us",
                    "timing_ms": 1842,
                    "request_url": "https://www.amazon.com/dp/B0B3ZD8QXJ",
                    "timestamp": "2026-05-03T10:14:22.318Z",
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "usage": {"requests_consumed": 1, "requests_remaining": 49999}
                  }
                }
              }
            }
          },
          "400": {"$ref": "#/components/responses/ValidationError"},
          "401": {"$ref": "#/components/responses/AuthError"},
          "404": {"$ref": "#/components/responses/PageNotFoundError"},
          "429": {"$ref": "#/components/responses/RateLimitOrQuotaError"},
          "500": {"$ref": "#/components/responses/InternalError"},
          "502": {"$ref": "#/components/responses/ScrapeFailedError"},
          "503": {"$ref": "#/components/responses/ServiceUnavailableError"}
        }
      }
    },
    "/search": {
      "get": {
        "tags": ["Search"],
        "summary": "Search Amazon by keyword",
        "description": "Submits a keyword query against the chosen marketplace and returns the search results page. Each entry already includes ASIN, title, price, rating, review count, monthly demand, and stock — enough to shortlist without a follow-up `/product` call.\n\nPagination: results are returned for the page Amazon shows for that query. Use `meta.request_url` and adjust the `&page=N` query in a follow-up `POST /scrape` call to walk further pages.",
        "operationId": "searchKeyword",
        "parameters": [
          {
            "name": "keyword",
            "in": "query",
            "required": true,
            "description": "Search keyword. URL-encode multi-word queries (e.g. `wireless+headphones` or `wireless%20headphones`).",
            "schema": {"type": "string", "minLength": 1},
            "example": "wireless headphones"
          },
          {
            "$ref": "#/components/parameters/Marketplace"
          }
        ],
        "responses": {
          "200": {
            "description": "Keyword search results page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                },
                "example": {
                  "success": true,
                  "page_type": "search",
                  "data": {
                    "title": "wireless headphones",
                    "current_page": 1,
                    "last_page_number": 20,
                    "total_results_count": 10000,
                    "shallow_parts": [
                      {
                        "asin": "B0CQXMXJC5",
                        "title": "Soundcore Q20i Headphones",
                        "price": 39.99,
                        "rating": 4.6,
                        "reviews": 58800,
                        "bought_past_month": 20000,
                        "in_stock": true,
                        "image_url": "https://m.media-amazon.com/images/I/..."
                      }
                    ]
                  },
                  "meta": {
                    "marketplace": "us",
                    "timing_ms": 2104,
                    "request_url": "https://www.amazon.com/s?k=wireless%20headphones",
                    "timestamp": "2026-05-03T10:14:22.318Z",
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "usage": {"requests_consumed": 1, "requests_remaining": 49998}
                  }
                }
              }
            }
          },
          "400": {"$ref": "#/components/responses/ValidationError"},
          "401": {"$ref": "#/components/responses/AuthError"},
          "404": {"$ref": "#/components/responses/PageNotFoundError"},
          "429": {"$ref": "#/components/responses/RateLimitOrQuotaError"},
          "500": {"$ref": "#/components/responses/InternalError"},
          "502": {"$ref": "#/components/responses/ScrapeFailedError"},
          "503": {"$ref": "#/components/responses/ServiceUnavailableError"}
        }
      }
    },
    "/offers": {
      "get": {
        "tags": ["Offers"],
        "summary": "Get every seller offer for a product",
        "description": "Returns the full Buy Box panel and All Offers Display for a product: every seller currently listing the ASIN, with their price, shipping cost, condition, fulfillment method (FBA/FBM/Amazon), seller rating, and stock. Updated in real time, not from a cached database.",
        "operationId": "getOffers",
        "parameters": [
          {
            "$ref": "#/components/parameters/Asin"
          },
          {
            "$ref": "#/components/parameters/Marketplace"
          }
        ],
        "responses": {
          "200": {
            "description": "Seller offer panel",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OffersResponse"
                },
                "example": {
                  "success": true,
                  "page_type": "offers",
                  "data": {
                    "sold_by_amazon": true,
                    "fba_count": 3,
                    "fbm_count": 2,
                    "product_sellers_info": [
                      {
                        "name": "Amazon.com",
                        "price": 29.99,
                        "shipping_price": 0,
                        "is_fba": true,
                        "is_amazon": true,
                        "stock_qty": 100,
                        "rating_percent": 95,
                        "reviews_count": 50000
                      }
                    ]
                  },
                  "meta": {
                    "marketplace": "us",
                    "timing_ms": 2417,
                    "request_url": "https://www.amazon.com/gp/product/ajax/aodAjaxMain/...",
                    "timestamp": "2026-05-03T10:14:22.318Z",
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "usage": {"requests_consumed": 1, "requests_remaining": 49997}
                  }
                }
              }
            }
          },
          "400": {"$ref": "#/components/responses/ValidationError"},
          "401": {"$ref": "#/components/responses/AuthError"},
          "404": {"$ref": "#/components/responses/PageNotFoundError"},
          "429": {"$ref": "#/components/responses/RateLimitOrQuotaError"},
          "500": {"$ref": "#/components/responses/InternalError"},
          "502": {"$ref": "#/components/responses/ScrapeFailedError"},
          "503": {"$ref": "#/components/responses/ServiceUnavailableError"}
        }
      }
    },
    "/scrape": {
      "post": {
        "tags": ["Scrape"],
        "summary": "Scrape an arbitrary Amazon URL",
        "description": "Submit any Amazon URL — product page, search results, offers, bestsellers, category, storefront, reviews. The page type is auto-detected from the URL pattern; the response shape matches the detected type. Use this when you need a page format that doesn't fit a typed endpoint (deal pages, marketplace-specific layouts, search variants).",
        "operationId": "scrapeUrl",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrapeRequest"
              },
              "example": {
                "url": "https://www.amazon.com/gp/bestsellers/electronics",
                "marketplace": "us"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Auto-detected page data. The `data` field shape matches the detected `page_type`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScrapeResponse"
                }
              }
            }
          },
          "400": {"$ref": "#/components/responses/ValidationError"},
          "401": {"$ref": "#/components/responses/AuthError"},
          "404": {"$ref": "#/components/responses/PageNotFoundError"},
          "429": {"$ref": "#/components/responses/RateLimitOrQuotaError"},
          "500": {"$ref": "#/components/responses/InternalError"},
          "502": {"$ref": "#/components/responses/ScrapeFailedError"},
          "503": {"$ref": "#/components/responses/ServiceUnavailableError"}
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your API key. Generate one at https://board.asinspotlight.com/dashboard/api"
      }
    },
    "parameters": {
      "Asin": {
        "name": "asin",
        "in": "query",
        "required": true,
        "description": "Amazon Standard Identification Number — 10-character alphanumeric ID for a product.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Z0-9]{10}$"
        },
        "example": "B0B3ZD8QXJ"
      },
      "Marketplace": {
        "name": "marketplace",
        "in": "query",
        "required": false,
        "description": "Two-letter marketplace code. Defaults to `us`. Picks which Amazon storefront to query.",
        "schema": {
          "$ref": "#/components/schemas/Marketplace"
        },
        "example": "us"
      }
    },
    "schemas": {
      "Marketplace": {
        "type": "string",
        "default": "us",
        "enum": [
          "us", "uk", "de", "fr", "it", "es", "ca", "au", "jp", "in",
          "mx", "br", "tr", "sa", "ae", "sg", "nl", "pl", "se", "be"
        ],
        "description": "Supported marketplaces:\n- `us` — amazon.com (United States)\n- `uk` — amazon.co.uk (United Kingdom)\n- `de` — amazon.de (Germany)\n- `fr` — amazon.fr (France)\n- `it` — amazon.it (Italy)\n- `es` — amazon.es (Spain)\n- `ca` — amazon.ca (Canada)\n- `au` — amazon.com.au (Australia)\n- `jp` — amazon.co.jp (Japan)\n- `in` — amazon.in (India)\n- `mx` — amazon.com.mx (Mexico)\n- `br` — amazon.com.br (Brazil)\n- `tr` — amazon.com.tr (Turkey)\n- `sa` — amazon.sa (Saudi Arabia)\n- `ae` — amazon.ae (UAE)\n- `sg` — amazon.sg (Singapore)\n- `nl` — amazon.nl (Netherlands)\n- `pl` — amazon.pl (Poland)\n- `se` — amazon.se (Sweden)\n- `be` — amazon.com.be (Belgium)"
      },
      "ResponseMeta": {
        "type": "object",
        "description": "Per-request metadata. Always present on successful responses.",
        "required": ["marketplace", "timing_ms", "request_url", "timestamp", "request_id", "usage"],
        "properties": {
          "marketplace": {
            "type": "string",
            "description": "The marketplace code that was queried.",
            "example": "us"
          },
          "timing_ms": {
            "type": "integer",
            "minimum": 0,
            "description": "End-to-end request time in milliseconds, measured from receipt to response.",
            "example": 1842
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "description": "The exact Amazon URL that was fetched. Useful for follow-up scrapes (e.g., walking pagination).",
            "example": "https://www.amazon.com/dp/B0B3ZD8QXJ"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp when the response was generated.",
            "example": "2026-05-03T10:14:22.318Z"
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request ID. Include it when contacting support.",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "usage": {
            "$ref": "#/components/schemas/UsageMeta"
          }
        }
      },
      "UsageMeta": {
        "type": "object",
        "description": "Per-request quota accounting. Use `requests_remaining` to drive quota-aware loops without polling a separate endpoint.",
        "required": ["requests_consumed", "requests_remaining"],
        "properties": {
          "requests_consumed": {
            "type": "integer",
            "minimum": 0,
            "description": "Credits charged for this request. `1` for successful scrapes and for `PAGE_NOT_FOUND`; `0` for any other failure (you are not charged for parser errors, captchas, or quota/auth rejections).",
            "example": 1
          },
          "requests_remaining": {
            "type": "integer",
            "minimum": 0,
            "description": "Credits remaining across all currently active request packages for your API key.",
            "example": 49999
          }
        }
      },
      "ProductData": {
        "type": "object",
        "description": "Detail-page data for a single ASIN. Field set is documented to the typical case; absent fields can occur on listings missing that data on the page.",
        "properties": {
          "asin": {"type": "string", "example": "B0B3ZD8QXJ"},
          "title": {"type": "string", "example": "Soundcore Q20i Headphones"},
          "buybox": {"type": "boolean", "description": "Whether a Buy Box is currently displayed.", "example": true},
          "bb_price": {"type": "number", "format": "double", "description": "Buy Box price.", "example": 39.99},
          "rating": {"type": "number", "format": "double", "minimum": 0, "maximum": 5, "example": 4.6},
          "reviews": {"type": "integer", "minimum": 0, "description": "Total review count.", "example": 58800},
          "bsr": {"type": "integer", "minimum": 1, "description": "Best Sellers Rank within the primary category.", "example": 12},
          "in_stock": {"type": "boolean", "example": true},
          "is_prime": {"type": "boolean", "example": true},
          "brand": {
            "type": "object",
            "properties": {
              "name": {"type": "string", "example": "Soundcore"},
              "url": {"type": "string", "description": "Relative URL to the brand storefront.", "example": "/stores/Soundcore"}
            }
          },
          "category": {
            "type": "object",
            "properties": {
              "name": {"type": "string", "example": "Over-Ear Headphones"},
              "url": {"type": "string", "description": "Relative URL to the category browse node.", "example": "/b?node=172541"}
            }
          },
          "image_url": {"type": "string", "format": "uri", "example": "https://m.media-amazon.com/images/I/61abc.jpg"},
          "sellers_all": {"type": "integer", "minimum": 0, "description": "Total seller count for this listing.", "example": 5},
          "bought_past_month": {"type": "integer", "minimum": 0, "description": "Amazon's `Xk+ bought in past month` indicator. Coerced from labels like `2K+` to integer.", "example": 20000}
        }
      },
      "ProductResponse": {
        "type": "object",
        "required": ["success", "page_type", "data", "meta"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "page_type": {"type": "string", "const": "product"},
          "data": {"$ref": "#/components/schemas/ProductData"},
          "meta": {"$ref": "#/components/schemas/ResponseMeta"}
        }
      },
      "SearchResultEntry": {
        "type": "object",
        "description": "One organic search result entry. Sponsored placements are filtered out.",
        "properties": {
          "asin": {"type": "string", "example": "B0CQXMXJC5"},
          "title": {"type": "string", "example": "Soundcore Q20i Headphones"},
          "price": {"type": "number", "format": "double", "example": 39.99},
          "rating": {"type": "number", "format": "double", "minimum": 0, "maximum": 5, "example": 4.6},
          "reviews": {"type": "integer", "minimum": 0, "example": 58800},
          "bought_past_month": {"type": "integer", "minimum": 0, "example": 20000},
          "in_stock": {"type": "boolean", "example": true},
          "image_url": {"type": "string", "format": "uri", "example": "https://m.media-amazon.com/images/I/..."}
        }
      },
      "SearchData": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "The keyword that was searched.", "example": "wireless headphones"},
          "current_page": {"type": "integer", "minimum": 1, "example": 1},
          "last_page_number": {"type": "integer", "minimum": 1, "example": 20},
          "total_results_count": {"type": "integer", "minimum": 0, "example": 10000},
          "shallow_parts": {
            "type": "array",
            "description": "Search result entries on the current page.",
            "items": {"$ref": "#/components/schemas/SearchResultEntry"}
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": ["success", "page_type", "data", "meta"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "page_type": {"type": "string", "const": "search"},
          "data": {"$ref": "#/components/schemas/SearchData"},
          "meta": {"$ref": "#/components/schemas/ResponseMeta"}
        }
      },
      "OfferEntry": {
        "type": "object",
        "description": "One seller offer on a product listing.",
        "properties": {
          "name": {"type": "string", "example": "Amazon.com"},
          "price": {"type": "number", "format": "double", "example": 29.99},
          "shipping_price": {"type": "number", "format": "double", "minimum": 0, "example": 0},
          "is_fba": {"type": "boolean", "description": "Fulfilled by Amazon.", "example": true},
          "is_amazon": {"type": "boolean", "description": "Sold by Amazon directly (vs. third-party seller).", "example": true},
          "stock_qty": {"type": "integer", "minimum": 0, "description": "Stock quantity if exposed by Amazon; may be 0 or absent if hidden.", "example": 100},
          "rating_percent": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Seller positive-feedback percentage.", "example": 95},
          "reviews_count": {"type": "integer", "minimum": 0, "description": "Seller's total review count.", "example": 50000}
        }
      },
      "OffersData": {
        "type": "object",
        "properties": {
          "sold_by_amazon": {"type": "boolean", "example": true},
          "fba_count": {"type": "integer", "minimum": 0, "description": "Count of FBA offers in this panel.", "example": 3},
          "fbm_count": {"type": "integer", "minimum": 0, "description": "Count of FBM (Fulfilled by Merchant) offers in this panel.", "example": 2},
          "product_sellers_info": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/OfferEntry"}
          }
        }
      },
      "OffersResponse": {
        "type": "object",
        "required": ["success", "page_type", "data", "meta"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "page_type": {"type": "string", "const": "offers"},
          "data": {"$ref": "#/components/schemas/OffersData"},
          "meta": {"$ref": "#/components/schemas/ResponseMeta"}
        }
      },
      "ScrapeRequest": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Full Amazon URL to scrape. The page type is auto-detected from the URL pattern.",
            "example": "https://www.amazon.com/s?k=laptop+stand"
          },
          "marketplace": {
            "$ref": "#/components/schemas/Marketplace"
          }
        }
      },
      "ScrapeResponse": {
        "type": "object",
        "required": ["success", "page_type", "data", "meta"],
        "properties": {
          "success": {"type": "boolean", "const": true},
          "page_type": {
            "type": "string",
            "enum": ["product", "search", "offers", "category", "bestseller", "storefront", "reviews"],
            "description": "Detected page type. Determines the shape of `data`."
          },
          "data": {
            "description": "Page data; shape depends on `page_type`. For `product`, matches ProductData; for `search`, matches SearchData; for `offers`, matches OffersData. Other types return a structured payload tailored to the page.",
            "oneOf": [
              {"$ref": "#/components/schemas/ProductData"},
              {"$ref": "#/components/schemas/SearchData"},
              {"$ref": "#/components/schemas/OffersData"},
              {"type": "object", "description": "Free-form payload for category, bestseller, storefront, or reviews pages."}
            ]
          },
          "meta": {"$ref": "#/components/schemas/ResponseMeta"}
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": ["success", "error"],
        "properties": {
          "success": {"type": "boolean", "const": false},
          "meta": {
            "type": "object",
            "description": "Present on quota/rate-limit errors so you can read remaining credits even when a request is rejected.",
            "properties": {
              "usage": {"$ref": "#/components/schemas/UsageMeta"}
            }
          },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code. Stable across releases.",
                "enum": [
                  "MISSING_API_KEY",
                  "INVALID_API_KEY",
                  "PAGE_NOT_FOUND",
                  "RATE_LIMIT_EXCEEDED",
                  "MONTHLY_QUOTA_EXCEEDED",
                  "SCRAPE_FAILED",
                  "CAPTCHA_DETECTED",
                  "API_USAGE_UNAVAILABLE",
                  "INTERNAL_ERROR"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable description. Subject to wording change; do not match on this string."
              }
            }
          }
        }
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Request validation failed (missing required parameter, invalid marketplace code, unrecognized field). Returned by the framework's validation pipe; payload shape may differ from the standard `ErrorEnvelope`.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "statusCode": {"type": "integer", "example": 400},
                "message": {
                  "oneOf": [
                    {"type": "string"},
                    {"type": "array", "items": {"type": "string"}}
                  ],
                  "example": ["asin should not be empty", "marketplace must be one of the following values: us, uk, de, ..."]
                },
                "error": {"type": "string", "example": "Bad Request"}
              }
            }
          }
        }
      },
      "AuthError": {
        "description": "Missing or invalid API key.",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "examples": {
              "missing": {
                "summary": "MISSING_API_KEY",
                "value": {
                  "success": false,
                  "error": {"code": "MISSING_API_KEY", "message": "Provide your API key in the x-api-key header."}
                }
              },
              "invalid": {
                "summary": "INVALID_API_KEY",
                "value": {
                  "success": false,
                  "error": {"code": "INVALID_API_KEY", "message": "The provided API key is not valid."}
                }
              }
            }
          }
        }
      },
      "PageNotFoundError": {
        "description": "The Amazon page does not exist (typically a wrong ASIN, removed listing, or marketplace mismatch). **Counts against quota** — Amazon-confirmed 404s are billable since the parser still ran.",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "example": {
              "success": false,
              "meta": {"usage": {"requests_consumed": 1, "requests_remaining": 49996}},
              "error": {"code": "PAGE_NOT_FOUND", "message": "The requested Amazon page was not found."}
            }
          }
        }
      },
      "RateLimitOrQuotaError": {
        "description": "Either too many parallel in-flight requests for your API key, or you have no active request credits left.",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "examples": {
              "rateLimit": {
                "summary": "RATE_LIMIT_EXCEEDED — too many concurrent requests",
                "value": {
                  "success": false,
                  "meta": {"usage": {"requests_consumed": 0, "requests_remaining": 49996}},
                  "error": {"code": "RATE_LIMIT_EXCEEDED", "message": "Too many parallel requests."}
                }
              },
              "quota": {
                "summary": "MONTHLY_QUOTA_EXCEEDED — no active credits",
                "value": {
                  "success": false,
                  "meta": {"usage": {"requests_consumed": 0, "requests_remaining": 0}},
                  "error": {"code": "MONTHLY_QUOTA_EXCEEDED", "message": "No active API request credits are available."}
                }
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal service failure or transport error to the parser worker.",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "example": {
              "success": false,
              "error": {"code": "INTERNAL_ERROR", "message": "Request to parser service failed. Please try again."}
            }
          }
        }
      },
      "ScrapeFailedError": {
        "description": "The parser reached the page but could not extract structured data (page format change, partial render, malformed HTML).",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "example": {
              "success": false,
              "error": {"code": "SCRAPE_FAILED", "message": "Failed to parse Amazon page."}
            }
          }
        }
      },
      "ServiceUnavailableError": {
        "description": "Amazon returned a captcha page, or the usage tracking layer is temporarily unavailable. Retry after a short delay.",
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorEnvelope"},
            "examples": {
              "captcha": {
                "summary": "CAPTCHA_DETECTED",
                "value": {
                  "success": false,
                  "error": {"code": "CAPTCHA_DETECTED", "message": "Amazon returned a captcha page. Please retry."}
                }
              },
              "usageUnavailable": {
                "summary": "API_USAGE_UNAVAILABLE",
                "value": {
                  "success": false,
                  "error": {"code": "API_USAGE_UNAVAILABLE", "message": "API usage tracking is temporarily unavailable."}
                }
              }
            }
          }
        }
      }
    }
  }
}
