Migration guide
Proxycurl alternative for LinkedIn profile APIs
Move a LinkedIn profile lookup or people-search workflow to pineapi with an asynchronous adapter, explicit billing and a schema you can inspect.
Proxycurl’s founder confirms that the original service is shut down and describes NinjaPear as a different successor product. Read the founder’s status update. This guide covers pineapi as an alternative, not an affiliation or a compatibility guarantee.
Reviewed 2026-10-19
Map the workflow before mapping the fields
| Existing workflow | pineapi approach | Change required |
|---|---|---|
| A list of LinkedIn profile URLs | POST /v1/profile-lookups with linkedin_urls | 1–2,000 URLs; normalize and deduplicate before reconciliation |
| People discovery using filters | POST /v1/profile-searches | Rebuild the request from the current catalogs; do not copy old filter IDs |
| One call returning a profile object | Create → poll run → read profiles | HTTP 202 contains run_id, not the finished profile |
| Matching returned rows to your input | requested_url on each returned profile | Do not join on linkedin_url: the current slug may differ |
| Missing or renamed profiles | unresolved on the run | not_found or unavailable; these URLs are not billed |
| Company, email or phone enrichment | No equivalent pineapi endpoint | Keep this outside the migration scope |
A replacement for the profile workflow
pineapi is an option for replacing a profile-URL or filter-search integration. It is not a drop-in replacement for the entire Proxycurl product. Endpoint paths, request shapes, authentication credentials and response handling must be adapted. If your application depends on company enrichment, contact details or synchronous responses, identify those dependencies before changing providers.
Build an adapter around runs
Keep your application’s existing input and output interfaces, then implement a pineapi adapter behind them. Persist the request body, Idempotency-Key and returned run_id. Poll every 5 seconds for the first minute and every 20 seconds afterwards until succeeded, partial, failed or cancelled. Read /v1/runs/{run_id}/profiles and pass next_cursor back as cursor until has_more is false. Keep run_id when your client times out so it can resume without starting a second paid run.
Map fields from your stored responses
Use your own saved response fixtures as the old contract and the generated pineapi OpenAPI document as the new one. Match identity fields deliberately; inspect experiences, current_title, current_company_name and the tenure fields rather than relying on similarly named fields having identical meaning. Preserve null values. Check experience_truncated and skills_truncated before treating a missing source section as an empty career or skill set.
Reconcile every requested URL
Use requested_url to connect each returned record to your normalized input list. Inspect unresolved separately and report its reason to the caller. A renamed LinkedIn slug can change linkedin_url, so it is not a safe join key for your original request. A duplicate inside one run is discarded; the same profile delivered again in a different run is billed again.
Budget the migration sample
Use a small, deliberately selected batch for the first paid run. A lookup delivering 100 profiles costs $1.20; unresolved URLs add no charge. Search costs at least $0.12 per completed run. Add prepaid balance from $5; there is no sandbox, free trial or transferable legacy credit balance. Compare your adapter’s output before replacing production traffic.
Inspect the contract before paying for a run
Generated API reference · Profile fields · Billing examples · Give the instructions to your assistant
Get API access