Migrating from legacy
Map every {legacy} open-refresh route to its /v1 equivalent.
#What changes
Legacy exchanges your API key for a short-lived token, then sends that token on every call:
curl -X POST https://api.up2data.ai/api/api-auth/authenticate \
-H "Content-Type: application/json" \
-d '{"apiKey": "your-api-key-here"}'
# -> {"accessToken": "eyJhbGciOiJIUzI1NiIs..."}/v1 drops the exchange entirely. Send your key directly, on every request:
X-API-Key: YOUR_API_KEYLegacy is also queue-first: most Profiles, Companies, and Posts routes enqueue a job and hand back a queueId, and you poll list/status or wait for a callback item to see what came back. /v1 flips that around: profiles/enrich, companies/enrich, and posts/enrich are synchronous request/response calls, and only POST /v1/batch is async, with its own job_id and a batch.completed webhook in place of the callback item.
#Route mapping
| Legacy route | /v1 equivalent | Notes |
|---|---|---|
POST /api-auth/authenticate |
None | /v1 has no token exchange - send X-API-Key directly on every call. |
POST /open-refresh/profile |
POST /v1/profiles/enrich |
Same job, still synchronous, new field and response names. |
POST /open-refresh/profiles-bulk |
POST /v1/batch |
Send items: [{ "type": "profile", "url": "..." }, ...]. batch.completed replaces the callback item; GET /v1/batch/{job_id} replaces list/status. |
POST /open-refresh/activity |
POST /v1/profiles/activity |
Legacy enqueues posts, comments, and reactions together for a batch of profiles. /v1 takes one profile and one kind (posts, comments, reactions, or reposts) per call, synchronously. |
POST /open-refresh/posts |
POST /v1/profiles/activity with kind: "posts" |
Same data, now synchronous, one profile per call. |
POST /open-refresh/comments |
POST /v1/profiles/activity with kind: "comments" |
Same. |
POST /open-refresh/reactions |
POST /v1/profiles/activity with kind: "reactions" |
Same. |
POST /open-refresh/latest-post |
No /v1 equivalent |
/v1 has no single-latest-post route. Call POST /v1/profiles/activity with kind: "posts" and read the first entry. |
POST /open-refresh/company |
POST /v1/companies/enrich |
Same job, still synchronous. |
POST /open-refresh/companies-bulk |
POST /v1/batch |
Send items: [{ "type": "company", "url": "..." }, ...]. |
POST /open-refresh/post-by-url |
POST /v1/posts/enrich |
Synchronous now; for volume, send type: "post" batch items instead. |
POST /open-refresh/search |
POST /v1/search/people/sales-nav and POST /v1/search/companies/sales-nav |
Legacy took a mixed list of Sales Navigator URLs in one call. /v1 splits people and company searches into two endpoints; each is one synchronous call per search that returns up to 100 results at a time (pagination.has_more when more exist). Pull a bigger set - up to 2,500 for people, 1,000 for companies - through a search item inside POST /v1/batch. |
GET /open-refresh/list |
GET /v1/batch/{job_id} or GET /v1/batch/{job_id}/results |
Batch results replace queue result pages; /results takes cursor and limit query params and cursor-pages incrementally, instead of legacy's page-based pagination. |
GET /open-refresh/status |
GET /v1/batch/{job_id} |
Same progress-check role, keyed by job_id instead of queueId. |
latest-post is the one legacy route with nothing to migrate to directly - see the row above for the closest equivalent.
#Other differences worth knowing
- Webhook routing. Legacy routes callbacks by
webhookTagsconfigured per team./v1takes onewebhook_urlper batch job - no team-wide tag matching. - Callback shape. Legacy's callback item carries a
typefield (Profile,Company,Activity,ActivityPosts, and so on) per queue kind./v1'sbatch.completedpayload is a single job summary; per-item results live inGET /v1/batch/{job_id}. - Billing. A not-found target is billed in both versions. In /v1 that covers synchronous enrich,
profiles/activityand every batch item, the same way legacy bulk endpoints charge each item at enqueue. The exact rates differ between versions - check each version's own Credits guide rather than assuming they match.