Voice hooks

The headless layer behind the voice components: voicemail lists, call history, click-to-call, and transcripts.

useVoicemails

const { voicemails, refreshVoicemail, hasMore, loadMore } = useVoicemails();

Newest first, polled every 15s by default. refreshVoicemail(id) re-fetches one voicemail — the fix for expired hour-limited audio URLs.

useCalls

const { calls, hasMore, loadMore } = useCalls({ phoneNumberId });

Call history, newest first, polled every 10s. Filter by tenant or one phone number.

useClickToCall

const { call, isActive, place, reset } = useClickToCall({
  onStatusChange: (call) => console.log(call.status),
});

await place({
  from: "num_…",              // caller ID
  to: "+14155550132",         // customer
  connectTo: "+14155550199",  // agent's phone rings first
  transcribe: true,
});

One POST, then automatic status polling until the call settles (completed, missed, voicemail, or failed). isActive is true from dialing through hang-up; reset() clears the finished call.

useCallTranscript

// Finished call:
const { transcript, isEmpty } = useCallTranscript(callId);

// Live call:
const live = useCallTranscript(activeCall.id, { pollMs: 2000 });
Return value
PropTypeDefaultDescription
transcriptCallTranscript | nullcall_id, joined text, and speaker-labeled segments.
isEmptybooleanTrue when the call has no transcript (404s handled for you).
isLoadingbooleanTrue until the first fetch resolves.
errorError | nullNon-404 fetch failures.
refresh() => Promise<void>Force an immediate re-fetch.