InsightHireHelp Center

LinkedIn

LinkedIn Apply Connect, OAuth setup, job posting, webhook apply ingestion, and Talent Solutions partner requirements.

LinkedIn integration lets orgs cross-post InsightHire positions to LinkedIn, ingest Easy Apply / Apply Connect applications via webhook, and sync screening results back to LinkedIn. Setup requires LinkedIn Talent Solutions partnership approval — standalone developer apps cannot access Job Posting or Apply Connect APIs.

Prerequisites

  1. LinkedIn Talent Solutions partner application — apply at LinkedIn ATS Partners.
  2. LinkedIn Developer App with Client ID and Client Secret.
  3. Numeric company organization ID (without urn:li:organization: prefix).
  4. Org Admin role in InsightHire.

Sign In with LinkedIn does not unlock recruitment APIs. If Auth → OAuth 2.0 scopes shows "No permissions added", Member OAuth will fail with invalid_scope_error.

Settings path

StepLocation
Connect integration/dashboard/settings/integrations/linkedin/setup
View connection status/dashboard/settings/integrations
Cross-post a positionPosition detail → LinkedIn actions (or API postPosition)

During setup the UI displays two URLs you must register in the LinkedIn Developer App:

URL typeAPI pathPurpose
OAuth redirect{API_BASE}/integrations/linkedin/callbackMember OAuth callback (optional)
Apply webhook{API_BASE}/api/webhooks/linkedin/applicationsApply Connect application delivery

Production example: https://api.insighthire.com/api/webhooks/linkedin/applications

Connection modes

InsightHire supports two connect paths via ats.linkedin.completeOAuth and ats.linkedin.connectWithCredentials:

Job Posting and Apply Connect use 2-legged OAuth (client_credentials). No browser redirect required.

  1. Open LinkedIn setup.
  2. Choose Client credentials only.
  3. Enter Client ID, Client Secret, organization URN/ID, and optional poster email.
  4. Select API type: apply-connect (default) or talent-hub.
  5. Submit — InsightHire tests the connection and stores config in ats_integrations.

Use this mode when LinkedIn Auth shows no member scopes.

Member OAuth (optional)

For Talent Hub admin flows that require member delegation:

  1. Choose Member OAuth.
  2. InsightHire generates an authorize URL with scopes:
    • Apply Connect: r_organization_admin, rw_organization_admin, r_recruitment
    • Talent Hub: above plus w_recruitment
  3. User completes LinkedIn consent; callback exchanges code for tokens.
  4. Tokens stored with refresh support in integration config.

If scopes are not provisioned by LinkedIn, authorization fails — switch to client credentials.

Register webhook in LinkedIn

In your LinkedIn app (Apply Connect configuration):

  1. Set jobApplicationWebhookUrl to the Apply webhook URL from setup.
  2. LinkedIn sends a GET challenge to validate ownership:
GET /api/webhooks/linkedin/applications?challengeCode=...

InsightHire responds with:

{
  "challengeCode": "<code>",
  "challengeResponse": "<hex HMAC-SHA256(challengeCode, clientSecret)>"
}
  1. LinkedIn then POSTs EXPORT_JOB_APPLICATION events to the same endpoint.

Webhook apply ingestion

POST bodies are verified with X-LI-Signature:

stringToSign = "hmacsha256=" + rawBody
signature = hex(HMAC-SHA256(stringToSign, clientSecret))

On valid signature, InsightHire calls ingestLinkedInApplyConnectApplication, which:

  • Resolves the position by externalJobId (InsightHire position ID or LinkedIn external ID).
  • Creates or updates the candidate application with externalSource: LINKEDIN.
  • Triggers journey invite flow when configured.

Non-apply event types are acknowledged with 200 and ignored.

Posting jobs to LinkedIn

After connection, cross-post from InsightHire via ats.linkedin.postPosition:

OperationEffect
CREATEPublish new LinkedIn job from position
UPDATESync title, description, location changes
CLOSEClose listing on LinkedIn
RENEWRenew expired posting

Optional posterEmail overrides the default recruiter email on Job Posting API calls.

Manual sync alternatives:

  • syncJobs — pull LinkedIn jobs into InsightHire
  • syncApplicants — pull applicants for a job

BullMQ schedules periodic LinkedIn sync after connect.

Status sync-back

When recruiters advance LinkedIn-sourced candidates:

  • updateCandidateStage updates local status and maps stage to LinkedIn application status when syncToLinkedIn: true.
  • postScreeningResults pushes assessment scores (adjusted/raw score, video URL, completion time) to LinkedIn after journey completion.

Partner approval requirements

RequirementDetail
Product accessJob Posting API and/or Apply Connect must be provisioned by LinkedIn — they do not appear on a standalone Products tab until partnership approval
Webhook URLMust be publicly reachable HTTPS (InsightHire API host)
Organization IDMust match the LinkedIn company page numeric ID
Client secretUsed for webhook challenge, signature verify, and token exchange
Member scopesOnly after Talent Solutions products are approved; otherwise use client credentials

Common errors:

ErrorResolution
invalid_scope_errorUse client credentials connect; apply for Talent Solutions partnership
INVALID_SIGNATURE on webhookVerify client secret matches LinkedIn app; check raw body parsing
Position not found on applyEnsure externalJobId in webhook matches InsightHire position ID used at post time
Unauthorized on postRe-connect integration; refresh tokens or verify partner product access

API reference (tRPC)

ProcedurePurpose
ats.linkedin.getSetupUrlsOAuth redirect + webhook URLs
ats.linkedin.getAuthUrlStart member OAuth
ats.linkedin.connectWithCredentials2-legged connect
ats.linkedin.completeOAuthFinish member OAuth
ats.linkedin.testConnectionVerify credentials
ats.linkedin.postPositionCross-post / update / close
ats.linkedin.syncJobsPull jobs from LinkedIn
ats.linkedin.syncApplicantsPull applicants
ats.linkedin.postScreeningResultsPush assessment results

External documentation