Drop-in compatibility proxies for enrichment APIs. Migrate without rewriting your integration.
V1 ships one route: People Data Labs → Nyne.
If you're already on PDL, you change one base URL (and add one header) and your existing code routes through Nyne instead. The request body stays the same. The response shape stays the same. Your parsing code, your downstream pipelines, your tests — all unchanged.
Built and maintained by Manicule.
# Before — your existing PDL code:
curl -X POST https://api.peopledatalabs.com/v5/person/enrich \
-H "X-Api-Key: $PDL_KEY" \
-d '{"email": "person@example.com"}'
# After — same code, different URL, swap creds:
curl -X POST https://compat.manicule.dev/pdl/v5/person/enrich \
-H "X-Api-Key: $NYNE_KEY" \
-H "X-Api-Secret: $NYNE_SECRET" \
-d '{"email": "person@example.com"}'You get back PDL-shaped JSON:
{
"status": 200,
"likelihood": 10,
"data": {
"full_name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"emails": [{ "address": "jane@…", "type": "personal", ... }],
"phone_numbers": ["+1…"],
"job_title": "Engineer",
"job_company_name": "ACME",
"linkedin_url": "https://linkedin.com/in/janedoe",
"experience": [ … ],
"education": [ … ],
"location_name": "San Francisco, CA"
}
}The PDL Python SDK (peopledatalabs) parses this directly.
| PDL | Nyne | |
|---|---|---|
| Auth | one header (X-Api-Key) |
two headers (X-API-Key + X-API-Secret) |
| Mode | synchronous | synchronous (default) |
| Response wrapper | {status, likelihood, data} |
{success, data: {result}} |
| Naming | snake_case |
camelCase |
| Emails | array of {address, type, ...} |
array of strings (altemails) |
| Phones | phone_numbers[] + phones[] |
fullphone[].fullphone |
| Work history | experience[] (nested company + title) |
organizations[] (flat) |
| Education | education[] (nested school) |
schools_info[] (flat) |
| Location | 10+ flat location_* fields |
one free-form string |
| Social | flat linkedin_url, twitter_url, etc. |
social_profiles.{platform}.url |
The full mapping spec lives at mappings/pdl_v5_person_enrich.yaml.
Some PDL fields have no equivalent in Nyne's response. The proxy returns them as null rather than omitting them, so existing PDL parsing code doesn't break with KeyError.
Fields that come through (Nyne returns them):
full_name,first_name,last_name,headline,sex- All social profile URLs + usernames (LinkedIn, Twitter, GitHub, Facebook)
linkedin_connectionspersonal_emails,recommended_personal_email,emails[]mobile_phone,phone_numbers[],phones[]job_title,job_company_name,job_start_date,job_summary(derived from current org)experience[],job_history[],education[]location_name,location_locality,location_region,location_country(parsed from the free-form Nyne string — best-effort)
Fields that come back null because Nyne doesn't expose them:
birth_date,birth_year,middle_name,middle_initialwork_email(Nyne doesn't tag email types)industry,inferred_salary,inferred_years_experience- All
job_company_*enrichment fields (size, founded, industry, location, revenue, employee count, …) location_metro,location_continent,location_street_address,location_postal_code,location_geointerests[],skills[],certifications[],languages[]possible_emails,possible_phones,possible_profiles,possible_street_addressesnum_sources,num_records,first_seen,dataset_version
If your code depends on any of those, this proxy isn't a drop-in for your use case. The mapping file lists everything; check it before migrating.
git clone https://github.com/maniculehq/api-compat
cd api-compat
python3.12 -m venv .venv && source .venv/bin/activate
pip install fastapi "uvicorn[standard]" httpx pyyaml
uvicorn proxy.main:app --reloadTest against your Nyne credentials:
curl -X POST http://localhost:8000/pdl/v5/person/enrich \
-H "X-Api-Key: $NYNE_KEY" \
-H "X-Api-Secret: $NYNE_SECRET" \
-d '{"email": "you@yourdomain.com"}'pip install pytest pytest-asyncio respx
pytest -v31 tests cover the request transform, response transform, FastAPI endpoint, and error handling.
The repo ships with a Dockerfile and fly.toml:
fly launch --no-deploy # creates the app, skip if it already exists
fly deployOr any container host — Cloud Run, Render, Railway, Heroku — works fine. The image is ~120MB and the service uses ~50MB resident RAM idle.
V1 covers /v5/person/enrich only. PDL has more endpoints:
/v5/person/search— Elasticsearch / SQL queries. Would need PDL query translation to Nyne's filter format. Not on the V1 roadmap./v5/person/identify— multi-match. Possible V2./v5/company/enrich— straightforward to add, blocked on the same field-mapping work. Open an issue if you need it.- Bulk endpoints — not planned. Loop in client code.
This isn't a complete PDL feature parity. It's a migration tool: get your enrichment pipeline pointed at Nyne with the smallest possible code change, then evolve toward Nyne's native API on your own schedule.
Manicule builds docs and developer marketing for AI infrastructure companies. Migration friction kills good products. When Nyne pitched themselves as a more accurate, cheaper PDL alternative, the natural question from every prospective customer was "how much engineering work to switch?" This proxy is the answer: about 60 seconds.
If you're a vendor building an API in a competitive category and want a drop-in compatibility layer that makes "we replaced their incumbent" the literal one-line change — we do this.
MIT