Robottino

Phone system CRM integration with webhooks and APIs

A phone system CRM integration makes your calls and your customer records talk to each other: calls open the right contact, outcomes land in the history, new leads reach your calling campaigns. This guide explains how webhooks and APIs work, which events to pick, how to secure them and how to build a receiver that never loses data.

9 min readUpdated on

Why integrate your phone system with your CRM

When the phone system and the CRM live apart, your agents do every job twice: they talk to the customer, then type the number, the reason for the call and the outcome into the CRM. It is slow, it invites mistakes, and the data shows up late or not at all. A phone system CRM integration removes that step: whatever happens on the phone gets recorded automatically, at the moment it happens.

The practical gains are easy to see. Agents know who is calling before they pick up. Managers find the full contact history in the CRM, calls included. Missed calls turn into follow-up tasks instead of numbers forgotten in a log. Leads from your website or a trade show go straight into calling campaigns, with no spreadsheet exports in between.

Two tools make this possible, and they work in opposite directions. Webhooks push events from the phone system to your CRM. APIs let your CRM pull data from the phone system or tell it to do something. Most solid integrations use both.

  • Screen pop: the contact record opens when the phone rings.
  • Calls, durations and outcomes logged on the contact timeline.
  • Tasks created for missed calls and callers who hung up in the queue.
  • Leads loaded into campaign lists.
  • A click-to-call button inside your CRM.

Webhooks vs API: the short version

A webhook is an HTTP request the phone system sends to a URL you own whenever an event happens: a call comes in, an agent answers, an outcome is saved. Your system does not have to ask; it hears about it straight away. That is the push model.

An API works the other way round. Your program calls the phone system whenever it needs to read or change something: add a lead to a list, look up a contact, start a call. That is request and response.

A common mistake is to use only the API to find out what is going on, asking the phone system for changes every few seconds. Polling works, but it wastes resources, runs into rate limits and is still late. For real-time events, use webhooks. Use the API for actions and for fetching data on demand.

WebhooksAPI
Who starts itThe phone systemYour system
WhenAs soon as an event happensWhenever you decide
Typical usesCall, queue, outcome and attendance notificationsLoading leads, updating contacts, click-to-call, reading call history
What you needA public HTTPS endpoint that respondsAn API key and a program making requests
Main riskA slow or unreachable receiverHitting rate limits

Which phone system events to send to your CRM

The temptation is to switch on every event. Resist it: each extra event is more traffic to handle and more logic to maintain. Start from the questions your CRM needs to answer and pick only the events that answer them.

Cloud phone system events usually come in families: calls (incoming, ended, missed), queues (entered, answered, abandoned, timed out, full), agents (login, break, ringing, answered, outbound call, transfer, outcome), IVR menus (entered, key pressed, no choice), feedback surveys and callback requests. In Robottino's webhooks and API there are 27 of them in seven groups, and you can limit each webhook to specific queues, agents, numbers or IVR menus.

Goal in the CRMEvent to useUseful data
Screen pop before answeringCall ringing for an agentCaller number, queue, agent extension
Call historyCall endedDuration, wait time, technical result
Callback tasksMissed call, abandoned in queueNumber, queue, wait time
Sales outcomesOutcome saved, or conversionOutcome name, note, callback date
Agent attendanceLogin, logout, break, availableAgent, break length
IVR analysisKey pressed, no choiceMenu, key, destination

Webhook payloads: full event or custom fields

Every webhook carries a body, almost always JSON, and there are two ways to shape it. The first is the full event: an ID, the event type, a timestamp and a data block with every object involved, such as the call, the contact, the queue and the agent. Pick this if you write the receiver yourself, because you get everything and decide in code what to keep.

The second is a custom payload: you choose the field names and fill them with variables such as {{call.from}}, {{queue.name}}, {{operator.extension}} or {{outcome.name}}. This helps when the receiving end expects an exact format, for example a CRM endpoint that wants "phone" and "agent" and nothing else, or an automation tool where you want tidy fields from the first step.

One detail matters more than it seems: a field that holds a single variable should keep its type. Numbers should arrive as numbers, true or false as booleans, missing values as null rather than an empty string. Your CRM then has nothing to convert and its filters just work.

  • Keep field names stable. Renaming them breaks whatever sits on the other end.
  • Send phone numbers in international E.164 format (such as +44...) so the CRM can match contacts reliably.
  • Always include an event ID and a call ID. You need them to spot duplicates and to tie several events of one call together.
  • To map agents to CRM users, store the CRM user ID as a custom field on the agent and send it in the webhook.

Webhook security: HTTPS, signatures and secret headers

A webhook endpoint is public by nature: anyone who finds the URL can post to it. A proper receiver therefore checks every request really comes from the phone system and has not been altered or replayed.

HTTPS is the baseline; without it, phone numbers and names travel in clear text. Next comes the signature. The phone system computes an HMAC-SHA256 of the request body with a secret only you know and puts it in a header. Your receiver computes the same HMAC and compares; if it does not match, the request is rejected. In Robottino the header is Robottino-Signature, holding t=timestamp and v1=signature, computed over the timestamp, a dot and the body.

