Skip to navigation

onCallStart

View as MarkdownOpen in Claude

Register a handler that runs when the call starts, before the AI speaks. It’s the counterpart of onCallEnd(). Handlers run in registration order.

The SDK registers the platform’s reserved startup_hook function for you. The platform calls it once, after the call is answered and before the AI’s first turn, and never offers it to the model.

A handler may return a FunctionResult, or nothing:

  • The result’s actions run at once, in registration order across handlers. Use updateGlobalData(), for example, to give the call data before the conversation starts.
  • The result’s response text is added to the conversation as a system message the model reads before its first turn. The texts of several handlers are joined, one per line. Only a plain string response is used, and OpenAI Realtime agents run the actions without adding the text.

postProcess isn’t used. A hook whose handlers return no text still adds a short placeholder line to the conversation, as any function with an empty reply does. An exception is logged, not raised, and that handler’s result is dropped, so a failing handler can’t stop the call from starting or the other handlers from running.

Slow handlers delay the greeting

The platform waits for the hook before the AI starts, up to 120 seconds, and sends the request again after a timeout or a 5xx. Keep handlers short and safe to run twice. Start long work without awaiting it, and send its result into the call later with calling.aiMessage() on the REST client.

Parameters

handler
(rawData: SwaigRequest) => FunctionResult | null | undefined | void | Promise<FunctionResult | null | undefined | void>Required

Called as handler(rawData) with the complete SWAIG request: call_id, global_data, and the caller’s details. May be async.

Returns

The handler, unchanged.

Example

import { AgentBase, FunctionResult } from '@signalwire/sdk';
const agent = new AgentBase({ name: 'dispatch', route: '/dispatch' });
agent.setPromptText('You are Ada, the dispatcher for Bayview Taxi.');
agent.onCallStart(async (rawData) => {
const caller = String(rawData.caller_id_num ?? '');
// Look the caller up in your system of record.
const rider = { id: 'rider-1042', name: 'Sam' };
return new FunctionResult(`The caller ${caller} is ${rider.name}, a returning rider.`)
.updateGlobalData({ rider_id: rider.id });
});
await agent.serve();