All work
Open source · Telephony integration

cti-kit

Open-source CTI integrations for Exotel and Ozonetel

A public, MIT-licensed reference implementation of the two integrations every cloud-telephony deployment needs and few build well: the application behind an Exotel Passthru applet, which decides how a live call routes, and the endpoint behind an Ozonetel Screen Pop URL, which shows an agent who is calling. Both sit on one vendor-neutral core, with zero runtime dependencies.

Year 2026Status BuildingVisit live site

The challenge

Neither API is difficult. Exotel’s Passthru contract is “we GET your URL, you return 200 or non-200”; Ozonetel appends query parameters to a URL and renders whatever HTML comes back. A competent engineer builds a working version of either in a day. What takes longer is learning which failure modes matter — and in telephony they matter immediately, because the customer is already on the line while the integration decides what to do with them.

What we did

  • Made every path fail open. In Exotel’s Sync mode the HTTP status code *is* the routing decision, which means an unhandled exception is not an error — it is a silent, invisible reroute that never appears in an error tracker and surfaces weeks later as “sometimes customers reach the wrong team”. Every path terminates in a deliberate choice instead.
  • Treated a slow CRM as a broken CRM. Agents notice a screen pop beyond roughly 400ms, so lookups race a hard latency budget and the dependency is abandoned on overrun. Measured against a 600ms CRM, the service returns in ~400ms rather than waiting.
  • Made the degraded state useful rather than blank. When a lookup fails the agent is already talking to a human being, so the panel still renders the caller’s number and a support reference — the two things they can actually act on — instead of a spinner.
  • Separated the core from the vendors strictly: the core may not name a telephony platform, and the platform adapters may not talk to a CRM. Adding a platform is one adapter; adding a CRM is one interface. That separation is why the second integration costs a fraction of the first.
  • Documented what is *not* verified. The published status table lists the four assumptions still taken from vendor documentation rather than confirmed against a live account, because being precise about the gap is worth more than implying full coverage.

Tech & scope

TypeScriptNode 22+Zero runtime dependenciesnode:testMIT licensed

The outcome

  • Published publicly with 35 unit tests and a 15-assertion end-to-end smoke suite, runnable from a clean clone with no install step.
  • A reusable CRM adapter interface that turns each additional connector into a single file rather than a fresh project.
  • A worked reference for the failure modes — fail-open routing, latency budgets, degraded rendering — that decide whether a telephony integration survives contact with production.

Building something like cti-kit?

Tell us what you are trying to ship. You will get an honest review, a clear plan and a fixed, affordable quote, usually within a day.