Skip to content

Event Types

Complete reference for all events in the SDK.

Overview

Events are triggered by the AI Flow service and handled by your assistant. All events include session information and are typed with TypeScript.

Base Event Structure

All events extend a base structure with session information:

typescript
interface SessionInfo {
  id: string;              // UUID of the session
  account_id: string;      // Account identifier
  phone_number: string;    // Phone number for this flow session
  direction?: "inbound" | "outbound";
  from_phone_number: string;
  to_phone_number: string;
}

Event Types

SessionStart Event

Triggered when a new call session begins.

typescript
interface AiFlowEventSessionStart {
  type: "session_start";
  session: {
    id: string; // UUID of the session
    account_id: string; // Account identifier
    phone_number: string; // Phone number for this flow session
    direction?: "inbound" | "outbound"; // Call direction
    from_phone_number: string; // Phone number of the caller
    to_phone_number: string; // Phone number of the callee
  };
}

Example:

typescript
onSessionStart: async (event) => {
  // Log session details
  console.log(
    `${event.session.direction} call from ${event.session.from_phone_number} to ${event.session.to_phone_number}`
  );

  // Return greeting
  return "Welcome to our service!";
};

UserSpeak Event

Triggered when the user speaks and speech-to-text completes.

typescript
interface AiFlowEventUserSpeak {
  type: "user_speak";
  text: string; // Recognized speech text
  session: SessionInfo;
}

Example:

typescript
onUserSpeak: async (event) => {
  const intent = analyzeIntent(event.text);

  if (intent === "help") {
    return "I can help you with billing, support, or sales.";
  }

  return processUserInput(event.text);
};

AssistantSpeak Event

Triggered after the assistant starts speaking. Event may be omitted for some text-to-speech models.

typescript
interface AiFlowEventAssistantSpeak {
  type: "assistant_speak";
  text?: string; // Text that was spoken
  ssml?: string; // SSML that was used (if applicable)
  duration_ms: number; // Duration of speech in milliseconds
  speech_started_at: number; // Unix timestamp (ms) when speech started
  session: SessionInfo;
}

Example:

typescript
onAssistantSpeak: async (event) => {
  console.log(`Spoke for ${event.duration_ms}ms`);

  // Track conversation metrics
  trackMetrics({
    sessionId: event.session.id,
    duration: event.duration_ms,
    text: event.text,
  });
};

AssistantSpeechEnded Event

Triggered after the assistant finishes speaking.

typescript
interface AiFlowEventAssistantSpeechEnded {
  type: "assistant_speech_ended";
  session: SessionInfo;
}

Example:

typescript
onAssistantSpeechEnded: async (event) => {
  console.log(`Finished speaking for session ${event.session.id}`);

  // Trigger next action if needed
  await triggerNextAction(event.session.id);
};

UserInputTimeout Event

Triggered when no user speech is detected within the configured timeout period after the assistant finishes speaking.

typescript
interface AiFlowEventUserInputTimeout {
  type: "user_input_timeout";
  session: SessionInfo;
}

When Triggered:

  1. A speak action includes a user_input_timeout_seconds field
  2. The assistant finishes speaking (assistant_speech_ended event fires)
  3. The specified timeout period elapses without any user speech detected

Example:

typescript
onUserInputTimeout: async (event) => {
  console.log(`No user input received for session ${event.session.id}`);

  // Retry the question
  return {
    type: "speak",
    session_id: event.session.id,
    text: "Are you still there? Please say yes or no.",
    user_input_timeout_seconds: 5
  };
};

Configuring Timeout:

Set user_input_timeout_seconds in the speak action:

typescript
onSessionStart: async (event) => {
  return {
    type: "speak",
    session_id: event.session.id,
    text: "What is your account number?",
    user_input_timeout_seconds: 5  // Wait 5 seconds for response
  };
};

Common Use Cases:

typescript
// Hangup after multiple timeouts
const timeoutCounts = new Map<string, number>();

onUserInputTimeout: async (event) => {
  const sessionId = event.session.id;
  const count = (timeoutCounts.get(sessionId) || 0) + 1;
  timeoutCounts.set(sessionId, count);

  if (count >= 3) {
    return {
      type: "hangup",
      session_id: sessionId
    };
  }

  return {
    type: "speak",
    session_id: sessionId,
    text: `I didn't hear anything. Please respond. Attempt ${count} of 3.`,
    user_input_timeout_seconds: 5
  };
};

// Transfer to agent after timeout
onUserInputTimeout: async (event) => {
  return {
    type: "speak",
    session_id: event.session.id,
    text: "Let me connect you with a live agent who can help you."
    // Follow with transfer action
  };
};

SessionEnd Event

Triggered when the call session ends.

typescript
interface AiFlowEventSessionEnd {
  type: "session_end";
  session: SessionInfo;
}

Example:

typescript
onSessionEnd: async (event) => {
  // Save conversation history
  await saveConversation(event.session.id);

  // Send analytics
  await trackSessionEnd(event.session);
};

Barge-In Detection

User interruptions are detected via the barged_in flag in user_speak events:

typescript
interface AiFlowEventUserSpeak {
  type: "user_speak";
  text: string;
  barged_in?: boolean; // true if user interrupted
  session: SessionInfo;
}

Example:

typescript
onUserBargeIn: async (event) => {
  // Called automatically when event.barged_in === true
  console.log(`User interrupted with: ${event.text}`);
  return "I'm listening, please continue.";
};

Event Flow

┌─────────────────┐
│  session_start  │──> Respond with speak/audio or do nothing
└─────────────────┘

┌─────────────────┐
│   user_speak    │──> Respond with speak/audio/transfer/hangup
│  (barged_in?)   │    Check barged_in flag for interruptions
└─────────────────┘

┌─────────────────┐
│ assistant_speak │──> Optional: track metrics, trigger next action
└─────────────────┘

┌─────────────────┐
│   session_end   │──> Cleanup only, no actions accepted
└─────────────────┘

Event Summary Table

Event TypeDescriptionWhen TriggeredCan Return Action?
session_startCall session beginsWhen a new call is initiated✅ Yes
user_speakUser speech detectedAfter speech-to-text completes (includes barged_in flag)✅ Yes
assistant_speakAssistant finished speakingAfter TTS playback completes✅ Yes
assistant_speech_endedAssistant finished speakingAfter speech playback ends✅ Yes
user_input_timeoutUser input timeout reachedWhen no speech detected after timeout✅ Yes
session_endCall session endsWhen the call terminates❌ No

Type Safety

All events are fully typed. Import types from the SDK:

typescript
import type {
  AiFlowEventSessionStart,
  AiFlowEventUserSpeak,
  AiFlowEventAssistantSpeak,
  AiFlowEventAssistantSpeechEnded,
  AiFlowEventUserInputTimeout,
  AiFlowEventSessionEnd,
  AiFlowEventUserBargeIn,
} from "@sipgate/ai-flow-sdk";

onSessionStart: async (event: AiFlowEventSessionStart) => {
  // event is fully typed
  const sessionId: string = event.session.id;
  // ...
};

Next Steps