# Open Beauty Facts

> Look up cosmetics by barcode in Open Beauty Facts, the free, open database of about 75,000 shampoos, creams, deodorants, make-up and soaps built by volunteers. Read a product's ingredient list, brand, category, label claims, shelf life after opening and pack photographs; search or filter by category, brand, label, ingredient or country; check an ingredient list for the groups people commonly avoid; compare products side by side; and watch for products added since a date. No account and no API key. The data is contributed voluntarily and carries no guarantee of accuracy or completeness, so check it before relying on it for an allergy or a health decision. Disclaimer: this is an independent integration with the community-run Open Beauty Facts project (openbeautyfacts.org); it is not affiliated with, endorsed by, or sponsored by Open Beauty Facts or the non-profit that operates it.

App · Health & Fitness · 7 actions. Web page: https://docs.lodol.com/docs/integrations/open-beauty-facts

## Actions

### Browse brands, categories and labels

List the values 'Find products' can filter by: brands, categories, labels, ingredients or countries, most-used first, each with how many products carry it. Use it to see what a filter can be set to, to find how the database spells something, or to answer a question of its own: which label claims are most common, how many products a brand has. Open Beauty Facts publishes the hundred most-used values of each, and the result says how many there are in total.

**Inputs**

- List (`catalogue`, text, required): Which list to browse. One of: `brands`, `categories`, `labels`, `ingredients`, `countries`.
- Containing (`contains`, text): Optional. Only values containing this text, for example sham to find the shampoo categories.
- How many (`limit`, number): How many values to return, up to 100. From 1 to 100. Default: `20`.

**Outputs**: The values a filter can be set to.

- `catalogue` (text): Which list was browsed.
- `catalogue_name` (text): That list in words.
- `contains` (text): The text values were filtered by.
- `count` (number): How many values came back.
- `filter_field` (text): The field of 'Find products' these values go in.
- `matched_count` (number): How many values matched before the row limit.
- `message` (text): Why nothing came back. Empty when something did.
- `published_count` (number): How many Open Beauty Facts publishes at once; it is the most-used hundred, not the whole list.
- `total_count` (number): How many values of this kind exist in all.
- `values` (list): The values, most-used first, each with the id a filter takes, a readable name, how many products carry it, and whether Open Beauty Facts recognises it or a contributor typed it.

**Example output**

```json
{
  "catalogue": "labels",
  "catalogue_name": "Labels",
  "contains": "",
  "count": 2,
  "filter_field": "label",
  "matched_count": 2,
  "message": "",
  "published_count": 100,
  "total_count": 2468,
  "values": [
    {
      "id": "en:vegan",
      "name": "Vegan",
      "product_count": 1795,
      "recognised": true
    },
    {
      "id": "en:without-paraben",
      "name": "Without paraben",
      "product_count": 585,
      "recognised": true
    }
  ]
}
```

### Check a product's ingredients

Read a product's ingredient list and say which of the groups people commonly avoid are in it. It knows twelve: parabens, sulfates, silicones, fragrance and its declarable allergens, drying alcohol, formaldehyde releasers, isothiazolinone preservatives, PEGs, mineral oil, aluminium salts and chemical UV filters. Each one names the ingredient that put it there. Add your own ingredients to watch for as well. It also reports the groups that are not present, because 'no parabens' is usually the answer being looked for. This reports what the list contains; it is not a safety assessment, and the list is contributed by volunteers.

**Inputs**

