Skip to main content

Example: third-party application integration

This page describes a high-level pattern, not a line-by-line tutorial. It shows how a third-party application — a CRM, a quality-assurance dashboard, an eDiscovery or surveillance platform — can surface Focus recordings, transcripts and media to its own users, on demand.

The goal here is to help you decide how the pieces fit together before you write any code. For exact request and response schemas, follow the links into the endpoint reference, and for the end-to-end narrative flow see the Native Focus REST API guide.

When to use this pattern

Use an on-demand integration when your users want Focus data in context inside another tool — for example, seeing the calls linked to a customer while looking at that customer's CRM record. If instead you want to pull a complete copy of all communications into your own store, use the local synchronisation example instead.

The shape of the integration

The typical design is a small server-side service that sits between your application and Focus. It never exposes your API key to the browser, and it translates your application's questions ("what calls involve this person?") into Focus API calls.

Your app UI ──► Your integration service ──► Focus API
(browser) (holds the API key, (public,
caches the token) read-only)

At a high level the service does three things:

  1. Authenticates and holds a token. On startup, or when the current token expires, call POST /authWithApiKey to exchange your API key for a short-lived bearer JWT. Cache the token in memory and reuse it across requests rather than authenticating on every call.
  2. Answers queries on demand. When a user opens a screen in your application, call the relevant search endpoint — for example POST /client/recording.search filtered by a person, endpoint or date range — and show the results.
  3. Fetches detail lazily. Only retrieve heavy content when the user actually asks for it. Pull the transcript with POST /client/recording.transcription.get when a recording is opened, and stream the audio with POST /client/recording.playBackByThirdPartyId only when the user presses play.

A worked scenario

Imagine a CRM that wants to show a "Recent conversations" panel on each customer record.

  • When the panel loads, your service looks up the customer's identifiers (phone number, email, Teams id) and calls POST /client/people/endpoint/search to resolve them to a Focus person, then POST /client/recording.search to list that person's recent recordings.
  • The panel renders each result using the lightweight fields already returned by the search — start time, duration, type, and the transcript snippet.
  • When an agent clicks a conversation, your service calls POST /client/recording.detail.get and the transcription endpoint to show the full record, and offers a play button that streams the audio on demand.

Because the search response already carries a useful summary, most screens need only one call to render, and the expensive operations happen only when a user drills in.

Practical guidance

  • Cache the token, not the data. Reuse the bearer JWT until it is close to expiry, then re-authenticate. Avoid storing recording content in your application unless you have a clear reason to — this pattern is designed to read live from Focus.
  • Respect roles and rights. Your integration user only sees what its assigned roles and rights allow. A call may return 403 if the user lacks a right such as Recording.Play; handle that gracefully in the UI.
  • Handle pagination. Search endpoints are paginated. Request a sensible page size and page through results rather than asking for everything at once.
  • Stay within rate limits. On-demand calls are naturally bursty. Debounce user-driven searches and avoid re-querying on every keystroke.
Docs AssistantAsk anything about our products