Managing LinkedIn Integration

Create a New Identity First

As a reminder, to automate LinkedIn actions, you must first create an identity in Captain Data using the Create an Identity endpoint. Example request:
curl --request POST \
  --url https://api.captaindata.com/v4/identities \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --data '{
  "name": "John Doe or a reference for your identity",
  "timezone": "Europe/Paris"
}'
name
string
A name that allows you to identify the Identity: it can be the full name of the Identity or an internal reference (or both!) at your convenience.
timezone
string
The Identity’s timezone.
The timezone field provisions a proxy IP matching that timezone/country. This needs to match the location where you log into your LinkedIn account to avoid restrictions.
When using a VPN, either
  1. Log out of your VPN before accessing social media, or
  2. Ensure the “timezone” you send matches the country of the VPN IP address.
Captain Data supports the canonical IANA time zones, as defined by the tz database. Only canonical names are accepted. Deprecated or alias entries are currently not supported.Example: “Europe/Kiev” is deprecated and has been replaced by “Europe/Kyiv”, which is the valid canonical identifier. Deprecated names are maintained in the IANA backward zone file for legacy compatibility but should not be used.

Connect LinkedIn to Identities

After adding an Identity, you will Connect an Identity’s Integration in order to link the LinkedIn account to the identity. You can connect LinkedIn accounts in two ways:
  1. Synchronize cookies: Send LinkedIn authentication cookies (li_at and optionally li_a for Sales Navigator) to connect an account. This is useful when:
    • You already have the cookies from your own Chrome extension
    • You want to handle authentication yourself
    • You need precise control over cookie management
curl --request POST \
  --url https://api.captaindata.com/v4/identities/{identity_uid}/integrations/linkedin \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --data '{
  "account_name": "LinkedIn Account #1",
  "auth_data": {
    "cookies": {
      "li_at": "<li_at_token>",
      "li_a": "<li_a_token>"
    }
  }
}'
account_name
string
Name of the LinkedIn account, e.g. “LinkedIn Account #1”. It’s generally the User’s full_name or email.
auth_data.cookies
object
For COOKIES integration types, provide authentication cookies here.
Important note: If you’re connecting an account for LinkedIn Sales Navigator, you need to send both cookies. If you don’t include the li_a token, the connection may not work properly with LinkedIn Sales Navigator. Including the li_a token will also speed up account synchronization.
  1. Connect natively: Provide the LinkedIn email and password to let Captain Data handle the authentication flow. This is recommended when:
    • You want a simpler integration
    • You don’t want to manage cookies
    • You need automatic cookie refresh
curl --request POST \
  --url https://api.captaindata.com/v4/identities/{identity_uid}/integrations/linkedin \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <api-key>' \
  --data '{
  "auth_data": {
    "basic": {
      "username": "elon@musk.com",
      "password": "********"
    }
  }
}'

Monitor LinkedIn Integration Status with Webhooks

LinkedIn integrations have a lifecycle that you can monitor in real-time using webhooks. Whether the integration was created through user interaction, frontend operations, or API calls, webhooks provide instant notifications about status changes. Webhooks send HTTP requests to your platform when integration events occur, allowing you to:
  • React immediately to authentication issues
  • Notify users about account status changes
  • Trigger automated responses (e.g., resync flows)
  • Monitor integration health proactively

Setup Process

1

Configure Your Webhook URL

