External Api docs

VsCRM → DialSummary lead webhook

This is an inbound integration. Configure VsCRM automation to POST new leads to DialSummary; this implementation does not call VsCRM APIs or configure VsCRM remotely. VsCRM outbound webhook availability must be confirmed with its team.

Deployment

VsCRM schema is deployed manually, without an EF migration for this feature. Before deploying the updated backend, select the intended database and run Migrations/Manual_RepairVsCrmIntegration.sql. It adds the connection table and nullable crm_leads.external_lead_id, then returns schema verification results. Existing crm_leads is required. Existing tables/columns are skipped, not rebuilt; verify their definitions if they already exist. The script uses datetime for compatibility with older MySQL servers and does not modify EF migration history. Preserve any historical migration entries already present in existing databases. Keep the entity models and DbContext mappings: the API requires them to access the manually provisioned schema. Future EF migrations must account for this schema as already provisioned rather than attempting to create it again.

1. Generate a company connection (Admin only)

POST /api/integrations/vscrm/connection

Header: sessionId: <active company Admin session GUID>

No body. The response contains connectionId, source: "VsCRM", apiKey, and webhookPath. Prefix the path with the deployed public HTTPS API origin to obtain the URL for VsCRM. The origin is deliberately not inferred from an untrusted Host header. The generated key is returned only here; only its SHA-256 hash is stored.

There is one VsCRM connection per company. Calling POST again rotates the key and reactivates the same connection, immediately invalidating the previous key. GET /api/integrations/vscrm/connection returns metadata/path, never the key. DELETE /api/integrations/vscrm/connection disables incoming deliveries. Both require the same company Admin session header.

2. Configure VsCRM's outgoing webhook

Trigger: new lead. Method: POST. URL: public API origin + returned webhookPath.


POST /api/integrations/vscrm/<connectionId>/leads
Content-Type: application/json
X-Api-Key: <generated DialSummary connection key>

{
  "externalLeadId": "VS-10001",
  "name": "Demo Lead",
  "countryCode": "+91",
  "mobile": "9876543210",
  "email": "demo@example.com",
  "companyName": "Example Company",
  "description": "Requested a product demo"
}

Map VsCRM's stable lead ID to externalLeadId, lead name to name, phone to mobile, email to email, notes to description. Name, externalLeadId, countryCode and mobile are required. Email, companyName and description are optional. Country code must be explicit. Mobile may be national digits or start with the specified +countryCode; spaces, parentheses and hyphens in the national number are removed. Combined country code and number must not exceed 15 digits.

Do not send company IDs, assignment or source: the connection determines the company and source. The API always saves source VsCRM, status New, and null assignee and assigned-by fields. Unknown payload fields cannot change these server-owned values.

Created response (201):


{
  "success": true,
  "isDuplicate": false,
  "leadId": 123,
  "source": "VsCRM",
  "assignedUserId": null,
  "message": "Lead received and saved unassigned."
}

3. Duplicate and error handling

  • Same company + VsCRM external ID: skip, including previously deleted records.
  • Same company + active normalized country/mobile or email: skip, across sources.
  • Existing duplicates are not overwritten or reassigned.
  • Duplicate response: 200, success: true, isDuplicate: true, existing leadId.
  • Deliveries for one connection are serialized using a database transaction/row lock, including across application instances. This protects simultaneous webhook retries; it does not change duplicate behavior of existing Excel/manual-create endpoints.
  • 400: invalid/missing input; correct the payload before resending.
  • 401: invalid/disabled connection/key or deleted/unconfigured company.
  • 403: connection management requires company Admin access.
  • 413: request exceeds 32 KiB.
  • Retry network/5xx failures with the same externalLeadId and exponential backoff.

4. Existing CRM Sync screen and assignment

List unassigned VsCRM leads:

GET /api/crm-leads?source=VsCRM&unassignedOnly=true&page=1&pageSize=20

Use the existing authenticated company session. Each item's source is available for the CRM source column/badge. Frontend needs to consume these fields/filters.

Admin selects leads and uses the existing endpoint:


PATCH /api/crm-leads/bulk-assignment
sessionId: <company session>
Content-Type: application/json

{ "leadIds": [123, 124], "assignedUserId": 42 }

This preserves the existing Excel-import assignment process. Calling/follow-up continues through existing application features; this change does not implement outbound call-history sync to VsCRM.

Acceptance checks before connecting production

On an isolated migrated MySQL database: create two company connections; verify a key cannot authenticate another connection; reject ordinary users managing connections; send a lead and verify null assignment/source; resend sequentially and concurrently and confirm one row; verify country-code separation; verify email duplicates; disable/rotate keys and reject old credentials; verify other-company leads stay invisible; assign received IDs using the existing bulk-assignment endpoint.