Skip to content
Dialer & Setup

Connecting a Custom CRM to a SIP Trunk: The Technical Integration Path

Off-the-shelf CRMs integrate with SIP trunks through pre-built connectors. Custom CRMs — built in-house or heavily modified from a base platform — require a direct integration path: SIP credentials, event webhooks, and a caller ID assignment layer all wired to your own data model. This is the playbook.

What "Custom CRM" Means in This Context

A custom CRM integration does not necessarily mean a from-scratch system. It includes:

  • An internally built sales or customer management tool with a calling feature added
  • A heavily customized Salesforce or HubSpot deployment where the native telephony adapters do not cover all required use cases
  • A contact center platform built on an open-source base (Odoo, SuiteCRM, vtiger) with telephony requirements that outstrip the built-in adapters
  • A no-code or low-code platform (Airtable, Notion, custom Retool app) extended with outbound calling capabilities

In all these cases, the integration path is the same: the CRM must initiate SIP calls, receive call completion events, and write call records to the data model. The mechanism is direct rather than through a pre-packaged adapter.

Integration Components Required

A complete custom CRM-to-SIP integration requires four components:

1. SIP client or click-to-call bridge. The CRM needs a mechanism to initiate outbound calls. Options:

  • WebRTC softphone embedded in the CRM UI. A JavaScript SIP library (JsSIP, SIP.js) runs in the browser, connects to the SIP gateway using the account credentials, and initiates calls from the agent's browser session. This is the most common approach for web-based CRMs.
  • Click-to-call API bridge. The CRM backend sends an API call to initiate a call rather than managing the SIP session directly. UnlimCall's call initiation API accepts a from number, a to number, and a seat credential — the trunk handles the SIP session, and the CRM receives a call UUID and events.
  • Hardware or desktop SIP client. For CRMs with desktop clients or where browser-based calling is not viable, a SIP softphone (Zoiper, Bria, Linphone) handles the SIP session, and the CRM logs events via webhook.

2. Credential and DID management. Each agent seat needs a SIP username and credential pair issued by the trunk provider. The CRM's user model must store these credentials — or reference them by seat ID — to send them with each call initiation request. DIDs provisioned across UnlimCall's 33 markets map to seat credentials in the portal and must be associated with CRM user records for caller ID to render correctly.

3. Webhook receiver. A HTTP endpoint in the CRM backend that accepts call event payloads. The endpoint must return 200 quickly and queue event processing asynchronously. See the event pipeline guide for the receiver architecture.

4. Call record data model. The CRM's database must have a table or collection for call records with at minimum: call UUID, contact foreign key, agent foreign key, direction, from/to numbers, initiated at, answered at, ended at, duration, hangup cause, and disposition. Agent-entered disposition data joins to the machine-generated call record by call UUID.

Implementing the WebRTC Path in a Custom Web CRM

For a web-based CRM built on React, Vue, or a similar framework, the WebRTC path uses a JavaScript SIP library to manage the call session in the browser. Here is the implementation sequence:

First, install a SIP library as a project dependency. JsSIP is widely used and well-maintained.

Second, initialize a SIP user agent in the CRM's calling module using the credentials stored in the current agent's user session. The user agent points to UnlimCall's WebRTC SIP gateway (WSS endpoint) and registers on session start.

Third, when an agent clicks a phone number in the CRM, the calling module calls the SIP user agent's call method with the destination number and the agent's configured caller ID. The SIP INVITE goes to the gateway; the gateway routes to PSTN.

Fourth, the call session object emits events (progress, established, ended) that the CRM calling module maps to UI states and fires to the backend to create or update the call record.

Fifth, on call end, the calling module posts the final state (duration, hangup cause) to the CRM backend, which writes the completed call record and triggers any post-call workflows (disposition prompt, next-action scheduling, webhook to external systems).

The full SDK reference for the SIP gateway's WebRTC configuration parameters is in the custom SIP integration guide.

Caller ID in a Custom CRM Context

The custom CRM must pass the correct caller ID in the SIP From header. The From header value must exactly match a DID provisioned to the UnlimCall account — including country code format.

For multi-country deployments, the CRM's agent profile or campaign configuration should store the DID for each target country and select the correct one when initiating the call based on the destination number's country prefix. A simple implementation: store a country-to-DID mapping in the CRM's configuration table; on call initiation, look up the DID for the destination number's country code.

UnlimCall provisions DIDs on demand across 33 live markets. The pricing page covers DID provisioning as part of seat setup.

Handling the SIP-to-HTTPS Credential Boundary

SIP credentials (username and password) stored in a browser application are visible in browser developer tools if stored in JavaScript state. For a production custom CRM, SIP credentials should not be stored in the browser.

Two patterns address this:

Server-proxied credential injection. On agent login, the CRM backend issues a short-lived SIP credential token (valid for the session, not the permanent password). The frontend uses the token to register with the SIP gateway. The permanent credential never touches the browser.

Backend call initiation. Instead of managing the SIP session in the browser, the CRM backend initiates calls through a REST API and receives events through webhooks. No SIP credential is stored in the frontend at all. The tradeoff: call quality depends on the backend's ability to manage the SIP session reliably, which is more complex to build correctly than a browser WebRTC session.

Testing the Integration

A custom CRM integration requires more rigorous testing than a pre-built connector because there is no reference implementation to compare against. Minimum test coverage:

  • Call initiation succeeds with valid credentials; fails with invalid credentials (credential validation is working)
  • Correct caller ID renders on the receiving end (DID-to-seat mapping is correct)
  • Call completion webhook fires and the CRM creates a call record (end-to-end pipeline is connected)
  • Duplicate webhook delivery does not create duplicate call records (deduplication is working)
  • Call fails gracefully when the destination is busy, no-answer, or unreachable (error states handled)
  • Agent session disconnect mid-call does not leave the call connected on the PSTN side (call cleanup is working)

Takeaways

  • Custom CRM integrations need four components: SIP client, credential and DID management, webhook receiver, and a call record data model.
  • WebRTC via JsSIP or SIP.js is the standard path for web-based CRMs; click-to-call API bridge is the alternative if browser SIP management is impractical.
  • SIP credentials must not be stored in browser JavaScript state — use server-proxied short-lived tokens or backend call initiation.
  • Caller ID must exactly match a provisioned DID; store a country-to-DID mapping for multi-country deployments.
  • Test six integration cases before production rollout: success, invalid credentials, correct caller ID, webhook delivery, duplicate suppression, and call cleanup.

Start With the Integration Documentation

The custom SIP integration guide covers the SDK, webhook schema, and API reference. The pricing page covers seat and DID provisioning.