{
  "openapi": "3.0.3",
  "info": {
    "title": "Barcode Report API",
    "version": "1.1.0",
    "description": "Look up product data by UPC, EAN, GTIN or ISBN across more than 500 million barcodes.\n\n**Get a key:** create a free account at https://barcodereport.com/register. New accounts include 100 lookups a\nmonth; paid plans start at $24.95 a month for 10,000. Your key is on https://barcodereport.com/dashboard.\n\n**Authentication:** send the key as `X-API-Key: KEY` or `Authorization: Bearer KEY`.\n\n**What counts as a lookup:** one per code for single and batch lookups (a code we don't have still counts, because\nthe search runs), one per call for product search. `/v1/account` is free. A request that fails on our side is not\ncharged.\n\n**Rate limits** are per key, per minute: single lookups get the plan's rate (Free 60, Standard 300, Premium 600,\nProfessional 1,200, Enterprise 2,400); batch and search get a fifth of it, at least 30. `/v1/account` allows 30.\nExceeding a limit returns `429` with `Retry-After`.\n\n**Errors** return `{\"error\": \"...\", \"code\": \"...\"}`. Branch on `code`; the message text may change.\n\nLegacy unversioned paths (`/api/search_barcode`, `/api/account`) still work and return the same data, but use\n`400`/`403` instead of `401`/`402`. New integrations should use `/api/v1/*`.\n\nThe same data is available to AI assistants through an MCP server at `https://barcodereport.com/api/mcp`.",
    "termsOfService": "https://barcodereport.com/pages/terms.html",
    "contact": {
      "name": "Barcode Report support",
      "email": "support@barcodereport.com",
      "url": "https://barcodereport.com/contact"
    },
    "x-logo": {
      "url": "https://barcodereport.com/img/email-logo.png",
      "altText": "Barcode Report"
    }
  },
  "externalDocs": {
    "description": "API documentation",
    "url": "https://barcodereport.com/barcode-api/documentation"
  },
  "servers": [
    {
      "url": "https://barcodereport.com/api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyHeader": []
    },
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Lookup",
      "description": "Look up products by barcode."
    },
    {
      "name": "Search",
      "description": "Find products by name, brand or category."
    },
    {
      "name": "Account",
      "description": "Plan and remaining allowance."
    }
  ],
  "paths": {
    "/v1/search_barcode": {
      "get": {
        "tags": [
          "Lookup"
        ],
        "operationId": "lookupBarcode",
        "summary": "Look up one barcode",
        "description": "Returns the product for a UPC-A, UPC-E, EAN-13, EAN-8, GTIN-14, ISBN-10 or ISBN-13. Matches every stored form of the code, so an ISBN-10 resolves to the same record as its ISBN-13. Costs one lookup, including when nothing is found.",
        "parameters": [
          {
            "name": "barcode",
            "in": "query",
            "required": true,
            "description": "The code to look up. Separators are ignored. At most 32 characters.",
            "schema": {
              "type": "string",
              "maxLength": 32
            },
            "example": "049000050103"
          }
        ],
        "responses": {
          "200": {
            "description": "The product.",
            "headers": {
              "X-Quota-Limit": {
                "$ref": "#/components/headers/X-Quota-Limit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                },
                "example": {
                  "barcode": "049000050103",
                  "requested_barcode": "049000050103",
                  "title": "Coca-cola bottle, 2 liters",
                  "brand": "Coca-Cola",
                  "brand_source": "record",
                  "category": "DSD BEVERAGES",
                  "country_of_registration": "United States and Canada",
                  "data_sources": [],
                  "attribution": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/QuotaExceeded"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/lookup": {
      "post": {
        "tags": [
          "Lookup"
        ],
        "operationId": "lookupBarcodes",
        "summary": "Look up up to 100 barcodes",
        "description": "Resolves up to 100 codes in one request. Each distinct code costs one lookup. All-or-nothing against your allowance: a batch that would exceed it is refused and nothing is consumed. Empty values and duplicates are ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "example": {
                "barcodes": [
                  "049000050103",
                  "3017620422003",
                  "860999888771"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One result per distinct code, in request order.",
            "headers": {
              "X-Quota-Limit": {
                "$ref": "#/components/headers/X-Quota-Limit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                },
                "example": {
                  "count": 3,
                  "found": 2,
                  "results": [
                    {
                      "requested_barcode": "049000050103",
                      "found": true,
                      "product": {
                        "barcode": "049000050103",
                        "requested_barcode": "049000050103",
                        "title": "Coca-cola bottle, 2 liters",
                        "brand": "Coca-Cola",
                        "brand_source": "record",
                        "category": "DSD BEVERAGES",
                        "country_of_registration": "United States and Canada",
                        "data_sources": [],
                        "attribution": null
                      }
                    },
                    {
                      "requested_barcode": "3017620422003",
                      "found": true,
                      "product": {
                        "barcode": "3017620422003",
                        "requested_barcode": "3017620422003",
                        "title": "Nutella Ferrero Hazelnut Chocolate Spread 400g",
                        "brand": "Ferrero",
                        "brand_source": "record",
                        "category": "Food, Beverages & Tobacco > Food Items > Dips & Spreads",
                        "country_of_registration": "France and Monaco",
                        "data_sources": [],
                        "attribution": null
                      }
                    },
                    {
                      "requested_barcode": "860999888771",
                      "found": false,
                      "product": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/QuotaExceeded"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "Search"
        ],
        "operationId": "searchProducts",
        "summary": "Search products by name",
        "description": "Full-text search over product title, brand and category, for when you have a name rather than a barcode. Words shorter than 3 characters are ignored. Costs one lookup per call, whatever the page size.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text, up to 120 characters.",
            "schema": {
              "type": "string",
              "maxLength": 120
            },
            "example": "nutella"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Results per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching products, best match first.",
            "headers": {
              "X-Quota-Limit": {
                "$ref": "#/components/headers/X-Quota-Limit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/X-Quota-Remaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                },
                "example": {
                  "query": "nutella",
                  "page": 1,
                  "per_page": 20,
                  "has_more": true,
                  "results": [
                    {
                      "barcode": "3017620422003",
                      "title": "Nutella Ferrero Hazelnut Chocolate Spread 400g",
                      "brand": "Ferrero",
                      "category": "Food, Beverages & Tobacco > Food Items > Dips & Spreads",
                      "image_url": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/QuotaExceeded"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccount",
        "summary": "Plan and remaining allowance",
        "description": "Your plan, allowance and usage this period. Does not consume a lookup. Limited to 30 requests a minute.",
        "responses": {
          "200": {
            "description": "Account and quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "example": {
                  "name": "Jane Doe",
                  "email": "jane@example.com",
                  "created_at": "2026-01-20T14:51:02",
                  "plan_name": "Standard Plan",
                  "plan_limit": 10000,
                  "api_usage": 1432,
                  "usage_remaining": 8568,
                  "usage_reset_at": "2026-11-20T14:51:02"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your API key from https://barcodereport.com/dashboard"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "The same API key, sent as `Authorization: Bearer KEY`."
      }
    },
    "headers": {
      "X-Quota-Limit": {
        "description": "Lookups included in your plan this period.",
        "schema": {
          "type": "integer"
        }
      },
      "X-Quota-Remaining": {
        "description": "Lookups left this period.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Limit": {
        "description": "Requests allowed per minute on this endpoint.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Requests left in the current minute.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "Unix time when the current window resets.",
        "schema": {
          "type": "integer"
        }
      },
      "X-Request-Id": {
        "description": "Request id to quote in support requests.",
        "schema": {
          "type": "string"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "Product": {
        "type": "object",
        "description": "A product record. Every field except `barcode` and `title` may be null. Fields may be added over time but are never removed or renamed, so ignore keys you do not recognise.",
        "required": [
          "barcode",
          "title"
        ],
        "properties": {
          "barcode": {
            "type": "string",
            "description": "Canonical code for this product.",
            "example": "049000050103"
          },
          "requested_barcode": {
            "type": "string",
            "nullable": true,
            "description": "The code you sent, which may differ in form from `barcode` (for example a 13-digit EAN-13 of a stored 12-digit UPC-A).",
            "example": "049000050103"
          },
          "title": {
            "type": "string",
            "description": "Product name. Present on effectively every record.",
            "example": "Coca-cola bottle, 2 liters"
          },
          "brand": {
            "type": "string",
            "nullable": true,
            "description": "Brand or manufacturer.",
            "example": "Coca-Cola"
          },
          "brand_source": {
            "type": "string",
            "nullable": true,
            "description": "Where `brand` came from: `record`, `enrichment`, or `inferred_prefix` (agreed by other products under the same GS1 company prefix).",
            "example": "record"
          },
          "category": {
            "type": "string",
            "nullable": true,
            "description": "Category path, `>`-delimited where available.",
            "example": "DSD BEVERAGES"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Free-text product description."
          },
          "image_url": {
            "type": "string",
            "nullable": true,
            "description": "Product image URL, hosted externally."
          },
          "min_price": {
            "type": "string",
            "nullable": true,
            "description": "Lowest price seen, as a decimal string."
          },
          "price_currency": {
            "type": "string",
            "nullable": true,
            "description": "Currency of `min_price`."
          },
          "old_barcode": {
            "type": "string",
            "nullable": true,
            "description": "A superseded code, typically the ISBN-10 of a book."
          },
          "upc_a": {
            "type": "string",
            "nullable": true,
            "description": "UPC-A form, where known."
          },
          "ean_13": {
            "type": "string",
            "nullable": true,
            "description": "EAN-13 form, where known."
          },
          "gtin_14": {
            "type": "string",
            "nullable": true,
            "description": "GTIN-14 form, where known."
          },
          "amazon_asin": {
            "type": "string",
            "nullable": true,
            "description": "Amazon ASIN, where known."
          },
          "model_number": {
            "type": "string",
            "nullable": true,
            "description": "Manufacturer model number."
          },
          "country_of_registration": {
            "type": "string",
            "nullable": true,
            "description": "Country of the GS1 member organisation that issued the prefix. This is where the code was registered, not where the product was made.",
            "example": "United States and Canada"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Colour, where known."
          },
          "size": {
            "type": "string",
            "nullable": true,
            "description": "Size, where known."
          },
          "weight": {
            "type": "string",
            "nullable": true,
            "description": "Weight, where known."
          },
          "product_dimension": {
            "type": "string",
            "nullable": true,
            "description": "Dimensions, where known."
          },
          "quantity": {
            "type": "string",
            "nullable": true,
            "description": "Net quantity, for example `2 L`."
          },
          "authors": {
            "type": "string",
            "nullable": true,
            "description": "Book authors."
          },
          "publisher": {
            "type": "string",
            "nullable": true,
            "description": "Publisher, from enrichment sources."
          },
          "publish_date": {
            "type": "string",
            "nullable": true,
            "description": "Book publication date as stored (free text)."
          },
          "number_of_pages": {
            "type": "string",
            "nullable": true,
            "description": "Book page count as stored (free text)."
          },
          "isbn": {
            "type": "string",
            "nullable": true,
            "description": "ISBN, for book records."
          },
          "isbn_publisher": {
            "type": "string",
            "nullable": true,
            "description": "ISBN registrant."
          },
          "isbn_identifier_group": {
            "type": "string",
            "nullable": true,
            "description": "ISBN registration group."
          },
          "isbn_check_digit": {
            "type": "string",
            "nullable": true,
            "description": "ISBN check digit."
          },
          "url": {
            "type": "string",
            "nullable": true,
            "description": "A source URL for the record, where one exists."
          },
          "attribution": {
            "type": "string",
            "nullable": true,
            "description": "Licence attribution to show with the data when part of it comes from an Open Database License source such as Open Food Facts; otherwise null."
          },
          "data_sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Open data sources that contributed fields (for example `openfoodfacts`).",
            "example": []
          }
        },
        "additionalProperties": true
      },
      "BatchRequest": {
        "type": "object",
        "required": [
          "barcodes"
        ],
        "properties": {
          "barcodes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "string",
              "maxLength": 32
            },
            "description": "Up to 100 codes."
          }
        }
      },
      "BatchResult": {
        "type": "object",
        "required": [
          "requested_barcode",
          "found",
          "product"
        ],
        "properties": {
          "requested_barcode": {
            "type": "string"
          },
          "found": {
            "type": "boolean"
          },
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Product"
              }
            ],
            "nullable": true
          }
        }
      },
      "BatchResponse": {
        "type": "object",
        "required": [
          "count",
          "found",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "description": "Distinct codes looked up (and charged)."
          },
          "found": {
            "type": "integer",
            "description": "How many of them matched."
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchResult"
            }
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "required": [
          "barcode",
          "title"
        ],
        "properties": {
          "barcode": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "brand": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "image_url": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": [
          "query",
          "page",
          "per_page",
          "has_more",
          "results"
        ],
        "properties": {
          "query": {
            "type": "string"
          },
          "page": {
            "type": "integer"
          },
          "per_page": {
            "type": "integer"
          },
          "has_more": {
            "type": "boolean"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResult"
            }
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "description": "ISO 8601."
          },
          "plan_name": {
            "type": "string",
            "nullable": true
          },
          "plan_limit": {
            "type": "integer",
            "nullable": true
          },
          "api_usage": {
            "type": "integer"
          },
          "usage_remaining": {
            "type": "integer",
            "nullable": true,
            "description": "Null when the account has no active plan."
          },
          "usage_reset_at": {
            "type": "string",
            "nullable": true,
            "description": "ISO 8601."
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable message; may change."
          },
          "code": {
            "type": "string",
            "enum": [
              "bad_request",
              "missing_key",
              "invalid_key",
              "quota_exceeded",
              "not_found",
              "rate_limited",
              "method_not_allowed",
              "server_error"
            ],
            "description": "Stable machine-readable code."
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "A parameter is missing or malformed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Barcode is not provided",
              "code": "bad_request"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No API key (`missing_key`) or an unknown one (`invalid_key`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Invalid API key",
              "code": "invalid_key"
            }
          }
        },
        "headers": {
          "WWW-Authenticate": {
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "QuotaExceeded": {
        "description": "Monthly allowance used up, or no active plan. The `Link` header points to the upgrade page.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "You have used all 100 lookups in your Free Plan this billing period. Upgrade for more at https://barcodereport.com/change-plan",
              "code": "quota_exceeded"
            }
          }
        },
        "headers": {
          "Link": {
            "description": "`<https://barcodereport.com/change-plan>; rel=\"help\"`",
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "NotFound": {
        "description": "No record for that barcode. Still counts as a lookup.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Barcode not found",
              "code": "not_found"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests this minute.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Rate limit exceeded (60 per 1 minute). Slow down.",
              "code": "rate_limited"
            }
          }
        },
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        }
      },
      "ServerError": {
        "description": "Failure on our side; not charged. Retry with backoff.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "An error occurred",
              "code": "server_error"
            }
          }
        }
      }
    }
  }
}
