Skip to main content
This guide walks you through every change needed to migrate your existing V1 integration to V2. The V2 API is fully backward-compatible in terms of data — the same data is returned, just in a standardized wrapper.
V1 will be deprecated. We recommend migrating to V2 as soon as possible. V1 endpoints will continue to work during the transition period, but all new features are V2-only.
A Claude Code skill is available in the webapp to automatically migrate your codebase from V1 to V2. Install it and run the migration directly from your terminal.

What Changed (TL;DR)

No more login_token

V1 required a login_token and country in every request. V2 replaces this with a single account_id.

One endpoint per category

V1 had a different URL for each action (e.g. /v1/profile/me, /v1/profile/info). V2 uses one URL per category with an action field in the body.

Standardized responses

V1 responses varied between endpoints. V2 always returns success, data/error, and metadata — no more guessing the format.

Proper HTTP status codes

V1 returned 200 for most errors. V2 uses correct HTTP status codes (400, 402, 403, 404, 429, 500).

New in V2 Only

These features have no V1 equivalent — they are only available in V2:
FeatureEndpointDescription
Webhooks for invitationsPOST /v2/webhooksaccepted_invitationGet notified in real-time when someone accepts your invitation
Account logsGET /v2/accounts/{id}Monitor account status, activity, and connection health
Simplified account managementGET /v2/accountsList, inspect, and manage all connected accounts from a single endpoint
Hosted WebhooksPOST /v2/webhooks (no url)Built-in SSE stream + polling — no server required
Webhook Event FilterPOST /v2/webhookseventsSubscribe to specific event types only

Step-by-Step Migration

Step 1 — Connect Your Account

In V1, you obtained a login_token from /v1/auth/login and passed it in every request along with country. In V2, you connect your account once and receive a persistent account_id.
POST /v2/login
{
  "platform": "linkedin",
  "email": "[email protected]",
  "password": "your_password",
  "country": "FR"
}
// → { "data": { "account_id": "69c127...", "status": "connected" } }
Save the account_id — you’ll use it in all V2 requests. You no longer need to store or manage login_token or country.
If the response returns "status": "checkpoint_required", call POST /v2/checkpoint with the verification code sent to your email. This replaces POST /v1/auth/verify.
Re-calling /v2/login with an already migrated token returns the same account_id — the call is idempotent and free.

Batch Migration (SaaS with many accounts)

If you have hundreds of login_token values stored in your database, migrate them before changing code:
  1. Add account_id and migration_status columns to your accounts table
  2. Iterate all rows, call POST /v2/login with { "login_token": "...", "country": "..." } for each
  3. Handle outcomes per row:
    • connected → save account_id, mark migrated
    • error (expired token) → mark failed, user must re-auth
  4. Add 0.5–2s random delay between calls
  5. Switch code to use account_id only after batch is complete
  6. Drop login_token / country columns once V2 is fully deployed

Step 2 — Update Request Format

Every V2 action endpoint uses the same structure:
POST /v2/{category}
{
  "account_id": "69c127c37cae0494dd827286",
  "action": "action_name",
  "params": {
    "key": "value"
  }
}
What to change in your code:
  1. Remove login_token and country from every request body
  2. Add account_id at the root level
  3. Add action to specify what to do
  4. Move all other parameters inside a params object
  5. Rename linkedin_urlprofile_url, messagemessage_text (send message)
  6. Convert search filters from strings to arrays (see below)
POST /v1/profile/info
{
  "login_token": "AQED...",
  "country": "FR",
  "linkedin_url": "https://www.linkedin.com/in/example"
}

Search Filters: Strings → Arrays

In V1, multi-value search filters used semicolons or commas as separators. In V2, pass proper arrays. This applies to search_people and search_companies — affected parameters: location, company_url, school_url, industry, network, past_company, sector, company_size.
{
  "keyword": "CTO",
  "location": "Paris;London;New York",
  "network": "F,S"
}
Single values still work as plain strings — you only need arrays when passing multiple values.

Step 3 — Update Response Parsing

V1 responses had inconsistent formats across endpoints. V2 unifies everything:
  • Success: { "success": true, "data": { ... }, "metadata": { "action", "account_id", "credits_consumed", "timestamp" } }
  • Error: { "success": false, "error": { "code": "...", "message": "..." }, "metadata": { ... } }
What to change:
  • data["status"] == "success"data["success"] == True
  • Errors: use data["error"]["code"] and data["error"]["message"]
  • metadata.credits_consumed is always present — use it for credit tracking
  • Remove any per-endpoint parsing workarounds

Step 4 — Update Error Handling

V2 uses real HTTP status codes — V1 returned 200 for almost everything.
CodeHTTP StatusWhat To Do
INVALID_API_KEY403Check your API key
INVALID_ACCOUNT404Call GET /v2/accounts to list valid IDs
ACCOUNT_INACTIVE403Re-login via POST /v2/login
INVALID_ACTION400Check docs for valid actions
INVALID_PARAMS400Read error.message for details
RATE_LIMITED429Implement exponential backoff
INSUFFICIENT_CREDITS402Top up at app.linkupapi.com
CHANNEL_ERRORvariesRetry or check the platform directly
INTERNAL_ERROR500Retry after a few seconds
Errors never consume credits in V2.

Step 5 — Migrate Webhooks

