openapi: 3.1.0 info: title: Open Food Facts Open API description: | As a developer, the Open Food Facts API allows you to get information and contribute to the products database. You can create great apps to help people make better food choices and also provide data to enhance the database. **IMPORTANT**: Please read the [API introduction](https://openfoodfacts.github.io/openfoodfacts-server/api/) before using this API. termsOfService: "https://world.openfoodfacts.org/terms-of-use" contact: name: Open Food Facts url: "https://slack.openfoodfacts.org/" email: reuse@openfoodfacts.org license: name: "data: ODbL" url: "https://opendatacommons.org/licenses/odbl/summary/index.html" # can't use url and identifier - use x-identifier x-identifier: "ODbL-1.0" version: "2" externalDocs: description: | **IMPORTANT**: Please read the API introduction before using this API. url: https://openfoodfacts.github.io/openfoodfacts-server/api/ servers: - description: dev url: "https://world.openfoodfacts.net" - description: prod url: "https://world.openfoodfacts.org" - description: proxy (for doc purpose) url: "http://localhost:8080" paths: "/api/v2/product/{code}": get: tags: - Products summary: Get Product Details description: | Fetches product details by its unique barcode. Can return all product details or specific fields like knowledge panels. Use the `blame` parameter to include information about who last modified each field of the product. operationId: get-product-by-code parameters: - name: code in: path description: The barcode of the product to be fetched required: true style: simple explode: false schema: type: string examples: - "3017620422003" - $ref: "./parameters/requested_product_type.yaml#/components/parameters/RequestedProductType" - $ref: "./parameters/cc.yaml#/components/parameters/Cc" - $ref: "./parameters/lc.yaml#/components/parameters/Lc" - $ref: "./parameters/product_available_fields.yaml#/components/parameters/ProductAvailableFields" - $ref: "./parameters/knowledge_panels_options.yaml#/components/parameters/KnowledgePanelClient" - $ref: "./parameters/knowledge_panels_options.yaml#/components/parameters/ActivateKnowledgePanelsSimplified" - $ref: "./parameters/knowledge_panels_options.yaml#/components/parameters/ActivateKnowledgePanelPhysicalActivities" - $ref: "./parameters/knowledge_panels_options.yaml#/components/parameters/KnowledgePanelsIncluded" - $ref: "./parameters/knowledge_panels_options.yaml#/components/parameters/KnowledgePanelsExcluded" - $ref: "./parameters/blame.yaml#/components/parameters/Blame" responses: "200": description: OK content: application/json: schema: title: get_product_by_barcode_all_response oneOf: - $ref: "./responses/get_product_by_barcode.yaml" - title: get_product_by_barcode_knowledge_panels_response allOf: - $ref: ./responses/get_product_by_barcode_base.yaml - type: object properties: product: $ref: "#/components/schemas/Product-Knowledge-Panels" - $ref: "./responses/get_product_by_barcode_with_blame.yaml" examples: full-product: $ref: "./examples/get_product_by_barcode_spread.yaml" knowledge-panels: $ref: "./examples/get_product_by_barcode_knowledge_panels.yaml" # You'll need to create this example with-blame: $ref: "./examples/get_product_by_barcode_with_blame.yaml" "302": description: Redirect to the correct server for the product type of the requested product headers: Location: schema: type: string description: URL to the correct server examples: redirect: value: "https://world.openbeautyfacts.org/api/v2/product/8710447445990" "404": description: Product not found /cgi/product_image_upload.pl: post: tags: - Images summary: Upload Product Image operationId: get-cgi-product_image_upload.pl description: | Photos are source and proof of data. The first photo uploaded for a product is auto-selected as the product’s “front” photo.' responses: "200": description: OK content: application/json: schema: $ref: ./responses/add_photo_to_existing_product.yaml requestBody: content: multipart/form-data: schema: allOf: - $ref: ./requestBodies/add_photo_to_existing_product.yaml - $ref: ./requestBodies/change_ref_properties.yaml description: "" security: - cookieAuth: [] userAgentAuth: [] /cgi/ingredients.pl: parameters: [] get: summary: OCR on Ingredients operationId: get-cgi-ingredients.pl responses: "200": description: OK content: application/json: schema: $ref: ./responses/ocr_on_product.yaml description: | Open Food Facts uses optical character recognition (OCR) to retrieve nutritional data and other information from the product labels. parameters: - $ref: "#/components/parameters/id" - $ref: "./parameters/code.yaml#/components/parameters/Code" - $ref: "#/components/parameters/process_image" - $ref: "#/components/parameters/ocr_engine" tags: - OCR /cgi/product_image_crop.pl: post: summary: Select and Crop Image operationId: post-cgi-product_image_crop.pl responses: "200": description: OK content: application/json: schema: $ref: ./responses/product_image_crop.yaml description: | Cropping is only relevant for editing existing products. You cannot crop an image the first time you upload it to the system. parameters: [] requestBody: content: multipart/form-data: schema: allOf: - $ref: ./requestBodies/crop_a_photo.yaml - $ref: ./requestBodies/change_ref_properties.yaml required: true tags: - Images get: summary: Rotate Image operationId: get-cgi-product_image_crop.pl responses: "200": description: OK content: application/json: schema: $ref: ./responses/rotate_a_photo.yaml description: | Although we recommend rotating photos manually and uploading a new version of the image, the OFF API allows you to make api calls to automate this process. You can rotate existing photos by setting the angle to 90º, 180º, or 270º clockwise. parameters: - $ref: "./parameters/code.yaml#/components/parameters/Code" - $ref: "#/components/parameters/id" - $ref: "#/components/parameters/imgid" - $ref: "#/components/parameters/angle" tags: - Images /cgi/product_image_unselect.pl: post: summary: Unselect Image description: | This endpoint allows the user to unselect a photo for a product. The user must provide the product code and the image ID to unselect. operationId: post-cgi-product_image_unselect.pl tags: - Images requestBody: content: multipart/form-data: schema: $ref: ./requestBodies/unselect_a_photo.yaml responses: "200": description: OK content: application/json: schema: title: unselect_a_photo_response type: object properties: status: type: string description: status of the unselect operation example: status ok status_code: type: number description: status code of the operation example: 0 imagefield: type: string example: front_fr description: image field that was unselected /cgi/product_jqm2.pl: post: summary: Edit Product operationId: post-cgi-product_jqm2.pl responses: "200": description: OK content: application/json: schema: $ref: ./responses/add_or_edit_a_product.yaml parameters: [] requestBody: content: multipart/form-data: schema: allOf: - $ref: ./requestBodies/add_or_edit_a_product.yaml - $ref: ./requestBodies/change_ref_properties.yaml tags: - Products description: | This updates a product. Note: If the barcode exists then you will be editing the existing product, However if it doesn''t you will be creating a new product with that unique barcode, and adding properties to the product. security: - cookieAuth: [] userAgentAuth: [] /api/v2/search: get: summary: Search Products tags: - Search responses: "200": description: OK content: application/json: schema: $ref: ./responses/search_for_products.yaml operationId: get-search description: | Search request allows you to get products that match your search criteria. It allows you create many custom APIs for your use case. If a search query parameter has multiple values, separate them with commas (`,`). When filtering with a language-specific parameter (`fr`, `de`, `en`, etc.), specify the language code in the parameter name (for example: `categories_tags_en`). **Important:** search API v2 does not support full text request (search_term), you have to use [search API v1](https://wiki.openfoodfacts.org/API/Read/Search) for that. Upcoming [search-a-licious project](https://github.com/openfoodfacts/search-a-licious) will fix that. ### Limiting results You can limit the size of returned objects thanks to the `fields` object (see below). Example: `fields=code,product_name,brands,attribute_groups` Please use it as much as possible to avoid overloading the servers. The search endpoint uses pagination: see `page` and `page_size` parameters. **Beware:** `page_count` is the number of products returned in the current page, not the total number of pages. ### Conditions on tags All `_tags`` parameters accepts either: * a single value * or a comma-separated list of values (doing a AND) * or a pipe separated list of values (doing a OR) You can exclude terms by using a "-" prefix. For taxonomized entries, you might either use the tag id (recommended), or a known synonym (without language prefix) * `labels_tags=en:organic,en:fair-trade` find items that are fair-trade AND organic * `labels_tags=en:organic|en:fair-trade` find items that are fair-trade OR organic * `labels_tags=en:organic,en:-fair-trade` find items that are organic BUT NOT fair-trade ### Conditions on nutriments To get a list of nutrients: You can either query on nutrient per 100g (`_100g` suffix) or per serving (`serving` suffix). You can also add `_prepared_` to get the nutrients in the prepared product instead of as sold. You can add a comparison operator and value to the parameter name to get products with nutrient above or below a value. If you use a parameter value it exactly match it. * `energy-kj_100g<200` products where energy in kj for 100g is less than 200kj * `sugars_serving>10` products where sugar per serving is greater than 10g * `saturated-fat_100g=1` products where saturated fat per 100g is exactly 10g * `salt_prepared_serving<0.1` products where salt per serving for prepared product is less than 0.1g ### Combining filters and pagination (examples) 1. Breakfast cereals with Nutri-Score A or B, with explicit pagination: `/api/v2/search?categories_tags_en=breakfast-cereals&nutrition_grades_tags=a|b&page=2&page_size=20&fields=code,product_name,nutrition_grades` 2. Multiple constraints in one query (category + nutrients + sorting + compact fields): `/api/v2/search?categories_tags_en=orange-juices&sugars_100g%3C8&salt_100g%3C0.2&sort_by=last_modified_t&page=1&page_size=24&fields=code,product_name,nutriments` 3. Include/exclude tags together: `/api/v2/search?labels_tags=en:organic,en:-fair-trade&page=1&page_size=24&fields=code,product_name,labels_tags` ### Response structure at a glance A successful response contains: * `count`: total number of matching products * `page`: current page number * `page_size`: requested number of products per page * `page_count`: number of products actually returned in this page * `skip`: number of products skipped before this page * `products`: array of products for the current page Total page count can be computed with: `Math.floor((count - 1) / page_size) + 1` ### More references See also [wiki page](https://wiki.openfoodfacts.org/Open_Food_Facts_Search_API_Version_2) parameters: # all tags parameters - $ref: "./schemas/tags_parameters.yaml#/properties/additives_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/allergens_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/brands_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/categories_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/countries_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/emb_codes_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/labels_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/manufacturing_places_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/nutrition_grades_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/origins_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/packaging_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/purchase_places_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/states_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/stores_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/traces_tags" - $ref: "./schemas/tags_parameters.yaml#/properties/tag_name_with_language_code" - $ref: "./schemas/nutrition_search.yaml#/properties/nutrient_lower_than" - $ref: "./schemas/nutrition_search.yaml#/properties/nutrient_greater_than" - $ref: "./schemas/nutrition_search.yaml#/properties/nutrient_equal" - $ref: "./parameters/product_available_fields.yaml#/components/parameters/ProductAvailableFields" - $ref: "#/components/parameters/sort_by" - $ref: "#/components/parameters/page" - $ref: "#/components/parameters/page_size" parameters: [] /cgi/suggest.pl: get: summary: Get Suggestions tags: - Suggestions responses: "200": description: OK content: application/json: schema: type: array items: type: string operationId: get-cgi-suggest.pl parameters: - $ref: "./parameters/tagtype.yaml#/components/parameters/Tagtype" - $ref: "#/components/parameters/term" description: | For example , Dave is looking for packaging_shapes that contain the term "fe", all packaging_shapes containing "fe" will be returned. This is useful if you have a search in your application, for a specific product field. /cgi/nutrients.pl: get: summary: Get Nutrients List tags: - Nutrients responses: "200": description: OK content: application/json: schema: $ref: ./responses/get_nutrients.yaml operationId: get-cgi-nutrients.pl parameters: - $ref: "./parameters/cc.yaml#/components/parameters/Cc" - $ref: "./parameters/lc.yaml#/components/parameters/Lc" description: | Used to display the nutrition facts table of a product, or to display a form to input those nutrition facts. /api/v2/attribute_groups: get: summary: Get Attribute Groups description: | Attributes are at the heart of personal search. They score the products according to different criterias, which could then be matched to a user's preferences. This API helps you list attributes and display them in your application, for the user to choose the importance of each criteria. note: `/api/v2/attribute_groups_{lc}` is also a valid route, but consider it deprecated tags: - Personal Search operationId: get-attribute-groups responses: "200": description: OK content: application/json: schema: title: get_attribute_groups_response $ref: ./responses/get_attribute_groups.yaml parameters: - $ref: "./parameters/lc.yaml#/components/parameters/Lc" /api/v2/preferences: get: summary: Get Preferences Weights description: | This endpoint retrieves the weights corresponding to attribute preferences for computing personal product recommendations. The weights are used to personalize the product recommendations based on user preferences. tags: - Personal Search operationId: get-preferences parameters: - $ref: "./parameters/lc.yaml#/components/parameters/Lc" responses: "200": description: OK content: application/json: schema: $ref: ./responses/get_preferences.yaml /cgi/session.pl: post: summary: Login Session operationId: get-cgi-session.pl description: Retrieve session cookie for writing operations. tags: - Authentication requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: user_id: type: string description: | Username for login Note: you must always use the username (and not the email) as it is far less brittle. password: type: string description: Password for login format: password required: - user_id - password responses: "200": description: Successful login headers: Set-Cookie: schema: type: string description: Session cookie for subsequent authenticated requests examples: sessionCookie: value: "session=user123&testuser&user_session&abcdef1234567890; domain=.example.net; path=/; SameSite=Lax" "401": description: Authentication failed components: securitySchemes: cookieAuth: type: apiKey in: cookie name: session description: | Session cookie containing user ID, username, and session token. The value is structured as: user_id&username&user_session&session_token e.g. "user_id&exampleuser&user_session&abcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLM". The session token is obtained after successful login via the `/cgi/session.pl` endpoint. userAgentAuth: description: Identification using the User-Agent header. This is recommended in all requests so that we can contact you if there are issues. If we cannot identify the source of problematic API queries, we may have to block them. User-Agent header in the format 'app_name/app_version (URL or contact info)' type: apiKey in: header name: User-Agent schemas: "Product-Base": $ref: ./schemas/product_base.yaml "Product-Misc": $ref: ./schemas/product_misc.yaml "Product-Tags": $ref: ./schemas/product_tags.yaml "Product-Images": $ref: ./schemas/product_images.yaml "Product-Eco-Score": $ref: ./schemas/product_ecoscore.yaml "Product-Ingredients": $ref: ./schemas/product_ingredients.yaml "Product-Nutrition": $ref: ./schemas/product_nutrition.yaml "Product-Nutrition-v3.5": $ref: "./schemas/product_nutrition_v3.yaml#/components/schemas/ProductNutritionDataV3" "Product-Nutriscore": $ref: "./schemas/product_nutriscore.yaml#/components/schemas/NutriscoreAll" "Product-Quality": $ref: ./schemas/product_quality.yaml "Product-Extended": $ref: ./schemas/product_extended.yaml "Product-Metadata": $ref: ./schemas/product_meta.yaml "Product-Knowledge-Panels": $ref: ./schemas/product_knowledge_panels.yaml "Product-Attribute-Groups": $ref: "./schemas/product_attribute_groups.yaml" # this is to have it displayed wholy in documentation Product: $ref: ./schemas/product.yaml Ingredient: # Added to fix some generator errors on recursive $ref $ref: ./schemas/ingredient.yaml Nutrient: # Added to fix some generator errors on recursive $ref $ref: "./schemas/nutrients.yaml#/components/schemas/Nutrient" parameters: id: schema: type: string example: ingredients_en in: query name: id required: true process_image: schema: type: string example: "1" in: query name: process_image required: true ocr_engine: schema: type: string example: google_cloud_vision in: query name: ocr_engine required: true imgid: schema: type: string example: "1" in: query name: imgid required: true angle: schema: type: string example: "90" in: query name: angle required: true page: schema: type: integer example: 24 in: query name: page description: | The page number you request to view (eg. in search results spanning multiple pages) page_size: schema: type: integer example: 24 in: query name: page_size description: | The number of elements should be sent per page sort_by: schema: type: string example: product_name enum: - product_name - last_modified_t - scans_n - unique_scans_n - created_t - completeness - popularity_key - nutriscore_score - nova_score - nothing - ecoscore_score in: query name: sort_by description: | The allowed values used to sort/order the search results. * `product_name` sorts on name * `ecoscore_score`, `nova_score`, `nutriscore_score` rank on the [Eco-Score](https://world.openfoodfacts.org/eco-score-the-environmental-impact-of-food-products), [Nova](https://world.openfoodfacts.org/nova), or [Nutri-Score](https://world.openfoodfacts.org/nutriscore) * `scans_n`, `unique_scans_n` and `popularity_key` are about product popularity: number of scans on unique scans, rank of product * `created_t`, `last_modified_t`, are about creation and modification dates * `nothing`, tells not to sort at all (because if you do not provide the sort_by argument we default to sorting on popularity (for food) or last modification date) term: schema: type: string example: f in: query name: term security: - userAgentAuth: [] # No authentication required by default (for read requests), but we recommend sending a User-Agent header in all requests. tags: - name: Products description: Endpoints for managing product data and information. - name: Images description: Endpoints for uploading, cropping, rotating, and managing product images. - name: Search description: Endpoints for searching products with various filters and criteria. - name: OCR description: Endpoints for optical character recognition on product labels. - name: Suggestions description: Endpoints for getting suggestions to aid in product editing. - name: Nutrients description: Endpoints for retrieving nutrition-related data and facts. - name: Personal Search description: Endpoints for personalized search and recommendations. - name: Authentication description: Endpoints for user authentication and session management.