> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sayna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SIP call

> Initiates an outbound SIP call through LiveKit. The optional `sip` object in the request body allows overriding global SIP configuration on a per-request basis. Request body values take priority over global config, enabling different SIP providers or credentials for specific calls.

Initiate an outbound SIP call through LiveKit. The call is connected to the specified room as a SIP participant, enabling real-time voice interactions with external phone numbers.

<Note>
  Requires SIP configuration with an `outbound_address` and a valid SIP trunk. The room is created automatically if it doesn't exist, with `metadata.auth_id` set for tenant isolation.
</Note>

## Request fields

| Field                  | Type   | Required | Description                                                                                               |
| ---------------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------- |
| `room_name`            | string | Yes      | The LiveKit room to connect the call to.                                                                  |
| `participant_name`     | string | Yes      | Display name for the SIP participant in the room.                                                         |
| `participant_identity` | string | Yes      | Unique identity for the SIP participant.                                                                  |
| `from_phone_number`    | string | Yes      | Caller ID phone number (must be configured in your SIP provider).                                         |
| `to_phone_number`      | string | Yes      | Destination phone number to dial.                                                                         |
| `sip`                  | object | No       | Per-request SIP configuration overrides. See [SIP configuration overrides](#sip-configuration-overrides). |

## SIP configuration overrides

The optional `sip` object allows you to override global SIP configuration on a per-request basis. This is useful when you need to use different SIP providers or credentials for specific calls.

| Field              | Type         | Description                                                         |
| ------------------ | ------------ | ------------------------------------------------------------------- |
| `outbound_address` | string\|null | SIP server address override. Format: `hostname` or `hostname:port`. |
| `auth_username`    | string\|null | SIP authentication username override.                               |
| `auth_password`    | string\|null | SIP authentication password override.                               |

<Tip>
  Existing requests without the `sip` object continue to work unchanged. The global server configuration is used when per-request overrides are not provided.
</Tip>

## Configuration priority

When the `sip` object is provided, its fields take priority over global server configuration:

**Request body `sip` config > Global server config**

| Request Body Field     | Overrides Global Config      |
| ---------------------- | ---------------------------- |
| `sip.outbound_address` | `sip.outbound_address`       |
| `sip.auth_username`    | `sip.outbound_auth_username` |
| `sip.auth_password`    | `sip.outbound_auth_password` |

<Note>
  If neither the request body nor global config provides an `outbound_address`, the call will fail with an `OUTBOUND_ADDRESS_NOT_CONFIGURED` error.
</Note>

## Example requests

<CodeGroup>
  ```json Basic request theme={null}
  {
    "room_name": "call-room-123",
    "participant_name": "John Doe",
    "participant_identity": "caller-456",
    "from_phone_number": "+15105550123",
    "to_phone_number": "+15551234567"
  }
  ```

  ```json With SIP configuration overrides theme={null}
  {
    "room_name": "call-room-123",
    "participant_name": "John Doe",
    "participant_identity": "caller-456",
    "from_phone_number": "+15105550123",
    "to_phone_number": "+15551234567",
    "sip": {
      "outbound_address": "sip.provider.com:5060",
      "auth_username": "user123",
      "auth_password": "secret456"
    }
  }
  ```
</CodeGroup>

## Authorization

Access is controlled via room metadata:

* When `auth.id` is present and the room exists: requires `room.metadata.auth_id == auth.id`
* When `auth.id` is present and room doesn't exist: room is created with `metadata.auth_id` set
* When `auth.id` is absent: access is allowed (backward-compatible mode)

## Error responses

| Status                      | Condition                                                              |
| --------------------------- | ---------------------------------------------------------------------- |
| `400 Bad Request`           | Invalid phone number format or empty required fields.                  |
| `404 Not Found`             | Room exists with a different tenant's `auth_id` (masked as not found). |
| `500 Internal Server Error` | LiveKit not configured, outbound address missing, or call failed.      |

<Tip>
  Phone numbers support international format (`+1234567890`), national format (`07123456789`), or internal extensions (`1234`).
</Tip>


## OpenAPI

````yaml POST /sip/call
openapi: 3.1.0
info:
  title: Sayna API
  description: >-
    Real-time voice processing server with Speech-to-Text (STT) and
    Text-to-Speech (TTS) services
  contact:
    name: Sayna
    url: https://api.sayna.ai
  license:
    name: Apache-2.0
    identifier: Apache-2.0
  version: 0.1.0
servers:
  - url: https://api.sayna.ai
    description: Production API
  - url: http://localhost:3001
    description: Local development
security: []
tags:
  - name: health
    description: Health check endpoints
  - name: voices
    description: TTS voice management
  - name: tts
    description: Text-to-speech synthesis
  - name: livekit
    description: LiveKit room and token management
  - name: recordings
    description: Recording download operations
  - name: sip
    description: SIP webhook configuration management
  - name: websocket
    description: WebSocket API for real-time communication
paths:
  /sip/call:
    post:
      tags:
        - sip
      summary: Handler for POST /sip/call endpoint
      description: >-
        Initiates an outbound SIP call through LiveKit. The optional `sip`
        object in the request body allows overriding global SIP configuration on
        a per-request basis. Request body values take priority over global
        config, enabling different SIP providers or credentials for specific
        calls.
      operationId: sip_call
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SIPCallRequest'
        required: true
      responses:
        '200':
          description: Call initiated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SIPCallResponse'
        '400':
          description: Invalid request (bad phone number or empty fields)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SIPCallErrorResponse'
        '404':
          description: Room not found or not accessible
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SIPCallErrorResponse'
        '500':
          description: LiveKit not configured, outbound address missing, or call failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SIPCallErrorResponse'
      security:
        - auth: []
components:
  schemas:
    SIPCallRequest:
      type: object
      description: >-
        Request body for initiating an outbound SIP call


        # Example

        ```json

        {
          "room_name": "call-room-123",
          "participant_name": "John Doe",
          "participant_identity": "caller-456",
          "from_phone_number": "+15105550123",
          "to_phone_number": "+15551234567",
          "sip": {
            "outbound_address": "sip.provider.com",
            "auth_username": "user123",
            "auth_password": "secret"
          }
        }

        ```


        # SIP Configuration Priority


        The `sip` object is optional. When provided, its fields take priority
        over global

        server configuration values. This allows per-request customization of
        SIP settings.


        **Priority order**: Request body `sip` config > Global server config


        - `outbound_address`: Overrides `sip.outbound_address` from config

        - `auth_username`: Overrides `sip.outbound_auth_username` from config

        - `auth_password`: Overrides `sip.outbound_auth_password` from config


        If neither the request body nor global config provides an
        `outbound_address`,

        the call will fail with `OUTBOUND_ADDRESS_NOT_CONFIGURED` error.
      required:
        - room_name
        - participant_name
        - participant_identity
        - from_phone_number
        - to_phone_number
      properties:
        from_phone_number:
          type: string
          description: |-
            Phone number the call will originate from.
            Must be configured in your SIP provider.
            Supports international format (+1234567890).
          example: '+15105550123'
        participant_identity:
          type: string
          description: Identity for the SIP participant in the room
          example: caller-456
        participant_name:
          type: string
          description: Display name for the SIP participant in the room
          example: John Doe
        room_name:
          type: string
          description: The LiveKit room name to connect the call to
          example: call-room-123
        sip:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/SIPCallSipConfig'
              description: >-
                Optional per-request SIP configuration overrides.

                When provided, these values take priority over the global server
                configuration.

                This allows using different SIP providers or credentials for
                specific calls.
        to_phone_number:
          type: string
          description: >-
            Phone number to dial.

            Supports international format (+1234567890), national format
            (07123456789),

            or extensions (1234).
          example: '+15551234567'
    SIPCallResponse:
      type: object
      description: |-
        Response for a successful SIP call initiation

        # Example
        ```json
        {
          "status": "initiated",
          "room_name": "call-room-123",
          "participant_identity": "caller-456",
          "participant_id": "PA_abc123",
          "sip_call_id": "SC_xyz789"
        }
        ```
      required:
        - status
        - room_name
        - participant_identity
        - participant_id
        - sip_call_id
      properties:
        participant_id:
          type: string
          description: The unique participant ID assigned by LiveKit
          example: PA_abc123
        participant_identity:
          type: string
          description: The identity of the SIP participant in the room
          example: caller-456
        room_name:
          type: string
          description: The room name where the call was connected
          example: call-room-123
        sip_call_id:
          type: string
          description: The unique SIP call ID for tracking
          example: SC_xyz789
        status:
          type: string
          description: Status of the call request ("initiated")
          example: initiated
    SIPCallErrorResponse:
      type: object
      description: |-
        Error response for SIP call failures

        # Example
        ```json
        {
          "error": "Outbound address not configured",
          "code": "OUTBOUND_ADDRESS_NOT_CONFIGURED"
        }
        ```
      required:
        - error
        - code
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: OUTBOUND_ADDRESS_NOT_CONFIGURED
        error:
          type: string
          description: Human-readable error message
          example: Outbound address not configured
    SIPCallSipConfig:
      type: object
      description: >-
        Per-request SIP configuration overrides


        Allows overriding the global SIP configuration on a per-request basis.

        When specified, these values take priority over the global server
        configuration.


        # Priority

        Request body values > Global config values


        # Example

        ```json

        {
          "outbound_address": "sip.example.com:5060",
          "auth_username": "user123",
          "auth_password": "secret456"
        }

        ```
      properties:
        auth_password:
          type:
            - string
            - 'null'
          description: >-
            SIP authentication password override.

            When provided, overrides the global `sip.outbound_auth_password`
            config.
          example: secure_password_456
        auth_username:
          type:
            - string
            - 'null'
          description: >-
            SIP authentication username override.

            When provided, overrides the global `sip.outbound_auth_username`
            config.
          example: sip_user_123
        outbound_address:
          type:
            - string
            - 'null'
          description: >-
            SIP server address override for outbound calls.

            When provided, overrides the global `sip.outbound_address` config.

            Format: hostname or hostname:port (e.g., "sip.example.com" or
            "sip.example.com:5060")
          example: sip.provider.com:5060
  securitySchemes:
    auth:
      type: http
      scheme: bearer
      bearerFormat: Token
      description: >-
        Authentication token for protected endpoints. Can be provided as
        `Authorization: Bearer <token>` or `?api_key=<token>`. Required when
        AUTH_REQUIRED is enabled.

````