- Barcode (`barcode`, text, required): The barcode printed on the pack, for example 4005800001192. Spaces and hyphens are fine.
- Look for (`avoid`, text): Which groups to look for. Leave all of them unticked to check every group. One or more of: `parabens` (Parabens: preservatives whose names end in -paraben), `sulfates` (Sulfates: SLS, SLES and the other foaming detergents, not every ingredient with sulfate in its name), `silicones` (Silicones: dimethicone, siloxanes and the rest of the -cone family), `fragrance` (Fragrance (parfum): an undeclared fragrance blend, however it is spelled), `fragrance_allergens` (Declarable fragrance allergens: the 26 fragrance compounds EU labelling names separately, such as limonene and linalool), `drying_alcohol` (Drying alcohol: alcohol denat. and ethanol, not the fatty alcohols such as cetyl or stearyl alcohol), `formaldehyde_releasers` (Formaldehyde releasers: preservatives that work by releasing formaldehyde slowly), `isothiazolinones` (Isothiazolinone preservatives: MI and MCI, common contact allergens in rinse-off products), `pegs` (PEGs and ethoxylates: PEG- and PPG- compounds, polysorbates and the -eth family), `mineral_oil` (Mineral oil and petrolatum: petroleum-derived occlusives, including paraffinum liquidum), `aluminium_salts` (Aluminium salts: the antiperspirant salts, not aluminium used as a thickener or a colour), `chemical_uv_filters` (Chemical UV filters: the absorbing sunscreen filters, as opposed to zinc or titanium).
- Also look for (`also_avoid`, text): Optional. Your own ingredients to watch for, separated by commas; a personal allergen, say. Part of a name is enough: nickel finds Nickel Sulfate.

**Outputs**: What the ingredient list turned out to hold.

- `analysis` (object): What the service's own analysis concluded about the list: vegan, vegetarian and palm oil, each answered in words.
- `barcode` (text): The barcode that was checked.
- `brand` (text): The brand on the pack.
- `checked` (list): The groups that were looked for.
- `clear` (list): The groups that were looked for and are not present.
- `concern_count` (number): How many groups are present.
- `found` (true/false): True when the product was found.
- `found_concerns` (list): The groups that are present, each naming the ingredients that put it there.
- `ingredient_count` (number): How many entries the list holds. It is read off a photograph of the pack, so not every entry is an ingredient.
- `ingredients` (list): The whole ingredient list, each entry with its printed INCI name and its taxonomy id.
- `ingredients_photo_url` (text): The photograph of the ingredient list, which is the way back in when the list has not been typed in.
- `ingredients_recorded` (true/false): True when somebody has typed the ingredient list in. False means there was nothing to check.
- `ingredients_text` (text): The ingredient list as one block of text, exactly as it was typed in.
- `message` (text): Why nothing could be checked. Empty when it could.
- `name` (text): The product name.
- `other_database` (object): Where the product really lives when it is not a cosmetic: the sibling database's name and the page for this barcode in it.
- `page_url` (text): The product's page on openbeautyfacts.org.
- `reason` (text): Why nothing came back: not_in_the_database, or different_kind_of_product when the barcode belongs to a food or a pet food. Empty when the product was found.
- `recognised_ingredient_count` (number): How many of those entries Open Beauty Facts matched to a real ingredient. The gap between the two is text on the pack, such as a batch code or an importer's address.

**Example output**

```json
{
  "barcode": "8001090662231",
  "brand": "Herbal Essences",
  "checked": [
    "Parabens",
    "Sulfates (SLS and SLES)",
    "Silicones",
    "Fragrance (parfum)"
  ],
  "clear": [
    "Parabens",
    "Fragrance (parfum)"
  ],
  "concern_count": 2,
  "found": true,
  "found_concerns": [
    {
      "concern": "Sulfates (SLS and SLES)",
      "id": "sulfates",
      "ingredients": [
        "Sodium Laureth Sulfate",
        "Sodium Lauryl Sulfate"
      ],
      "note": "the foaming detergents SLS and SLES"
    },
    {
      "concern": "Silicones",
      "id": "silicones",
      "ingredients": [
        "Dimethiconol",
        "Dimethicone"
      ],
      "note": "dimethicone, siloxanes and the rest of the -cone family"
    }
  ],
  "ingredient_count": 41,
  "ingredients_recorded": true,
  "message": "",
  "name": "Coconut Milk",
  "page_url": "https://world.openbeautyfacts.org/product/8001090662231",
  "recognised_ingredient_count": 38
}
```

### Compare products

Put two to five products side by side by barcode and work out what they share and what only one of them has: which ingredients are in every one, which are in just this one, and the categories and label claims they have in common. The answer to 'which of these two should I buy' is the difference, not two lists printed one after the other. Ingredient lists are read off photographs of the pack, so the comparison uses the entries Open Beauty Facts recognised as ingredients; each product's full list comes back with it.

**Inputs**

- Barcodes (`barcodes`, list, required): Two to five barcodes to compare. One per line, or separated by commas.

**Outputs**: The products side by side, and their differences.

