CosIng API · Public REST endpoints · Integrity-verified SQL patches · Webhooks
CosIng API: the EU cosmetic ingredient database, delivered as a live API
The EU CosIng database (INCI names, CAS numbers, EINECS, Annex II–VI restrictions) as a REST API: free public endpoints to start today, and integrity-verified incremental SQL patches for production. For teams who need CosIng data in their product without scraping ec.europa.eu or maintaining a diff engine.
Free API key
Query the CosIng database in one call
The public read endpoints use a free API key that you get with your email. Send it in the X-API-Key header. Copy, paste, and you have live CosIng data.
# Search the CosIng database by INCI name, CAS or EC number
curl "https://api.bdapi.app/api/public/cosing/search?q=phenoxyethanol&limit=1" \
-H "X-API-Key: $BDAPI_API_KEY"
{
"rows": [{
"result_type": "ingredient",
"inci_name": "PHENOXYETHANOL",
"cas_no": "122-99-6",
"ec_no": "204-589-7",
"chemical_name": "2-Phenoxyethanol",
"function_names": ["ANTIMICROBIAL", "PRESERVATIVE"],
"slug": "phenoxyethanol",
"has_fiche": true,
"matched_via": "inci",
"fiche_url": "https://bdapi.app/en/cosing-database/ingredient/phenoxyethanol/"
}],
"total": 1
}
# Live substance counts per Annex (II-VI)
curl "https://api.bdapi.app/api/public/cosing/stats" \
-H "X-API-Key: $BDAPI_API_KEY"Response trimmed for readability. Search covers regulated ingredients by default — add regulated_only=false for the full INCI inventory. The free daily quota is 500 requests per email. Since 12 October 2026, calls without a key return 401 api_key_required. The search on bdapi.app stays free and needs no key.
The free key covers ingredient identity. The regulatory data (Annex, reference number, maximum concentrations, conditions and warnings) is on the paid plans. See plans →
Get a free API key
Enter your email and we will send you a key. It is only delivered by email. The free daily quota is 500 requests per email.
Reference
Public read endpoints, with documented rate limits
Three read-only endpoints on the free key: identity search, Annex counts and the regulatory watch feed. Limits are per IP per minute — published here because production software deserves to know its budget.
GET /api/public/cosing/searchIngredient identity search by INCI name, CAS or EC number. Each row returns INCI name, CAS, EC number, chemical name, functions and fiche_url, the link to the public fiche on bdapi.app. Defaults to regulated ingredients (Annexes II–VI); pass regulated_only=false to search the full INCI inventory.
60 req/minGET /api/public/cosing/statsLive counts per Annex (II–VI): substances, CAS numbers and inventory totals — the same numbers shown across this site.
30 req/minGET /api/public/watch/latestLatest regulatory events across DG SANTE, SCCS, EUR-Lex and Safety Gate, with official source URLs. No key needed.
60 req/minPaid plans: the other /api/public/cosing/* routes return regulatory data and answer 403 paid_plan_required to the free key: ingredient/:slug, ingredients/slugs, annex/:code/ingredients, cmr, allergens, microplastics, recently-prohibited, substance/:slug, substances/slugs, functions/slugs, function/:slug/ingredients, ingredient/:slug/publications, publication/ingredients.
Every response carries CDN-friendly Cache-Control headers. Error codes: 401 api_key_required or invalid_api_key (missing or invalid key), 403 paid_plan_required (paid-plan route; not counted against the quota), 429 daily_quota_exceeded (daily quota used up until the next UTC day) and the rate-limit 429, which includes retryAfter in seconds. Full OpenAPI 3.1 specification on request →
Use cases
What teams build with it
Cosmetic formulation & PLM software
Validate INCI lists against Annex II–VI restrictions inside your own product. Prototype the ingredient lookup against the free endpoints, then move to a paid plan for the regulatory data and the licensed sync: an offline PostgreSQL replica with no per-request dependency.
Certification bodies & regulatory consultants
Check CMR classifications, recent Annex II additions and restriction conditions programmatically before signing off a dossier — with every answer traceable to the official EC source.
Content, research & internal tooling
Power ingredient glossaries, dashboards and static sites with live Annex counts and ingredient identity lookups. CDN-friendly cache headers make it cheap to consume at build time.
Production
The licensed sync API: four calls
Once the prototype works, production should not depend on per-request calls. The licensed API replicates the full CosIng dataset into your own PostgreSQL with integrity-verified incremental SQL patches.
# 1. Check whether a newer CosIng version exists
curl -X POST https://api.bdapi.app/api/versions/check \
-H "Authorization: Bearer $LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"current_version": "1.0.0"}'
# 2. Download the incremental SQL patch
curl https://api.bdapi.app/api/versions/1.1.0/patch \
-H "Authorization: Bearer $LICENSE_KEY" \
-o patch.sql
# 3. Verify SHA-256 integrity before applying
curl -sI https://api.bdapi.app/api/versions/1.1.0/patch \
-H "Authorization: Bearer $LICENSE_KEY" \
| grep -i x-hash-sha256
# 4. Apply in a single PostgreSQL transaction, then confirm
psql -1 -f patch.sql && curl -X POST .../api/versions/confirm \
-H "Authorization: Bearer $LICENSE_KEY" \
-d '{"version":"1.1.0","success":true,"error":null}'If the hash does not match, the apply never happens. Automatic rollback if the transaction fails. No surprises.
Evaluation
CosIng API vs the alternatives
Three ways to access CosIng data. Only one is built for production.
| BD-API CosIng API | Downloading the official .xls | Consumer ingredient-lookup APIs | |
|---|---|---|---|
| Freshness | Auto-synced on every EC XLS change (CRON-driven, weekly by default, up to daily) | Manual re-download required — you notice changes only when you check | Varies; often days or weeks behind the official source |
| Integrity | Patches verified with SHA-256 + HMAC-SHA256 webhook notifications | None — no hash, no signature, no way to detect tampering | None at the data layer |
| Format | Structured PostgreSQL with FK between Annexes, substances and CAS numbers | Raw spreadsheet cells — columns shift between releases | Per-request JSON — one lookup at a time, no relational structure |
| Delivery | Incremental SHA-256 verified patches applied inside a single SQL transaction | Full-file download every time, even if one row changed | One ingredient per API call — no batch, no sync |
| Audit trail | Source, timestamp and verifiable proof per change — what auditors require | None — you cannot prove when you received the data or what changed | None at the data layer |
| Built for | Cosmetic software vendors who need CosIng live in their product | One-off human checks by regulatory affairs teams | B2C apps and ingredient safety scores for end users |
BD-API CosIng API
Auto-synced on every EC XLS change (CRON-driven, weekly by default, up to daily)
Official .xls download
Manual re-download required — you notice changes only when you check
Consumer lookup APIs
Varies; often days or weeks behind the official source
BD-API CosIng API
Patches verified with SHA-256 + HMAC-SHA256 webhook notifications
Official .xls download
None — no hash, no signature, no way to detect tampering
Consumer lookup APIs
None at the data layer
BD-API CosIng API
Structured PostgreSQL with FK between Annexes, substances and CAS numbers
Official .xls download
Raw spreadsheet cells — columns shift between releases
Consumer lookup APIs
Per-request JSON — one lookup at a time, no relational structure
BD-API CosIng API
Incremental SHA-256 verified patches applied inside a single SQL transaction
Official .xls download
Full-file download every time, even if one row changed
Consumer lookup APIs
One ingredient per API call — no batch, no sync
BD-API CosIng API
Source, timestamp and verifiable proof per change — what auditors require
Official .xls download
None — you cannot prove when you received the data or what changed
Consumer lookup APIs
None at the data layer
BD-API CosIng API
Cosmetic software vendors who need CosIng live in their product
Official .xls download
One-off human checks by regulatory affairs teams
Consumer lookup APIs
B2C apps and ingredient safety scores for end users
CosIng API
Questions about the data and delivery
Is there a free public CosIng API I can try?+
Yes. Ingredient identity search (/api/public/cosing/search: INCI name, CAS, EC number, chemical name, functions and a link to the public fiche) and the Annex counts (/api/public/cosing/stats) are free with an API key that you get with your email. Send it in the X-API-Key header. The regulatory data (Annex entries, maximum concentrations, conditions, warnings, the Annex and CMR listings and the full ingredient detail) is on the paid plans; with the free key those routes return 403 paid_plan_required. The free daily quota is 500 requests per email, on top of the per-IP limits (30 to 60 requests per minute depending on the route). Since 12 October 2026, calls without a key return 401 api_key_required. The search on bdapi.app stays free and needs no key, and so does the regulatory watch feed (/api/public/watch). Responses are served with CDN-friendly cache headers. The licensed API adds what production needs: SHA-256-verified incremental SQL patches into your own PostgreSQL, webhooks and email alerts. Hands-on guide with verified examples →
Why does the public search return no results for some well-known ingredients?+
By default /cosing/search only returns ingredients whose Annex II–VI entry is linked in the relational layer — that is what most compliance lookups need. Some inventory entries, retinol among them, are keyed under a separate substance record, so they do not appear in the default result set. Pass regulated_only=false to search the full INCI inventory of roughly 33,000 entries.
What exactly does the CosIng API return?+
Each sync returns an integrity-verified (SHA-256) incremental SQL patch: only the rows that changed since your current version. The patch contains UPSERT statements for substances, CAS numbers, EINECS entries and Annex restrictions (Annexes II–VI), plus a SHA-256 hash in the response headers. You apply it in a single PostgreSQL transaction and confirm with a follow-up call. Nothing is overwritten blindly — every column that changed has a before/after trace.
How is it kept in sync with the official CosIng?+
BD-API polls the official European Commission XLS on a configurable CRON schedule — weekly by default, configurable up to daily. When a new XLS is published, the diff engine runs within minutes, produces a versioned SQL patch, and queues it for delivery. Your installation polls /api/versions/check at whatever cadence you prefer — you only download when there is actually a newer version.
Is it a per-request lookup or a full dataset?+
Neither. It is incremental: on first sync you receive a full baseline, on every subsequent sync you receive only what changed. You own a live PostgreSQL replica of the full CosIng dataset — all ~2,385 entries across Annexes II–VI — with foreign keys between Annexes, substances and CAS numbers. No per-query fees, no round-trips at request time, no rate-limit surprises in production. Browse the CosIng database →
How do I verify the data has not been tampered with?+
Every patch ships with a SHA-256 hash in the x-hash-sha256 response header. Your client downloads the patch, computes the hash locally, and compares before calling psql. If the hashes do not match, the apply never happens. Webhook notifications from the watch pipeline carry an HMAC-SHA256 signature you verify with your shared secret before processing.
Can I self-host the data?+
Yes — that is the whole point. Patches are pure SQL in your own PostgreSQL. BD-API has no read path into your database, no SDK that must stay running, and no proprietary binary format. If you ever stop using BD-API, the data you have already applied stays in your database, intact and queryable forever. Seven criteria to evaluate a CosIng data source →