CosIng · API · Developers

How to query the CosIng database programmatically

9 min
  • The CosIng database API has public read endpoints you can query right now, with no API key: search, stats, ingredient detail, Annex listings, CMR, recently prohibited, and a regulatory watch feed.
  • Every example below was run against the live API before publishing — responses are real captures, trimmed for readability.
  • One gotcha will bite you in the first five minutes: search defaults to regulated ingredients only. regulated_only=false unlocks the full INCI inventory.

1. What you can query

The CosIng database is the European Commission's inventory of cosmetic ingredients: INCI names, CAS and EC numbers, functions, and the restrictions defined in Regulation 1223/2009 Annexes II–VI. The official portal serves humans; if you are building software, you want the same data over HTTP with predictable JSON.

That is what the CosIng database API provides. The base URL for all public endpoints is:

https://api.bdapi.app/api/public

No authentication, no registration. Rate limits apply per IP and are documented per route — we will get to them at the end, because you should design around them from the start.

2. Search by INCI name, CAS or EC number

The workhorse endpoint. It matches INCI names, CAS numbers and EC numbers:

curl "https://api.bdapi.app/api/public/cosing/search?q=phenoxyethanol&limit=1"
{
  "rows": [{
    "inci_name": "PHENOXYETHANOL",
    "cas_no": "122-99-6",
    "ec_no": "204-589-7",
    "chemical_name": "2-Phenoxyethanol",
    "function_names": ["ANTIMICROBIAL", "PRESERVATIVE"],
    "cosmetic_restriction": "V/29",
    "slug": "phenoxyethanol",
    "regulatory": { "annexes": [ /* Annex V entry, ref 29 */ ] }
  }],
  "total": 1
}

Two fields matter more than the rest:

  • cosmetic_restriction — the Annex reference in annex/ref notation. V/29 means Annex V (permitted preservatives), reference 29. An ingredient can carry more than one: salicylic acid returns III/98 and V/3, because it is both restricted as an ingredient and permitted as a preservative.
  • slug — your key into the detail endpoint (next section).

Searching by CAS number works with the same parameter: ?q=122-99-6 finds the same row. If you would rather browse than write curl commands, the CosIng ingredient search page runs the same kind of lookup from a UI.

3. The gotcha: regulated_only defaults to true

Try this and you will get an empty result:

curl "https://api.bdapi.app/api/public/cosing/search?q=retinol"
# → { "rows": [], "total": 0 }

Retinol is obviously in the INCI inventory — so what happened? By default, the search covers regulated ingredients: entries whose Annex II–VI record is linked in the relational layer, which is what most compliance lookups need. Some inventory entries, retinol among them, are keyed under a separate substance record. Opt out of the default filter and it appears:

curl "https://api.bdapi.app/api/public/cosing/search?q=retinol&regulated_only=false&limit=1"
{
  "rows": [{
    "inci_name": "RETINOL",
    "cas_no": "68-26-8 / 11103-57-4",
    "ec_no": "200-683-7 / 234-328-2",
    "chemical_name": "Retinol; vitamin A",
    "cosmetic_restriction": "III/376",
    "slug": "retinol"
  }],
  "total": 8
}

Rule of thumb: compliance lookups → default; inventory-wide search boxes → regulated_only=false. If retinol's regulatory status is what you are after, the retinol restriction under Regulation 2024/996 has its own write-up.

4. Full ingredient detail by slug

Once you have a slug from search, the detail endpoint returns everything — identifiers, functions, Annex restrictions and cross-references:

curl "https://api.bdapi.app/api/public/cosing/ingredient/phenoxyethanol"

The response nests the complete regulatory picture: each Annex entry with its reference number, maximum concentration, conditions and warnings, plus cross-references to related substances. A 404 comes in two flavours worth distinguishing in your error handling: not_regulated (the ingredient exists in the INCI inventory but has no Annex II–VI entry) and ingredient_not_found (the slug matches nothing).

5. Browse by Annex

Each of the five Annexes is enumerable, paginated, using codes ii through vi:

