Last year I tried to look up whether a specific chemical was regulated in South Korea. Thirty minutes later I was still clicking through a Korean-only government portal, guessing at form fields, getting cryptic error codes.
That's when I realized: there's no English-language API for Korean chemical regulations. Not from the government, not from anyone.
So I built one.
What this actually does
Korea has a law called K-REACH (similar to EU REACH) that classifies chemical substances into categories like toxic, restricted, prohibited, CMR, etc. The official data sits on data.go.kr — Korea's public data portal — but it's painful to use. Six mandatory parameters per request. Responses in inconsistent formats. GHS hazard data lives in a completely separate API. Everything is in Korean.
My API wraps all of that into a single CAS number lookup:
import requests
headers = {
"X-RapidAPI-Key": "YOUR_API_KEY",
"X-RapidAPI-Host": "k-reach-chemical-substance-api.p.rapidapi.com"
}
response = requests.get(
"https://k-reach-chemical-substance-api.p.rapidapi.com/v1/substance/cas/71-43-2",
headers=headers
)
data = response.json()
print(data['substance']['flags']['is_toxic']) # True
print(data['ghs']['signal_word']) # 위험 (Danger)
You get back 9 boolean regulatory flags, GHS hazard codes, pictograms, regulation details — all as structured JSON. No Korean parsing required.
The data
46,000+ substances from the Korea Environment Corporation (KECO), collected through officially approved data.go.kr API endpoints. No scraping.
The part I'm most proud of is the integrity pipeline. Every day at a fixed time, a monitoring script:
- Checks total counts across 36 alphanumeric search characters (both chemical and GHS APIs)
- Samples 500 substances and compares them against the source
- Detects changes and auto-updates the database
- Runs integrity checks (FK validation, flag consistency, sandbox verification) before swapping in the new DB
- Rolls back automatically if anything fails
The whole update happens with zero downtime — Gunicorn graceful reload, so the API never drops a request mid-update.
Every response includes X-Data-Version and X-Data-Last-Checked headers so you know exactly how fresh the data is.
Why not just use the government API directly?
You could. But here's what you're signing up for:
- All 6 parameters are mandatory. Miss one and you get an error code with no useful message.
- Regulatory classifications are nested in inconsistent formats. You'll spend hours figuring out which field means "toxic."
- GHS is a separate API with different parameter names. You need to cross-reference two data sources yourself.
- Substring matching returns massive overlapping result sets. Searching "a" returns 42,000 results.
- 10,000 calls/day quota with no built-in deduplication.
I spent weeks dealing with all of this so you don't have to. I also hit every edge case you can imagine — FTS5 reserved words breaking search, CAS numbers with no associated substance, GHS APIs returning empty hazard lists for substances that definitely have hazard data. Each one became a bug fix.
The response structure
{
"substance": {
"cas_no": "71-43-2",
"name_eng": "Benzene",
"name_kor": "벤젠",
"formula": "C6H6",
"flags": {
"is_toxic": true,
"is_restricted": false,
"is_prohibited": false,
"is_priority": true,
"is_cmr": false,
"is_accident_prep": true,
"is_persistent": false,
"is_registration_req": true,
"is_rotterdam": false
}
},
"regulations": [...],
"ghs": {
"signal_word": "위험",
"pictograms": ["GHS02", "GHS07", "GHS08"],
"hazards": [...]
}
}
The flags object is what makes this useful. Instead of parsing Korean regulation text, you get a boolean answer: is it toxic? Is it banned? Nine categories, one API call.
Search and list endpoints return slim results (name + flags only). Detail endpoints return everything. I call it "thin list, fat detail" — keeps list responses fast while full data is always one CAS lookup away.
# Search by keyword
GET /v1/substance/search?q=chromium
# List all restricted substances
GET /v1/regulations/list?type=restricted
# Get GHS data
GET /v1/ghs/71-43-2
# Search by GHS hazard code
GET /v1/ghs/hazard/H350
Who would use this
Mostly B2B:
- EHS SaaS platforms that need Korean regulatory data alongside EU REACH, US TSCA, etc.
- Customs platforms screening Korea-bound chemical shipments
- Regulatory consultants running K-REACH compliance audits
- Chemical manufacturers checking substances before entering the Korean market
Pricing
| Plan | Price | Requests/mo | Unique Substances/mo |
|---|---|---|---|
| BASIC | Free | 200 | 200 |
| PRO | $99/mo | 3,000 | 1,500 |
| ULTRA | $299/mo | 25,000 | 5,000 |
| MEGA | $899/mo | 100,000 | 10,000 |
Free tier includes 3 sandbox substances (Benzene, Ethanol, Formaldehyde) with full data for integration testing. No credit card needed.
The "unique substances" limit is intentional — it's how I protect the dataset while keeping the API useful for legitimate compliance workflows.
Links
- RapidAPI — subscribe and test
- Postman docs — browse all endpoints
- GitHub — code examples in Python, JavaScript, cURL
- Decoded Korea — blog covering Korean chemical and cosmetic regulations
Quick test:
curl "https://k-reach-chemical-substance-api.p.rapidapi.com/v1/substance/cas/71-43-2" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: k-reach-chemical-substance-api.p.rapidapi.com"
What's next
Working on Python/JS SDK packages, and eventually pairing this with my K-Beauty Cosmetic Ingredients API for full Korean compliance coverage across chemicals and cosmetics.
If you work with chemical regulations in Asian markets, I'm curious what your workflow looks like today.
This is my second API on RapidAPI. The first — K-Beauty Cosmetic Ingredients API — covers Korean cosmetic ingredient regulations across 10 countries.
Top comments (0)