- `barcodes` (list): The barcodes that were compared.
- `count` (number): How many barcodes were compared.
- `found_count` (number): How many of them were found.
- `message` (text): What went wrong with any barcode that was not found. Empty when all were.
- `only_in_one` (list): Per product, the ingredients, categories and labels none of the others have.
- `products` (list): The full record for each barcode, in the order they were given. One that was not found carries found: false and the reason.
- `shared` (object): The ingredients, categories and labels every one of the compared products has.

**Example output**

```json
{
  "barcodes": [
    "8001090662231",
    "4005800001192"
  ],
  "count": 2,
  "found_count": 2,
  "message": "",
  "only_in_one": [
    {
      "barcode": "8001090662231",
      "categories": [
        "Shampoos"
      ],
      "ingredients": [
        "Sodium Laureth Sulfate",
        "Dimethicone"
      ],
      "labels": [],
      "name": "Coconut Milk"
    },
    {
      "barcode": "4005800001192",
      "categories": [
        "Moisturizing creams"
      ],
      "ingredients": [
        "Paraffinum Liquidum",
        "Lanolin Alcohol"
      ],
      "labels": [],
      "name": "Nivea Creme"
    }
  ],
  "products": [
    {
      "barcode": "8001090662231",
      "brand": "Herbal Essences",
      "found": true,
      "ingredient_count": 41,
      "ingredients_recorded": true,
      "name": "Coconut Milk"
    },
    {
      "barcode": "4005800001192",
      "brand": "Nivea",
      "found": true,
      "ingredient_count": 21,
      "ingredients_recorded": true,
      "name": "Nivea Creme"
    }
  ],
  "shared": {
    "categories": [],
    "ingredients": [
      "Aqua",
      "Citric Acid",
      "Glycerin",
      "Parfum"
    ],
    "labels": []
  }
}
```

### Find products

Search about 75,000 cosmetics by words, and narrow by category, brand, label, ingredient or the country a product is sold in. Use it to find a product's barcode from its name, to list every vegan deodorant, or to find what contains an ingredient. Each filter is a dropdown of values the database actually holds, so a filter that matches nothing is rare, and when it happens the result says so rather than coming back as an empty list.

**Inputs**

- Words (`words`, text): Optional. Words to look for in the product name and brand, for example coconut shampoo.
- Category (`category`, text): Optional. Only products in this category, for example Shampoos or Deodorants.
- Brand (`brand`, text): Optional. Only products from this brand.
- Label (`label`, text): Optional. Only products carrying this claim, for example Vegan, Organic or Without paraben.
- Ingredient (`ingredient`, text): Optional. Only products whose ingredient list includes this, for example Niacinamide.
- Sold in (`country`, text): Optional. Only products sold in this country.
- Order by (`sort`, text): How to order the results. Most scanned puts the products people actually buy first. One of: `unique_scans_n` (Most scanned), `created_t` (Newest first), `last_modified_t` (Recently updated), `product_name` (Name (A to Z)). Default: `unique_scans_n`.
- How many (`limit`, number): How many products to return, up to 100. From 1 to 100. Default: `20`.
- Page (`page`, number): Which page of results to return. Page 2 continues where page 1 stopped. At least 1. Default: `1`.

**Outputs**: One page of matching products.

- `count` (number): How many products this page returned.
- `filters` (object): The filters that were applied.
- `limit` (number): How many products a page holds.
- `message` (text): Why nothing matched. Empty when something did.
- `page` (number): Which page this is.
- `page_count` (number): How many pages the matches fill.
- `products` (list): The matching products, each with its barcode, name, brand, size, categories, labels, countries and front photograph.
- `sort` (text): The ordering that was applied.
- `sort_name` (text): That ordering in words.
- `total_count` (number): How many products match in all.
- `words` (text): The words that were searched for.

**Example output**