curl "https://api.bdapi.app/api/public/cosing/annex/iv/ingredients?limit=1"
{
  "annex_code": "iv",
  "annex": { "id": 4, "code": "IV", "title": "Colorantes permitidos" },
  "rows": [{
    "chemical_name": "(29H,31H-Phthalocyaninato(2-)-N29,N30,N31,N32)copper",
    "inci_name": "CI 74160",
    "ref_number": "105",
    "substance_slug": "29h-31h-phthalocyaninato-2-n29-n30-n31-n32-copper-s2237"
  }],
  "total": 154,
  "page": 1,
  "page_size": 1
}

Pagination accepts either page + page_size or raw limit + offset — use whichever matches your client. If Annex semantics are new to you, how to read the CosIng Annexes covers what each one governs.

6. Compliance-focused lists

Three endpoints answer questions that otherwise require joining and filtering yourself:

# Substances with a CMR classification (carcinogenic, mutagenic, reprotoxic)
curl "https://api.bdapi.app/api/public/cosing/cmr?limit=1"

# Substances added to Annex II in the last N months (1-24, default 6)
curl "https://api.bdapi.app/api/public/cosing/recently-prohibited?months=12"

# The 26 mandatory fragrance allergens from Annex III
curl "https://api.bdapi.app/api/public/cosing/allergens"

recently-prohibited is the one to wire into a dashboard: it returns each substance with its Annex II update date and the cutoff used, so "what was banned since our last portfolio review?" becomes one HTTP call. For background on CMR mechanics, see CMR substances in cosmetics.

7. Live counts and dataset freshness

The stats endpoint returns per-Annex counts and inventory totals — useful for dashboards and for sanity-checking your own replica:

curl "https://api.bdapi.app/api/public/cosing/stats"
{
  "annexes": [
    { "code": "II",  "substance_count": 1758, "cas_count": 2073 },
    { "code": "III", "substance_count": 381,  "cas_count": 481 },
    { "code": "IV",  "substance_count": 154,  "cas_count": 199 },
    { "code": "V",   "substance_count": 58,   "cas_count": 134 },
    { "code": "VI",  "substance_count": 34,   "cas_count": 39 }
  ],
  "regulated_total": 2385,
  "inci_inventory_total": 33621
}

There is also a regulatory watch feed — the latest events detected across DG SANTE, SCCS, EUR-Lex and Safety Gate, each with its official source URL:

curl "https://api.bdapi.app/api/public/watch/latest?limit=5"

8. Rate limits: design around them, not into them

Every public route is rate-limited per IP, per minute:

EndpointLimit
/cosing/search60 req/min
/cosing/stats30 req/min
/cosing/ingredient/:slug120 req/min
/cosing/ingredients/slugs10 req/min
/cosing/annex/:code/ingredients60 req/min
/cosing/cmr, /cosing/recently-prohibited60 req/min
/watch/latest60 req/min

Three practical consequences:

  1. Respect the cache headers. Every response carries Cache-Control tuned to how often the underlying data changes — ingredient detail is cacheable for an hour in the browser and a day at the CDN. A polite client that caches will rarely see a limit.
  2. Handle 429 properly. The error body includes retryAfter in seconds. Back off for that long; do not hammer.
  3. Batch at build time. The slugs endpoints (10 req/min) exist for static-site generators: one call enumerates everything, then detail fetches fan out. That is exactly how this site's own ingredient pages are built.

9. From prototype to production

Everything above is read-only lookup over HTTP — perfect for prototypes, internal tools, dashboards and content. Production compliance software has a different constraint: ingredient validation should not depend on a network call to anyone, including us.

That is what the licensed tier of the CosIng database API is for: signed incremental SQL patches that replicate the full dataset into your own PostgreSQL, verified with SHA-256 before apply, so your product validates offline. If you are evaluating that jump, how to choose a CosIng data source gives you the criteria — and CosIng API vs manual XLS downloads compares it against the do-it-yourself route.

Explore the CosIng database API →

Full endpoint reference with documented rate limits, verified examples, and the licensed sync path when your prototype is ready for production.

This article was written with the assistance of artificial intelligence and was reviewed and verified by a person against the official sources (EUR-Lex, CosIng, European Commission). More on our use of AI

← Back to the blog