INCI Beauty Safety Score & Ingredients Scraper avatar

INCI Beauty Safety Score & Ingredients Scraper

Pricing

from $4.50 / 1,000 results

Go to Apify Store
INCI Beauty Safety Score & Ingredients Scraper

INCI Beauty Safety Score & Ingredients Scraper

Scrape INCI Beauty by barcode: the 0-20 safety score, full risk-rated INCI composition and ingredient reference dictionary. Score INCI, pay per result.

Pricing

from $4.50 / 1,000 results

Rating

0.0

(0)

Developer

Extractify Labs

Extractify Labs

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

2

Monthly active users

a month ago

Last modified

Share

🧴 INCI Beauty Safety Score & Ingredients Scraper

Scan a barcode, get the score French shoppers actually check. This actor turns incibeauty.com into a clean, structured feed: every cosmetic product keyed by its EAN/GTIN barcode, carrying INCI Beauty's published 0-20 "Note INCI Beauty" safety score, the full ordered ingredient (INCI) composition with each ingredient's risk class, product images and retail price offers. Alongside the products you get a 16,879-record INCI ingredient reference dictionary (INCI name, CAS, EINECS, functions, risk class, origin, multilingual names). Two entities, one dataset, joinable on the ingredient identifier.

The key thing to understand up front: we reproduce INCI Beauty's own published data, faithfully. The 0-20 score and the green-to-red ingredient ratings are theirs, captured verbatim. This actor invents no methodology and computes no score of its own. If you have ever been burned by a scraper that bolts on its own opinionated "safety rating," that is exactly the trap this avoids.

🇫🇷 INCI Beauty est un service du marché français. Cet acteur extrait les produits cosmétiques (score 0-20 « Note INCI Beauty », composition INCI complète, classe de risque par ingrédient) et le dictionnaire de référence des ingrédients INCI d'incibeauty.com.


👤 Who it's for

  • 💄 Cosmetic brands & formulators (R&D, regulatory, competitive marketing). See exactly how your SKUs and your competitors' score on a French-market gatekeeper, ingredient by ingredient, and benchmark composition against your own catalog.
  • 📱 Clean-beauty, "dupe" and comparison apps. Barcode in, score plus composition out, so you can power "is this safe?" and "show me a better-rated alternative" without building a scoring system.
  • 🛒 Retailers & e-commerce teams enriching product pages with a recognized safety score and surfacing better-rated SKUs.
  • 🔬 Researchers & NGOs running ingredient-prevalence and cosmetic-safety studies across the catalog plus the full ingredient dictionary.
  • ✍️ Affiliate & SEO content sites building score-plus-price comparison content that earns engagement.

✅ What you get

  • 🎯 The real 0-20 "Note INCI Beauty" score, plus the quality tier behind the colored-flower badge, captured exactly as INCI Beauty publishes it.
  • 🌿 Per-ingredient risk, green to red. Every ingredient in the composition carries its hazard level (0 = no concern, higher = more concern) and its penalty families, aligned to the declared order.
  • 🧪 The full ordered INCI composition for each product, not a summary. This is the headline field.
  • 🔍 A transparent score breakdown (valid ingredient count, composition size, clean and bio flags) so you can see why a product scored the way it did and reconcile it against your own data.
  • 🆔 EAN/GTIN as the primary key, so products drop straight into retail catalogs, open product databases and your own SKU lists.
  • 📚 A 16,879-record INCI ingredient dictionary: official INCI name, CAS, EINECS, food-additive E-number, cosmetic functions, risk/penalty class, origin, free-text notes, localized names (22 locales) and a count of how many products contain each ingredient.
  • ⏱️ Freshness built in. Risk classes and scores are a moving target on INCI Beauty as their knowledge base updates. Every row carries a scraped_at capture timestamp, and products carry the source's own composition date, so a periodic re-crawl keeps you current instead of stuck with a one-time dump.
  • ⚙️ You choose what to pull: products only, the ingredient dictionary only, or both in one run. Narrow by brand, barcode, ingredient or specific URLs. Toggle composition and price.

