Step by step: connect CRM via intermediary

Rules:

  1. Create the webhook in the intermediary (Make/n8n/custom)
    • Method: POST
    • Public HTTPS URL (this URL will be the crmAccessToken in LinkedScope).
    • The endpoint must accept the auth header (this value will be the crmSecretToken in LinkedScope).
    • The body received from LinkedScope is empty (null / no payload).
  2. Implement auth validation in the intermediary
    • Read req.headers.auth.
    • If different from the expected token, return 401/403.
    • If valid, continue with the CRM query.
  3. Fetch deals from the CRM and map them to the expected format
    • Your intermediary flow must call the desired CRM endpoints and return open deals (open/created date) from the last 24 months
    • Build a pure JSON array (not an object with deals)
    • Required return: HTTP 200 + application/json + […]
  4. Expected JSON response structure
    • The root must be an array: [ {deal1}, {deal2} ]
    • Recommended fields per deal:
      • dealName, dealLink, companyName, createdAt, dealStage, dealValue
    • Identification fields (strongly recommended):
      • linkedinCompanyId or companyUrn / company_urn
      • optional: linkedinCompanyUrl (/company/123 or /company/slug)
    • Status:
      • isWon: true | false | null
      • Also accepts strings such as won/lost/closedwon/closedlost

Practical example:

[
{
"dealId": "D-1001",
"dealName": "Enterprise Plan",
"dealLink": "https://crm.example.com/deals/D-1001",
"pipeline": "Sales",
"ownerName": "Ana Silva",
"ownerEmail": "[email protected]",
"companyName": "ACME",
"companyDomain": "acme.com",
"linkedinCompanyId": "89482395",
"dealStage": "Proposal sent",
"dealValue": 15000,
"createdAt": "2025-11-01T10:23:00Z",
"closedAt": null,
"isWon": null
}
]
  1. Configure in LinkedScope (Settings > Integrations > Any CRM)
    • Field 1 (trigger/webhook URL): URL of the intermediary webhook.
    • Field 2 (token): shared secret.
    • Save. The backend validates by calling the webhook (dummyFetch).
  2. Validation and synchronization
    • If webhook/auth fails on save: credential error (CRM Credentials Error).
    • With the connection saved, LinkedScope uses this webhook to load deals/users/stages.
    • Optional: trigger a manual sync via POST /api/v1/crm-sync/invoke (authenticated).
  3. Common error checklist
    • Returning { deals: […] } instead of […] → incorrect.
    • If you do not send ownerName / ownerEmail / dealStage → users/stages may appear incomplete or empty.
    • URL without http/https → blocked in the UI.
    • Empty token → the ANY integration may return empty results.

Webhook response requirements:

  • The response must be a JSON array ([ … ]), not an object.
  • Return open deals from the last 24 months (2 years) for a better experience.
  • Technically the parser accepts deals with missing fields (fallback logic is applied), so the “hard required per deal” fields are minimal.
  • In practice, for proper functionality, return at least:
    • dealName, dealLink, companyName, createdAt, dealStage, dealValue
  • Highly recommended:
    • id/dealId/deal_id (dedupe)
    • linkedinCompanyId or companyUrn (better matching)
    • ownerName and ownerEmail (owners/listings)