In V1, webhooks were standalone “webhook accounts” with their own login_token. In V2, webhooks are configurations attached to existing accounts.
POST /v1/webhooks/accounts
{
  "platform": "linkedin",
  "login_token": "AQED...",
  "webhook_url": "https://your-server.com/webhook",
  "country": "FR"
}
Key changes:
  • No more separate “webhook accounts” — reuse your existing account_id
  • webhook_urlurl
  • Filter events with the events array: ["message_received", "accepted_invitation", "disconnection"]
  • Start/stop: /v1/webhooks/accounts/{id}/start/v2/webhooks/{id}/start
  • Status: replace GET .../status with the is_active field on GET /v2/webhooks
  • New hosted mode: omit url to get a built-in SSE stream + polling endpoint (no server needed)

Complete Endpoint Mapping

Authentication

V1 EndpointV2 Endpoint
POST /v1/auth/loginPOST /v2/login
POST /v1/auth/verifyPOST /v2/checkpoint
GET /v2/accounts (new)
GET /v2/accounts/{id} (new)

Profiles

V1 EndpointV2 Action
POST /v1/profile/mePOST /v2/profilesget_me
POST /v1/profile/infoPOST /v2/profilesget
POST /v1/profile/contactPOST /v2/profilesget_contact
POST /v1/profile/visitPOST /v2/profilesvisit
POST /v1/profile/searchPOST /v2/profilessearch_people
POST /v1/companies/searchPOST /v2/profilessearch_companies
POST /v1/companies/infoPOST /v2/profilesget_company

Messages

V1 EndpointV2 Action
POST /v1/messages/send-messagePOST /v2/messagessend
POST /v1/messages/inboxPOST /v2/messageslist_inbox
POST /v1/messages/conversationPOST /v2/messagesget_conversation

Network

V1 EndpointV2 Action
POST /v1/network/connectPOST /v2/networkinvite
POST /v1/network/accept-invitationPOST /v2/networkaccept
POST /v1/network/connectionsPOST /v2/networklist_connections
POST /v1/network/invitationsPOST /v2/networklist_invitations
POST /v1/network/sent-invitationsPOST /v2/networklist_sent
POST /v1/network/withdrawPOST /v2/networkwithdraw
POST /v1/network/invitation-statusPOST /v2/networkcheck_invitation
POST /v1/network/get-network-recommendationsPOST /v2/networkrecommendations

Content & Posts

V1 EndpointV2 Action
POST /v1/posts/createPOST /v2/contentcreate
POST /v1/posts/create-companyPOST /v2/contentcreate_company
POST /v1/posts/searchPOST /v2/contentsearch
POST /v1/posts/feedPOST /v2/contentget_feed
POST /v1/posts/likePOST /v2/contentlike
POST /v1/posts/reactPOST /v2/contentreact
POST /v1/posts/commentPOST /v2/contentcomment
POST /v1/posts/answer-commentPOST /v2/contentanswer_comment
POST /v1/posts/repostPOST /v2/contentrepost
POST /v1/posts/extract-commentsPOST /v2/contentget_comments
POST /v1/posts/reactionsPOST /v2/contentget_reactions
POST /v1/posts/time-spentPOST /v2/contenttime_spent

Recruiter

V1 EndpointV2 Action
POST /v1/recruiter/postsPOST /v2/recruiterget_posts
POST /v1/recruiter/get-candidatePOST /v2/recruiterget_candidates
POST /v1/recruiter/cvPOST /v2/recruiterget_cv
POST /v1/recruiter/publishPOST /v2/recruiterpublish_job
POST /v1/recruiter/closePOST /v2/recruiterclose_job

Email / Enrichment

V1 EndpointV2 Action
POST /v1/data/mail/finderPOST /v2/enrichfind_email
POST /v1/data/mail/reversePOST /v2/enrichreverse_email
POST /v1/data/mail/validatePOST /v2/enrichvalidate_email

Webhooks

V1 EndpointV2 Endpoint
POST /v1/webhooks/accountsPOST /v2/webhooks
GET /v1/webhooks/accountsGET /v2/webhooks
PUT /v1/webhooks/accounts/{id}PUT /v2/webhooks/{id}
DELETE /v1/webhooks/accounts/{id}DELETE /v2/webhooks/{id}
POST /v1/webhooks/.../startPOST /v2/webhooks/{id}/start
POST /v1/webhooks/.../stopPOST /v2/webhooks/{id}/stop
GET /v1/webhooks/.../statusCheck is_active on GET /v2/webhooks
GET /v2/webhooks/{id}/stream (new: SSE)
GET /v2/webhooks/{id}/events (new: polling)

Quick Migration Checklist

1

Connect your account

Call POST /v2/login with your credentials or existing V1 token to get an account_id.
2

Replace login_token with account_id

Remove login_token and country from all requests. Add account_id instead.
3

Update endpoint URLs

Replace individual V1 URLs with the V2 category endpoint + action field.
4

Wrap params

Move all action parameters inside the params object.
5

Rename parameters

linkedin_urlprofile_url, messagemessage_text. Convert search filter strings to arrays.
6

Update response parsing

Check success (boolean) instead of status (string). Access data via data field.
7

Update error handling

Use HTTP status codes and error.code for programmatic error handling.
8

Migrate webhooks

Create webhook configs via POST /v2/webhooks with your existing account_id.

Need Help?