Configure a webhook URL in the developer section of your Captain Data workspace.
Webhook URL Requirements:
  • Must be HTTPS (e.g., https://your-domain.com/webhooks)
  • Supports extended URLs with basic auth, ports, and query parameters (up to 1024 characters)
  • Example: https://user:pass@your-website.com:8080/webhooks/captaindata/linkedin-integration?foo=bar
You can also add up to 10 custom headers (e.g., API keys) that will be included with each webhook call.
2

Implement Your Webhook Handler

Each LinkedIn integration event triggers a POST request to your configured URL with this JSON payload:
{
  "event_uid": "<string>",
  "event_type": "integration",
  "event": "AUTH_SUCCESS" | "AUTH_PENDING" | "AUTH_FAILED" | "AUTH_EXPIRED",
  "timestamp": "<ISO 8601 datetime>",
  "data": {
    "identity_uid": "<string>",
    "integration_permalink": "linkedin",
    "workspace_uid": "<string>",
    "auth_type": null | "BASIC" | "OAUTH" | "COOKIES" | "APIKEY",
    "setup_source": null | "MANUAL" | "EXTENSION" | "SHARED" | "API",
    "reason": null | "<string>",
    "action_to_be_taken": null | "CONTACT_SUPPORT" | "RETRY_LOGIN" | "RETRY_CHECKPOINT"
  }
}
Field Explanations
FieldDescription
event_type, eventThe type and nature of the integration event
dataStandard integration information (see API reference)
reasonCause of the event (especially relevant for AUTH_EXPIRED)
action_to_be_takenRecommended next step for handling the event

Event Types

EventDescriptionTypical Action
AUTH_SUCCESSIntegration successfully authenticatedContinue normal operations
AUTH_PENDINGAuthentication in progressWait for completion
AUTH_FAILEDAuthentication failedRetry or notify user
AUTH_EXPIREDAuthentication expiredTrigger resync flow

Use Cases

1. Handle Expired Sessions

When you receive an AUTH_EXPIRED event with action_to_be_taken: "RETRY_LOGIN", you can:
  • Trigger immediate resync via API call
  • Notify users to re-authenticate
  • Pause dependent workflows until resolved

2. Monitor Native Login Workflow

When using the native login workflow, users complete authentication asynchronously. The AUTH_SUCCESS event confirms when setup is complete.
Best Practices:
  • Ensure your webhook endpoint handles POST requests and JSON payloads
  • Implement proper error handling and logging
  • Consider verifying webhook authenticity (e.g., via headers)
  • Respond quickly to webhook requests (within 5 seconds)

Best Practices for LinkedIn Automation

VPN and Timezone/Country Settings
  • Ensure the timezone in Captain Data matches your login location on LinkedIn.
  • Match your VPN’s country with Captain Data, or disconnect the VPN while logging in.
Managing Chrome Sessions
  • Use Captain Data’s Chrome Extension to automatically sync cookies, useful for testing purposes.
  • If you’re using multiple LinkedIn accounts on the same browser, you must create separate Chrome profiles:
    • Click your Chrome profile icon > Add a new profile.
    • Name it according to the LinkedIn account (e.g., “Account B”).
    • Log in to Captain Data and LinkedIn within this new session.
Updating cookies for Account A while logged into Account B can lead to mismatches and errors.

Refreshing Cookies

Cookies need refreshing if:
  • You log out of LinkedIn
  • LinkedIn expires or changes cookies
  • LinkedIn restricts the account due to excessive activity
Regular activity and following Smart Limits guidelines help prevent restrictions.

How to refresh cookies via API

To refresh accounts via API, use the Connect an Identity’s Integration endpoint by passing the updated li_at and/or li_a cookie values:
If you build your own Chrome Extension, you should refresh cookies every 2 hours or so.
Here’s a code example for a Chrome Extension that runs in the background using alarms:
/**
 * Alarm to update cookies every X minutes.
 */
chrome.alarms.onAlarm.addListener(() => {
  // Ensure updateTokensHandle() is defined elsewhere in your code
  return updateTokensHandle();
});

// Set up the alarm when the extension is installed
chrome.runtime.onInstalled.addListener(async ({ reason }) => {
  const periodDurationMinutes = 120; // Every 2 hours

  // Create an alarm that will trigger every `periodDurationMinutes`
  await chrome.alarms.create("updateToken", {
    periodInMinutes: periodDurationMinutes,
  });

  console.log(
    "Alarm created to update token every " + periodDurationMinutes + " minutes"
  );
});
Complete source code is available on GitHub.

Smart Limits to Prevent Restrictions

Captain Data developed a unique Smart Limits feature to protect your users’ LinkedIn accounts. Learn more in this article LinkedIn Rate Limits.

LinkedIn Licenses Compatibility

Captain Data supports various LinkedIn licenses, each with unique features and limitations. Below is a breakdown of how each license integrates with Captain Data:
LicenseCaptain Data LevelCaptain Data CompatibilityInMails/MonthInvitations with NoteCRM Integration
LinkedIn BasicClassic✅ Yes05/monthNo
LinkedIn Premium CareerClassic❌ No5N/ANo
LinkedIn Premium BusinessClassic✅ Yes15400No
Sales Navigator CoreSales Navigator✅ Yes50400No
Today Captain Data handles LinkedIn Basic, LinkedIn Premium Business, and Sales Navigator Core which are defined as level in the LinkedIn integration. By following this guide, you can safely automate LinkedIn activities with Captain Data, ensuring stable sessions and avoiding platform restrictions. For further assistance, feel free to reach out to our support team at support@captaindata.com 🙌

Troubleshooting LinkedIn Login Errors

When connecting a LinkedIn account natively (using username and password), you may encounter various errors. Below is a comprehensive guide to the most common error cases, their meanings, and how to resolve them.

Common Error Cases

When using our native LinkedIn connection module (username and password), you may encounter various errors. Below is a comprehensive guide to the most common error cases, their meanings, and how to resolve them.
ScenarioMessageStatusError
Invalid credentialsUsername or password invalid.400INVALID_CREDENTIALS
Double-check your LinkedIn username and password.
See authentication endpoint
Google login not supportedUsername or password invalid.400INVALID_CREDENTIALS
Google login is not supported.
Use “Forgot password” on LinkedIn to set a password and use that for login.
Checkpoint code invalidCode invalid.400INVALID_CODE
The checkpoint (2FA/SMS/email) code is incorrect. Try again.
See checkpoint endpoint
In-app challenge pendingWaiting for user to validate in_app_challenge500IN_APP_CHALLENGE_PENDING
Complete the challenge in your LinkedIn app.
In-app challenge expiredIn_app_challenge expired. Please retry the whole process by sending credentials again on /authenticate500IN_APP_CHALLENGE_EXPIRED
Start the login process again.
2FA expired2FA expired. Please retry the whole process by sending credentials again on /authenticate5002FA_VALIDATION_EXPIRED
Start the login process again.
Failed IP attributionCould not login the account.500LOGIN_ACCOUNT_500_ERROR
Retry logging in. This is a LinkedIn-side issue.
IP allocation errorIP allocation error. Please retry again in 5 minutes or contact support.400IP_ATTRIBUTION_ERROR_400
Wait 5 minutes and try again, or contact support.
IP allocation conflictIP allocation error. Please retry again in 5 minutes or contact support.409IP_ATTRIBUTION_CONFLICT_409
Wait 5 minutes and try again, or contact support.
IP rate limit exceededRate limit exceeded IP attribution, please try again in five (5) minutes or contact the support.429IP_ATTRIBUTION_RATE_LIMIT_429
Wait 5 minutes and try again, or contact support.
No IP available in timezoneNo IP available in this timezone. Update your timezone to a neighbouring one or contact support.400IP_TIMEZONE_NOT_SUPPORTED_400
Change your timezone in Captain Data or contact support.
Captcha challengeError while resolving the challenge, the Captcha challenge seem to be pending. Re-send username and password to overcome this.500CAPTCHA_CHALLENGE_ERROR
Retry the authentication with your credentials.
Unsupported challengeUnsupported challenge identified, please contact the support and provide it with the identity_uid so we can address it.500UNSUPPORTED_CHALLENGE
Contact support with your identity_uid.
Simple challenge failedError while solving challenge, retry in 5 minutes, if it persists contact support.500LOGIN_SIMPLE_CHALLENGE
Wait and retry, or contact support.
Checkpoint missing dataError while solving the challenge, retry the whole process by sending credentials to /authenticate again500CHECKPOINT_MISSING_DATA
Start the login process again.
User management not permittedUser management via the API is not permitted for the current workspace, activate the option on settings403CREATE-ONE-ACCOUNT_403_FORBIDDEN
Enable user management in your workspace settings.
Identity already existsAn identity with the same Linkedin ID already exists.409CREATE_OR_UPDATE_ACCOUNT_409_CONFLICT
Use a different LinkedIn account or identity.
Account already exists on identityAn account already exist on this identity409CREATE_OR_UPDATE_ACCOUNT_409_CONFLICT
This will be merged in the future.
Account link changePlease note that your LinkedIn integration is different from the one that has already been synchronized on this identity.409CREATE_OR_UPDATE_ACCOUNT_409_CONFLICT
Use the same LinkedIn account as previously connected.
Other errorsError while synchronizing your account, please retry again or contact the support.500-
Retry or contact support.

Notes & Recommendations

  • Google Login: If your LinkedIn account uses Google login, you must set a password on LinkedIn (via “Forgot password”) to use native login.
  • IP/Location Issues: Many errors are related to IP allocation or location mismatches. Make sure your timezone and country settings in Captain Data match your actual login location.
  • Challenge/2FA: If you receive a challenge (SMS, email, in-app), complete it promptly. If it expires, restart the login process.
  • Contact Support: For persistent or unclear errors, contact support and provide your identity_uid for faster resolution.
For more details, see the LinkedIn authentication and checkpoint API documentation.