Install the Up2Data skill

Teach Claude Code to integrate the Up2Data API. Installs once, then loads automatically whenever you ask it about Up2Data.

  1. Run this in your terminal
    bash
    mkdir -p ~/.claude/skills/up2data-api && curl -fsSL https://up2data.ai/docs/v1/skill.md -o ~/.claude/skills/up2data-api/SKILL.md
  2. Restart Claude CodeSo it picks up the new skill.
  3. Try it"Enrich these LinkedIn profiles with Up2Data and send results to my webhook"

Requires Claude Code. macOS, Linux, or WSL.

Prefer to read it first? View the skill file

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:

bash
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:

http
X-API-Key: YOUR_API_KEY

Legacy 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.
Warning

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 webhookTags configured per team. /v1 takes one webhook_url per batch job - no team-wide tag matching.
  • Callback shape. Legacy's callback item carries a type field (Profile, Company, Activity, ActivityPosts, and so on) per queue kind. /v1's batch.completed payload is a single job summary; per-item results live in GET /v1/batch/{job_id}.
  • Billing. A not-found target is billed in both versions. In /v1 that covers synchronous enrich, profiles/activity and 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.