```json
{
  "count": 1,
  "filters": {},
  "limit": 20,
  "message": "",
  "page": 1,
  "page_count": 3,
  "products": [
    {
      "added_on": "2024-11-13",
      "barcode": "8001090662231",
      "brand": "Herbal Essences",
      "categories": [
        {
          "id": "en:shampoos",
          "name": "Shampoos"
        }
      ],
      "countries": [
        {
          "id": "en:morocco",
          "name": "Morocco"
        }
      ],
      "ingredients_recorded": true,
      "labels": [],
      "name": "Coconut Milk",
      "page_url": "https://world.openbeautyfacts.org/product/8001090662231",
      "period_after_opening": null,
      "photo_url": "https://images.openbeautyfacts.org/images/products/800/109/066/2231/front_fr.11.400.jpg",
      "size": "400 ml",
      "updated_on": "2026-05-22"
    }
  ],
  "sort": "unique_scans_n",
  "sort_name": "Most scanned",
  "total_count": 49,
  "words": "coconut shampoo"
}
```

### Get a product's photos

Get the photographs Open Beauty Facts holds for a barcode: the front of the pack, the ingredient list and the packaging, at thumbnail, medium or large size. The ingredient photograph is the useful one when the ingredients have not been typed in yet: hand it to a step that reads text from images and the list is recoverable anyway.

**Inputs**

- Barcode (`barcode`, text, required): The barcode printed on the pack, for example 4005800001192. Spaces and hyphens are fine.
- Size (`size`, text): How large the photographs should be. One of: `display` (Large (400px)), `small` (Medium (200px)), `thumb` (Thumbnail (100px)). Default: `display`.

**Outputs**: The photographs on the record.

- `barcode` (text): The barcode that was looked up.
- `brand` (text): The brand on the pack.
- `found` (true/false): True when the product was found.
- `message` (text): Why there are none. Empty when there are.
- `name` (text): The product name.
- `other_database` (object): Where the product really lives when it is not a cosmetic: the sibling database's name and the page for this barcode in it.
- `page_url` (text): The product's page on openbeautyfacts.org.
- `photo_count` (number): How many photographs came back.
- `photos` (list): One entry per kind of photograph, each with its address at the chosen size and the languages the pack was photographed in.
- `reason` (text): Why nothing came back: not_in_the_database, or different_kind_of_product when the barcode belongs to a food or a pet food. Empty when the product was found.
- `size` (text): The photo size that was asked for.
- `size_name` (text): That size in words, with its pixels.

**Example output**

```json
{
  "barcode": "4005800001192",
  "brand": "Nivea",
  "found": true,
  "message": "",
  "name": "Nivea Creme",
  "page_url": "https://world.openbeautyfacts.org/product/4005800001192",
  "photo_count": 2,
  "photos": [
    {
      "kind": "front",
      "kind_name": "Front of pack",
      "languages": [
        "ar",
        "fr"
      ],
      "url": "https://images.openbeautyfacts.org/images/products/400/580/000/1192/front_fr.5.400.jpg"
    },
    {
      "kind": "ingredients",
      "kind_name": "Ingredient list",
      "languages": [
        "fr"
      ],
      "url": "https://images.openbeautyfacts.org/images/products/400/580/000/1192/ingredients_fr.7.400.jpg"
    }
  ],
  "size": "display",
  "size_name": "Large (400px)"
}
```

### List recently added products

List the cosmetics added to Open Beauty Facts since a date, newest first, optionally only in a category, from a brand or carrying a label, or the ones edited since then instead. This is the step behind watching the database: a weekly run that reports the new vegan shampoos, or a check for anything new from a brand you stock.

**Inputs**

- Since (`since`, date, required): Only products from this date onwards.
- Added or updated (`changed`, text): Whether the date means when a product was first added, or when it was last edited. One of: `created_t` (Added), `last_modified_t` (Updated). Default: `created_t`.
- Category (`category`, text): Optional. Only products in this category, for example Shampoos or Deodorants.
- Brand (`brand`, text): Optional. Only products from this brand.
- Label (`label`, text): Optional. Only products carrying this claim, for example Vegan, Organic or Without paraben.
- How many (`limit`, number): How many products to return, up to 100. From 1 to 100. Default: `20`.

**Outputs**: What has appeared since the date, newest first.

- `changed` (text): Whether the date was read against when a product was added or when it was last edited.
- `changed_name` (text): That choice in words.
- `count` (number): How many products came back.
- `filters` (object): The filters that were applied.
- `limit` (number): The most products that could come back.
- `message` (text): Why nothing came back. Empty when something did.
- `more_available` (true/false): True when the list stopped at the row limit rather than at the date, so there are more to read.
- `pages_read` (number): How many pages of results the walk read to answer this. The service rations searches, so the walk is bounded.
- `products` (list): The products, newest first, each with its barcode, name, brand, categories and the dates it was added and last edited.
- `since` (text): The date they were counted from.