🗂️ Scope & coverage (what's in, what's not)

Covered

  • 🚀 Products: the cosmetic catalog keyed by EAN/GTIN, walked brand by brand across the full A-Z brand index (hundreds of thousands of products, on the order of ~300,000), de-duplicated by barcode. No result-window cap, so a full crawl reaches the whole brand-listed catalog.
  • 🧬 Product composition & score: the complete per-product INCI composition (ordered list + per-ingredient risk + score breakdown), captured for each product by default.
  • 💶 Price offers: the merchant price offers shown on each product page (EUR by default).
  • 📖 Ingredients: the full browsable INCI reference dictionary, 16,879 verified distinct ingredients, de-duplicated by ingredient id.

Not covered (by design)

  • 💬 Product reviews / Q&A are not collected. They appear only on a Cloudflare-protected product page with no API path, so this actor does not fetch them. The review fields remain in the schema (always empty) for transparency.
  • 🏷️ Brandless products (any product not listed under a brand) fall outside the brand-walk, the one structural item edge.
  • 🔤 Ingredient synonym tail beyond the 16,879 browsable records (a much larger backend synonym keyspace) is intentionally out of default scope.
  • 🔒 Account-gated B2B / login-walled feeds are out of scope. This actor reads only what INCI Beauty shows publicly to anonymous visitors; it never logs in.

These edges could be covered later by companion actors if you need them. They are boundaries, not defects.


📊 Output fields

The actor writes one dataset with two row types. Every row has an entity field set to either product or ingredient. Product rows fill the product fields; ingredient rows fill the ingredient fields; a small set of fields is shared by both. Use the built-in Products and Ingredient reference dataset views to see each as a clean table, or filter on entity yourself.

Shared fields (both entities)

FieldTypeDescription
entitystringRow type: product or ingredient. Use it to filter, or pick the matching dataset view.
sourceUrlstringThe incibeauty.com page this row was collected from.
websitestringSource website host (incibeauty.com).
scrapeDatestringUTC date (YYYY-MM-DD) the row was collected. Scores and risk classes change over time, so this matters.
scraped_atstring | nullUTC capture timestamp (ISO-8601). The freshness key for the mutable score and risk data.
countrystring | nullISO country of the service (FR).
currencystring | nullPrice currency for product offers (EUR).
product_localestring | nullLocale of the captured row (default fr).
locale_variantsarray | nullOther-language versions of the page available (hreflang variants).
canonical_urlstring | nullCanonical page URL.

Product fields (entity = "product")