The timestamp protects against replay attacks, where someone captures a valid request and sends it again later. Your receiver checks that the timestamp is recent, say within five minutes of server time, and turns older requests away. You pick the tolerance: loose enough for small clock drift, tight enough that a copied request is useless.

  1. Read the raw body

    Compute the signature over the body exactly as received, before parsing the JSON. A single changed space alters the result.

  2. Split the header

    Take the value after t= and the value after v1=.

  3. Recompute the HMAC

    Using the signing secret, compute HMAC-SHA256 of timestamp, dot and body, as hex.

  4. Compare in constant time

    Use your language's timing-safe comparison rather than a plain equality check, so you leak nothing to someone guessing signatures.

  5. Check the timestamp

    Reject anything outside your tolerance window.

Retries, duplicates and fast responses

Sooner or later your server will be unreachable: a deployment, an expired certificate, a traffic spike. A good phone system does not drop the event; it tries again. In Robottino, if your endpoint does not return a 2xx status within 10 seconds, delivery is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours. If nothing gets through for more than three days, the webhook is paused and you get an email.

That means your receiver must be idempotent: getting the same event twice must not create two tasks or two timeline entries. The simple fix is the event ID. It comes in the body and in the Robottino-Event-Id header, and it stays the same across retries and when you resend an event by hand from the delivery log. Store the IDs you have processed; when a known one comes back, return 200 and do nothing else.

The other rule is to answer quickly. Ten seconds sounds generous until your handler calls the CRM, waits on another API and writes to a slow database. The robust pattern is: verify the signature, store the event in a queue or table, return 200, then process it in a separate worker. A slow CRM then never causes failed deliveries.

  • Return 2xx only once the event is safely stored, not before.
  • Return 4xx or 5xx when something goes wrong, so the event is retried.
  • Do not rely on arrival order: with retries, an event can land after a later one. Sort by the event timestamp.
  • Watch the delivery log during the first days; the request and response of each attempt show where things break.

The phone system API: leads, contacts and click-to-call

In the other direction, your CRM uses the API to get the phone system to do things. Requests are authenticated with an API key sent as a Bearer token in the Authorization header. Create a separate key for each program that connects: if one leaks you revoke it without breaking the rest, and you can see when each key was last used.

Three uses come up again and again. First, loading leads: your web form or CRM adds the contact to a list and your calling campaigns pick it up straight away. Second, keeping contacts in sync: when a customer's number changes in the CRM, update it in the phone system too, so their calls are recognised. Third, click-to-call: a Call button in your CRM rings the agent's phone first and, once they answer, dials the customer.

APIs come with rate limits, for example 600 requests a minute per key, with paged lists of up to 1,000 items. For large syncs, spread requests over time and, when you hit a limit, wait before retrying rather than hammering the endpoint.

Setting up the integration step by step

Whether you write your own receiver or use an automation tool such as Zapier, Make or n8n, the sequence is the same. Automation tools hand you a ready-made URL, like Zapier's Catch Hook, and are a quick way to start; your own receiver pays off once volumes grow or the logic gets more involved.

  1. Define the goals

    Write down what should happen in the CRM and for which events, for example a task for every missed call in the support queue.

  2. Build the receiver

    An HTTPS endpoint that verifies the signature, stores the event and replies 200 within moments.

  3. Create the webhook

    Enter the URL, method and any headers, then choose the events and filter by queue, agent or number.

  4. Choose the payload

    The full event if the receiver is yours, custom fields if the destination expects a fixed format.

  5. Test with sample data

    Send a test request and check your system's response before switching it on.

  6. Go live and watch deliveries

    For the first few days, check the log for errors, response times and retries.

Common phone system CRM integration mistakes

The same problems show up in integration after integration. Knowing them up front saves days of debugging.

  • Doing all the work inside the webhook request, timing out and triggering a chain of retries.
  • Ignoring duplicates, so the CRM fills up with double tasks and notes.
  • Skipping signature checks because "nobody knows the URL anyway".
  • Returning 200 even when processing failed: the phone system marks the event delivered and never retries.
  • Matching phone numbers stored in different formats, so the caller is never found.
  • Sharing one API key between several programs.
  • Having nobody own the error emails, and noticing weeks later that the webhook is paused.

Frequently asked questions

How do I connect a VoIP phone system to a CRM?

Usually with two tools: webhooks, which let the phone system tell the CRM about events such as calls and outcomes, and an API, which lets the CRM load leads, update contacts or start calls. Some CRMs offer ready-made connectors; otherwise a small receiver or an automation tool does the job.

What is the difference between a webhook and an API?

A webhook is the phone system sending data to you when something happens. An API is your system asking the phone system for data, or telling it to act, whenever it wants. Use webhooks for real-time notifications and the API for actions.

How do I verify that a webhook is genuine?

Recompute the HMAC-SHA256 signature of the raw body with the shared secret, compare it with the one in the header, and check the timestamp is recent. If the signature does not match or the request is too old, reject it.

What happens if my server is down when an event fires?

The phone system retries at growing intervals, for example after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, and you can usually resend an event from the delivery log. That is why your receiver must ignore events it has already processed.

Can I connect my phone system to Zapier, Make or n8n?

Yes. Point a webhook at the URL the automation tool gives you and choose the events. With custom fields you send only the data you need, already named for the next steps.

What is click-to-call?

It is a button in your CRM that starts a call through the phone system's API. The agent's phone rings first and, once they answer, the customer is dialled, with no number typed by hand.

Try it on your own phone lines

Sign up free and put this guide into practice with your numbers, or message us on WhatsApp.