**Example output**

```json
{
  "changed": "created_t",
  "changed_name": "Added",
  "count": 1,
  "filters": {},
  "limit": 20,
  "message": "",
  "more_available": true,
  "products": [
    {
      "added_on": "2026-09-13",
      "barcode": "0667555841313",
      "brand": "Bath & Body Works",
      "categories": [],
      "countries": [
        {
          "id": "en:united-states",
          "name": "United states"
        }
      ],
      "ingredients_recorded": false,
      "labels": [],
      "name": "Fresh Getaway Fine Fragrance Mist",
      "page_url": "https://world.openbeautyfacts.org/product/0667555841313",
      "size": "236 ml",
      "updated_on": "2026-09-13"
    }
  ],
  "since": "2026-09-10"
}
```

### Look up a product

Look a cosmetic up by the barcode on its pack and get everything Open Beauty Facts holds about it: the name and brand, the size, what kind of product it is, the claims on the label, the ingredient list as printed, how long it lasts after opening, where it is sold, and the photographs of the pack. A barcode nobody has entered yet, and a barcode that turns out to be a food or a pet food rather than a cosmetic, both come back as an answer saying which, rather than as an error, so a workflow can branch on it.

**Inputs**

- Barcode (`barcode`, text, required): The barcode printed on the pack, for example 4005800001192. Spaces and hyphens are fine.

**Outputs**: What the barcode turned out to be.

- `barcode` (text): The barcode that was looked up.
- `found` (true/false): True when Open Beauty Facts holds this product.
- `message` (text): A sentence explaining a product that was not found. Empty when it was.
- `other_database` (object): Where the product really lives when it is not a cosmetic: the sibling database's name and the page for this barcode in it.
- `product` (object): The product record: name, brand, size, categories, labels, countries, shelf life after opening, ingredients, allergens, packaging, photographs and when it was added and last edited. Absent when the product was not found.
- `reason` (text): Why nothing came back: not_in_the_database, or different_kind_of_product when the barcode belongs to a food or a pet food.

**Example output**

```json
{
  "barcode": "4005800001192",
  "found": true,
  "message": "",
  "product": {
    "added_on": "2014-09-06",
    "allergens": [],
    "analysis": {
      "palm_oil": "Not known",
      "vegan": "Not known",
      "vegetarian": "Not known"
    },
    "barcode": "4005800001192",
    "brand": "Nivea",
    "brands": [
      "Nivea"
    ],
    "categories": [
      {
        "id": "en:face",
        "name": "Face"
      },
      {
        "id": "en:moisturizing-creams",
        "name": "Moisturizing creams"
      }
    ],
    "countries": [
      {
        "id": "en:france",
        "name": "France"
      }
    ],
    "data_completeness_percent": 78,
    "description": "Moisturising cream",
    "ingredient_count": 21,
    "ingredients": [
      {
        "id": "en:water",
        "name": "Aqua"
      },
      {
        "id": "en:glycerin",
        "name": "Glycerin"
      }
    ],
    "ingredients_photo_url": "https://images.openbeautyfacts.org/images/products/400/580/000/1192/ingredients_fr.7.400.jpg",
    "ingredients_recorded": true,
    "ingredients_text": "Aqua, Paraffinum Liquidum, Glycerin...",
    "labels": [],
    "language": "fr",
    "made_in": [],
    "name": "Nivea Creme",
    "origins": [],
    "packaging": [
      {
        "id": "metal",
        "name": "Metal"
      }
    ],
    "page_url": "https://world.openbeautyfacts.org/product/4005800001192",
    "period_after_opening": {
      "label": "12 months after opening",
      "months": 12,
      "recorded_as": "12 mois"
    },
    "photo_url": "https://images.openbeautyfacts.org/images/products/400/580/000/1192/front_fr.5.400.jpg",
    "scan_count": 59,
    "size": "150 ml",
    "stores": [],
    "updated_on": "2026-03-25"
  }
}
```