FieldTypeDescription
ean_gtinstring | nullThe product barcode (EAN / GTIN). Primary key for products. Several barcode forms can occur (13-digit, zero-padded, hyphenated).
product_namestring | nullProduct title.
brandstring | nullBrand name.
brand_slugstring | nullBrand slug (the key to the brand's page).
marque_parentstring | nullParent company or group behind the brand, when published.
inci_scorenumber | nullThe 0-20 "Note INCI Beauty" overall safety score.
score_quality_tierstring | nullQuality tier behind the colored-flower badge.
score_breakdownobject | nullThe components behind the 0-20 score: score value, count of valid ingredients, composition size, and the clean / bio flags.
is_unratedboolean | nullTrue when the product is not yet scored.
is_approximative_noteboolean | nullTrue when the score is approximate.
product_categorystring | nullCosmetic category path.
full_inci_compositionarray | nullThe headline field. The full ordered INCI ingredient list. Each entry carries the ingredient name, official name, risk level and function families.
composition_ingredient_namearray | nullThe official INCI names of the composition, in declared order.
composition_ingredient_positionarray | nullThe 1-based declared position of each ingredient.
per_ingredient_risk_classarray | nullPer-ingredient hazard level (0 = no concern, higher = more concern), aligned to the composition order.
per_ingredient_penalty_reasonsarray | nullRisk/penalty families per ingredient, aligned to the composition order.
composition_statusstring | nullWhether the composition is fully expanded (the normal case) or, in a rare fallback, returned in raw form. In the published actor this is the expanded form.
composition_ciphertextstring | nullEmpty in normal runs; populated only in the rare raw fallback noted above.
composition_ciphertext_b64_leninteger | nullDiagnostic length value, present only alongside the rare fallback.
product_image_largestring | nullLarge product image URL.
product_image_smallstring | nullSmall product image URL.
product_image_thumbstring | nullThumbnail image URL (from the brand listing card).
user_photosarray | string | nullUser-submitted photos when available.
where_to_buy_tablearray | nullMerchant price offers. Each offer carries retailer, price value, currency, availability, a display string and a shop link.
acheter_currency_optionsarray | nullCurrencies offered by the price widget.
acheter_response_statusinteger | nullStatus of the price/offers lookup (200, or 404 when a product has no offers).
date_compostring | nullWhen INCI Beauty last computed the composition/score (ISO-8601). A second freshness signal.
similarobject | array | nullRelated/recommended products.
alternative_productsarray | null"Produits alternatifs" links. Not collected (bot-protected page; always null) — for related products see similar.
comment_count_newinteger | nullCount behind the "new comments" badge.
comment_count_totalinteger | nullTotal review/comment count. Not collected (always null).
reviews_commentsarray | nullUser reviews/comments. Not collected — the reviews page is bot-protected (always empty).
review_authorstring | nullPublic review author pseudonym. Not collected (always null).
review_bodystring | nullReview free text. Not collected (always null).
review_datestring | nullReview date. Not collected (always null).
review_idinteger | nullReview identifier. Not collected (always null).
product_miniobject | string | nullA lighter product card surface, when available.
product_subscription_statestring | boolean | nullThe anonymous "searchable" flag for the product.
brand_logostring | nullBrand logo image URL.
product_weightstring | nullNet weight / volume, from the product information block.
skin_typestring | array | nullTarget skin type(s), from the product information block.
certificationsarray | nullCertifications / labels (e.g. bio, clean). Sparse; present mainly on certified products.
product_informationarray | object | nullThe product information block: weight/volume, skin type, period-after-opening, usage advice.
engagement_statsobject | nullPublic engagement counters (scans, likes).
product_natural_extractsarray | object | nullNatural-extract details for the product.

Ingredient fields (entity = "ingredient")

FieldTypeDescription
ingredient_idinteger | nullInteger ingredient id. Primary key for ingredients, and the join key from a product's composition.
ingredient_slugstring | nullURL slug.
inci_namestring | nullOfficial INCI name.
ingredient_french_namestring | nullFrench common name.
cas_numberstring | nullCAS registry number.
einecs_numberstring | nullEINECS / EC number.
additif_enumberstring | nullFood-additive E-number, when applicable.
ingredient_descriptionstring | nullFree-text "À savoir" note, when present.
ingredient_functionsarray | nullCosmetic functions, each with a name and description.
ingredient_risk_penalty_statusstring | nullThe colored-flower risk/penalty rating label.
ingredient_risk_penalty_tierstring | nullThe risk tier behind the flower icon.
ingredient_originarray | nullOrigin classification (e.g. vegetal, synthetic).
ingredient_classificationarray | nullClassification labels.
ingredient_names_other_languagesarray | nullNames in other languages, from the detail page.
ingredient_name_localizedobject | nullA {locale: name} map across 22 locales.
ingredient_products_containingarray | nullA sample of products that contain this ingredient, each with barcode, name, brand and score.
ingredient_nb_produitsinteger | nullHow many products contain this ingredient (a scale signal).
ingredient_natural_extractobject | string | nullNatural-extract detail for the ingredient, when available.
inci_name_md5string | nullStable hash of the INCI name.
ingredient_spellcheck_namestring | nullNormalized name.
ingredient_id_synonymeinteger | nullSynonym id (0 = canonical record).
ingredient_linkstring | nullCanonical ingredient link.

🔗 About the product ↔ ingredient join. A product's composition carries an ingredient id, and the ingredient dictionary is keyed by that same id, so the two streams are designed to be joined on the ingredient identifier. Run with entity = both to get both in one feed.


🔧 Input

Everything is optional. Leave it all on the defaults for a quick, non-empty sample run.

InputWhat it does
What to collect (entity)products, ingredients, or both. Products are EAN-keyed and scored with full composition; ingredients are the reference dictionary.
Start URLs (startUrls)Specific INCI Beauty page URLs to collect: a product page (/produit/<barcode>), an ingredient page (/ingredients/<id>-<name>), or a brand page (/brand/<brand-slug>). Leave empty to crawl by the filters below.
Brands (brands)Brand slugs to crawl (e.g. loreal-paris, nivea). Only products from these brands are returned. Empty = walk the full A-Z brand catalog.
Product barcodes (eans)A list of EAN / GTIN barcodes to look up directly, skipping the brand walk. Ideal for enriching an existing barcode list.
Ingredient identifiers (ingredientIds)A list of ingredient id-name segments (e.g. 12345-aqua) to look up directly from the dictionary.
Maximum results (maxItems)Stop after this many records per stream (products and ingredients are capped independently). Lower it for a quick test. The free daily-test default is 10.
Include price offers (includePrice)ON by default; adds negligible cost. Collects the retail price offers shown on each product page. Products only.
Enrich ingredient records (enrichIngredients)OFF by default. Adds extra naming, classification and CAS detail to each ingredient at the cost of one extra request per ingredient. Ingredients only.
Proxy (proxyType)No proxy (default, fastest and cheapest) works for the whole actor. Apify Proxy routes through your own Apify account (you pay Apify for that traffic) if you want to rotate IPs.

⚡ Quick sample run (the default, finishes fast)

This is the prefilled default. It pulls a small slice of the ingredient dictionary and finishes non-empty in well under five minutes, with no proxy.

{
"entity": "ingredients",
"maxItems": 10,
"enrichIngredients": false,
"proxyType": "none"
}

💄 One brand, products with composition and score

Pull a single brand's products, each with the full risk-rated composition, the 0-20 score and price offers.

{
"entity": "products",
"brands": ["respire"],
"maxItems": 100,
"includePrice": true,
"proxyType": "none"
}

🔢 A handful of barcodes (enrich your own SKU list)

Resolve specific barcodes straight to their scored product records.

{
"entity": "products",
"eans": ["3760368740730", "4005808851904"],
"includePrice": true,
"proxyType": "none"
}

📦 Sample output

A product row (values are illustrative placeholders):

{
"entity": "product",
"ean_gtin": "3760368740730",
"product_name": "Deodorant Stick Fleur de Coton",
"brand": "Respire",
"brand_slug": "respire",
"inci_score": 19.5,
"score_quality_tier": "fleurfont1",
"score_breakdown": { "score_sur20": 19.5, "valid_incis": 3, "composition_count": 3, "is_ib_clean": true, "is_bio": false },
"product_category": "Deodorant",
"composition_ingredient_name": ["HELIANTHUS ANNUUS SEED OIL", "PARFUM", "TOCOPHEROL"],
"composition_ingredient_position": [1, 2, 3],
"per_ingredient_risk_class": [0, 2, 0],
"where_to_buy_table": [{ "retailer": "Example Shop", "price_value": 9.9, "price_currency": "EUR", "price_availability": "in_stock" }],
"product_image_large": "https://incibeauty.com/photos/products/large/.../image.jpg",
"date_compo": "2025-08-20T04:52:45Z",
"sourceUrl": "https://incibeauty.com/produit/3760368740730",
"scrapeDate": "2026-06-22",
"scraped_at": "2026-06-22T18:00:00Z"
}

An ingredient row (values are illustrative placeholders):

{
"entity": "ingredient",
"ingredient_id": 1447,
"inci_name": "HELIANTHUS ANNUUS SEED OIL",
"ingredient_french_name": "Huile de graines de tournesol",
"cas_number": "8001-21-6",
"einecs_number": "232-273-9",
"ingredient_functions": [{ "function_name": "Emollient", "function_desc": "Softens the skin." }],
"ingredient_risk_penalty_status": "No concern",
"ingredient_risk_penalty_tier": "1",
"ingredient_origin": ["Vegetal"],
"ingredient_name_localized": { "en": "Sunflower seed oil" },
"ingredient_nb_produits": 227635,
"sourceUrl": "https://incibeauty.com/ingredients/1447-helianthus-annuus-seed-oil",
"scrapeDate": "2026-06-22",
"scraped_at": "2026-06-22T18:00:00Z"
}

❓ FAQ

How fast is it, and how many results will I get? The quick sample default (10 ingredient records, no proxy) finishes non-empty in well under five minutes. A full crawl scales with how much you ask for: the products catalog runs into hundreds of thousands of records (on the order of ~300,000), and the ingredient dictionary is 16,879 verified records. Use maxItems to cap either stream while you test.

How fresh is the data? You get whatever INCI Beauty publishes at the moment you run the actor. Scores and per-ingredient risk classes are mutable, they change as INCI Beauty updates its knowledge base, so every row carries a scraped_at timestamp and products also carry the source's own date_compo. Re-run on a schedule to keep current; this is a refreshable feed, not a one-time dump.

Where does the score come from? Is it your rating? No. The 0-20 score, the quality tier and the per-ingredient risk classes are INCI Beauty's own published data, captured faithfully. This actor computes no score and invents no methodology.

Do I need a proxy? No. The default No proxy option works for the whole actor and is the fastest and cheapest. Apify Proxy is optional and routes through your own Apify account (you pay Apify for that traffic) if you want to rotate IPs.

How does billing work? This actor uses Pay Per Result: you are billed per item written to the dataset. There is no separate start fee. If you are on a free plan, the run stops gracefully when it reaches your usage limit, it does not crash, so you always keep the results collected up to that point. Use maxItems to control exactly how many results (and how much spend) you want.

Can I get just the products, or just the ingredients? Yes. Set What to collect to products, ingredients, or both. Both streams land in the same dataset, tagged by the entity field, and the dataset ships with separate Products and Ingredient reference views.

Can I look up specific products by barcode? Yes. Put your EAN / GTIN barcodes in the Product barcodes input and each one is resolved straight to its scored product record, skipping the brand walk. Perfect for enriching an existing SKU list.

Are reviews included? No. Reviews appear only on a bot-protected product page (no API path), so this actor does not collect them. It focuses on the 0-20 score, the full risk-rated composition, price, and the 16,879-ingredient dictionary.

Is this legal? This actor collects data that INCI Beauty displays publicly to anonymous visitors. You are responsible for using the output in line with applicable law and INCI Beauty's terms. See the disclaimers below.


⚠️ Disclaimers

Unofficial and not affiliated. This actor is unofficial and is not affiliated with, authorized by, or endorsed by INCI Beauty or Touslesprix. It is not "the INCI Beauty API." No third-party trademarks or logos are used. All product, brand and service names belong to their respective owners.

Public data. This actor collects data that INCI Beauty displays publicly to anonymous visitors.

Faithful reproduction. The 0-20 INCI Beauty score, the per-ingredient risk classes and the compositions are INCI Beauty's published data, reproduced faithfully. This actor does not invent a scoring methodology and does not compute its own scores or ratings.

Personal data. By default this actor collects no personal data — it returns public cosmetic product and ingredient information. Product reviews (which would contain author pseudonyms and free text) are not collected, because their source page is bot-protected. Use any output in line with applicable law and INCI Beauty's terms.

Responsible use. Use this data in compliance with applicable law and INCI Beauty's terms. You are responsible for your use of the output, including any reuse, redistribution, or processing of personal data.


🔎 Keywords: INCI Beauty scraper, cosmetic safety score, Note INCI Beauty, INCI ingredients, composition cosmétique, score de sécurité cosmétique, EAN GTIN cosmetics, ingredient risk class, base de données ingrédients INCI, CAS EINECS, cosmetic ingredient database.