EWG APIewg.org ↗
Search EWG's Skin Deep database and retrieve hazard scores, health concerns, synonyms, and regulatory data for cosmetic ingredients via 2 REST endpoints.
What is the EWG API?
The EWG Skin Deep API gives developers access to safety data for cosmetic ingredients across 2 endpoints. Use search_ingredients to find ingredients by name and retrieve hazard scores and data availability ratings, then call get_ingredient to pull full detail: a 1–10 hazard score, common health concern categories with severity levels, alternative chemical names, regulatory data sources, and EWG VERIFIED criteria — all keyed to EWG's Skin Deep database.
curl -X GET 'https://api.parse.bot/scraper/47ae178e-a2f8-4985-9dac-c800f6eeabae/search_ingredients?page=1&search=retinol' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace ewg-org-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: EWG Skin Deep SDK — bounded, re-runnable; every call capped."""
from parse_apis.ewg_org_api import EWGSkinDeep, IngredientNotFound
client = EWGSkinDeep()
# Search for ingredients matching "retinol", cap at 3 results
for ingredient in client.ingredient_summaries.search(query="retinol", limit=3):
print(ingredient.name, ingredient.score, ingredient.data_availability)
# Drill down into the first result's full details
item = client.ingredient_summaries.search(query="glycerin", limit=1).first()
if item:
try:
detail = item.details()
print(detail.name, detail.score, detail.data_availability)
print(detail.description)
for concern in detail.common_concerns:
print(concern.name, concern.level)
except IngredientNotFound as e:
print(f"Not found: {e.ingredient_id}")
print("exercised: ingredient_summaries.search, ingredient_summaries.details")
Search the EWG Skin Deep database for cosmetic ingredients by name. Returns a paginated list of matching ingredients with their hazard scores and data availability ratings. Results are auto-iterated; use limit to cap total items fetched.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination (1-based). |
| search | string | Search query for ingredient name. Use '*' to list all ingredients. |
{
"type": "object",
"fields": {
"page": "current page number",
"total": "total number of matching ingredients",
"ingredients": "array of ingredient summaries with id, name, slug, score, score_min, data_availability, and url",
"total_pages": "total number of pages available"
},
"sample": {
"data": {
"page": 1,
"total": 74,
"ingredients": [
{
"id": "705545",
"url": "https://www.ewg.org/skindeep/ingredients/705545-RETINYL_PALMITATE_VITAMIN_A_PALMITATE/",
"name": "RETINYL PALMITATE (VITAMIN A PALMITATE)",
"slug": "RETINYL_PALMITATE_VITAMIN_A_PALMITATE",
"score": 9,
"score_min": 1,
"data_availability": "Fair"
},
{
"id": "706889",
"url": "https://www.ewg.org/skindeep/ingredients/706889-RETINOL_VITAMIN_A/",
"name": "RETINOL (VITAMIN A)",
"slug": "RETINOL_VITAMIN_A",
"score": 9,
"score_min": 1,
"data_availability": "Good"
}
],
"total_pages": 7
},
"status": "success"
}
}About the EWG API
Searching Ingredients
The search_ingredients endpoint accepts a search string and an optional page integer. Pass a partial or full ingredient name to get a paginated list of matches. Each result includes a numeric id, name, slug, score, score_min, data_availability, and a direct url to the Skin Deep listing. Passing '*' as the search term iterates across all available ingredients. The response also surfaces total and total_pages so you can walk the full result set programmatically.
Ingredient Detail
get_ingredient takes an ingredient_id (e.g. '702620' for Glycerin) and an ingredient_slug (e.g. 'GLYCERIN') — both obtainable from search_ingredients results. The response includes the ingredient's score (1–10, higher indicating greater hazard), score_min for context-dependent lower-bound scores, score_notes explaining variability, and a description field. Health concerns are broken out in common_concerns as an array of categories each tagged with a severity level: low, moderate, or high.
Regulatory and Reference Data
The get_ingredient response includes a data_sources array listing the regulatory and scientific sources referenced in the safety assessment, along with synonyms — an array of alternative chemical names that can be useful for ingredient cross-referencing and label parsing. The data_availability field classifies how much safety data exists for the ingredient across five tiers: Robust, Good, Fair, Limited, and None. An other_concerns text summary captures concerns that don't fit the structured categories.
Identifiers and Pagination
Ingredient IDs are numeric strings internal to Skin Deep. Slugs are uppercase versions of the ingredient name (e.g. 'SODIUM-LAURYL-SULFATE'). Both are returned by search_ingredients, making it straightforward to build a lookup pipeline: search first, then fetch detail by ID and slug. Pagination in search_ingredients is 1-based via the page parameter.
The EWG API is a managed, monitored endpoint for ewg.org — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when ewg.org changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official ewg.org API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Screen cosmetic product formulations against EWG hazard scores before launch
- Build a consumer-facing ingredient scanner that flags high-severity health concerns
- Enrich an internal ingredient database with synonyms for label normalization
- Generate regulatory compliance reports citing EWG data sources for each ingredient
- Filter product catalogs by data_availability tier to surface under-researched ingredients
- Cross-reference ingredient IDs to track score changes over time
- Power an autocomplete search for ingredient names using the paginated search_ingredients endpoint
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does EWG offer an official developer API for Skin Deep?+
What does the score field in get_ingredient represent, and how does score_min differ?+
score field is EWG's hazard rating on a 1–10 scale, where higher numbers indicate greater concern. score_min represents the lower bound of the score range, which can vary depending on the ingredient's usage concentration or formulation context. The score_notes array explains the specific factors driving any variability between these two values.Does the API return product-level data, such as specific cosmetics that contain an ingredient?+
Are there any limitations on which ingredients are covered?+
search_ingredients results. Data availability for individual ingredients varies widely — the data_availability field reflects this, ranging from 'Robust' to 'None', so some entries will have minimal detail in get_ingredient responses.Can I retrieve EWG VERIFIED product certifications through this API?+
get_ingredient response includes EWG VERIFIED criteria as part of the ingredient detail, but full product-level EWG VERIFIED certification listings are not a separate endpoint. You can fork this API on Parse and revise it to add an endpoint covering the EWG VERIFIED product directory if that scope is needed.