Three engines.
Independently callable.
Five-minute integration.
UNMAPPED is open skills-intelligence infrastructure for LMICs. You don't need to adopt our UI — mount any of the three engines in your own product. Every response is taxonomy-coded (ESCO / ISCO-08 / O*NET) and cites its data source.
Five-minute integration
One curl per engine. Every endpoint accepts country_context at runtime — no hardcoding, ever.
curl -X POST https://unmapped-614242090378.europe-west1.run.app/engine/skills/extract \
-H "Content-Type: application/json" \
-d '{
"input_text": "I have been fixing phones for 5 years, taught myself Python on YouTube, manage 3 people at the shop.",
"education_level": "secondary",
"country_context": "ghana",
"taxonomy": "esco",
"language": "en"
}'curl -X POST https://unmapped-614242090378.europe-west1.run.app/engine/risk/assess \
-H "Content-Type: application/json" \
-d '{
"profile_id": "00000000-0000-0000-0000-000000000001",
"country_context": "ghana",
"automation_dataset": "frey_osborne",
"include_landscape_projection": true,
"projection_horizon_year": 2035
}'curl -X POST https://unmapped-614242090378.europe-west1.run.app/engine/opportunities/match \
-H "Content-Type: application/json" \
-d '{
"profile_id": "00000000-0000-0000-0000-000000000001",
"assessment_id": "<assessment_id from /engine/risk/assess>",
"country_context": "ghana",
"opportunity_types": ["formal_employment","self_employment","gig","training_pathway"],
"max_results": 8,
"include_econometric_signals": true
}'All three engines are independently useful. You can call Engine 03 with any external profile_id you already store; pass assessment_id only if you want automation-risk weighting in the score.
Who calls what
Pick the smallest surface area you actually need.
| Who | Why | Endpoint |
|---|---|---|
| Employer / HR platform | Verify a candidate’s informal claims against ESCO/ISCO/O*NET in one call. | POST /engine/skills/extract + POST /engine/skills/validate |
| Training provider / NGO | Know what to teach next: get adjacent resilient skills + Wittgenstein 2035 landscape. | POST /engine/risk/assess + GET /engine/risk/landscape |
| Government / policymaker tool | Embed regional skill-desert scores and growth-leader sectors in your own dashboard. | GET /engine/opportunities/dashboard |
| Jobs platform | Power skill-to-opportunity matching with real wage + automation-risk weighting. | POST /engine/opportunities/match |
Add your country in four steps
Zero country logic in Python or TypeScript. The full Kenya rollout below was four files. The frontend reads the registry from /engine/meta/countries on startup.
# 1. Drop a new country config (one file, no code changes) backend/config/myanmar.json # 2. Add a row to each shared dataset (uses ISO-3 country code as key) backend/data/wittgenstein_2035.json # education projections backend/data/ilo_wages.json # wage medians + by-education backend/data/policymaker_regions.json # regional skill desert seed # 3. (Optional) restart backend; load_country_config() is lru_cached uvicorn backend.main:app --reload # 4. The /engine/meta/countries endpoint now lists Myanmar. # The frontend CountryToggle hydrates a new button. # All three engines accept country_context: "myanmar" immediately.
{
"country_name": "Kenya",
"country_code": "KEN",
"currency": "KES",
"currency_symbol": "KSh",
"language": "en",
"greeting": "Karibu",
"automation_lmic_calibration": 0.74,
"education_taxonomy": {
"primary": "Primary school (KCPE)",
"secondary": "Secondary school (KCSE)",
"vocational": "TVET / Polytechnic",
"tertiary": "University degree"
},
"top_growth_sectors": [
{"sector": "digital_services", "yoy_growth_pct": 38},
{"sector": "agritech", "yoy_growth_pct": 24},
{"sector": "mobile_finance", "yoy_growth_pct": 31}
],
"demo_persona": {
"name": "Wanjiku",
"story": "Running a phone-accessories shop in Eastlands, taught myself JavaScript on shared WiFi..."
}
}See backend/config/__init__.py → available_countries() for the loader. Every dataset under backend/data/ is keyed by ISO-3 country code; missing keys fail loudly so you know exactly what to seed.
Embed the policymaker dashboard
One GET, JSON in, render anywhere. Use it in a partner platform, a ministry briefing tool, or a static report.
// Server-side fetch from any partner dashboard
const dashboard = await fetch(
'https://unmapped-614242090378.europe-west1.run.app/engine/opportunities/dashboard?country=ghana®ion=all&view=policymaker'
).then(r => r.json())
// dashboard.regions[] => [{ region_name, lat, lng, skill_desert_score,
// youth_neet_pct, top_missing_skills, top_unfilled_roles, ... }]
// dashboard.national_summary => { youth_unemployment_pct, neet_pct,
// informal_employment_share, fastest_growing_sectors, data_sources }
// Drop into your own map / chart layer. Every value carries a data_source.Or drop the policymaker page directly into an iframe:
<iframe src="https://your-unmapped-host/policymaker" width="100%" height="800" style="border:0; background:#080808" loading="lazy" title="UNMAPPED Policymaker Dashboard" ></iframe>
Discoverability
Self-describing endpoints. Point any client at /engine/meta/countries to find what country contexts this UNMAPPED instance supports.
# Discover which countries this UNMAPPED instance supports curl https://unmapped-614242090378.europe-west1.run.app/engine/meta/countries # Inspect a single country's full config (education taxonomy, opportunity # types, demo persona, currency, greeting) curl https://unmapped-614242090378.europe-west1.run.app/engine/meta/country/ghana
Three engines. Real data. Engine 01 maps skills · Engine 02 assesses risk · Engine 03matches opportunities. Every response cites ESCO v1.1.3, ISCO-08, O*NET 27.3, ILO ILOSTAT 2024, World Bank WDI 2023, Frey & Osborne 2013, and Wittgenstein Centre WC2023_v1 where applicable.