> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.telekesher.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.telekesher.dev/_mcp/server.

# Session

A `Session` is the addressable unit of a voice interaction: one phone call or
standalone WebSocket audio endpoint that your application can inspect and
control. SIP and WebRTC participants are planned for a future release. A
[Room](/api/rooms) connects multiple Sessions into a shared conversation,
while playback, DTMF collection, recording, and WebSocket audio operate on an
individual Session.

## How Sessions are created

Sessions enter your application in several ways:

| Origin                                                                               | Session `type`    | What your application receives                                                                                                                         |
| ------------------------------------------------------------------------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| An incoming phone call                                                               | `phone_in`        | The platform creates the Session and sends a [`call.created`](/webhooks/call-events#callcreated) webhook. Your application can then answer or end it.  |
| [`POST /sessions:dial`](api:voice-api:POST/v1/sessions:dial)                         | `phone_out`       | The API immediately returns a `session_uuid`; ringing, answer, and termination progress arrives through call webhooks.                                 |
| [`POST /sessions:connectWebsocket`](api:voice-api:POST/v1/sessions:connectWebsocket) | `websocket`       | The API creates a media-only Session with no phone leg. It begins in `connecting` and becomes `answered` when the WebSocket connection is established. |
| A configured SIP or WebRTC connection *(Future)*                                     | `sip` or `webrtc` | In a future release, the Session will represent that connected voice participant and use the same Session APIs.                                        |

The lifecycle field depends on the endpoint: each item returned by
[`GET /sessions`](api:voice-api:GET/v1/sessions) uses `state`, while
[`GET /sessions/{session_uuid}`](api:voice-api:GET/v1/sessions/\{session_uuid})
uses `status`. Both use the same values: `new`, `connecting`, `ringing`,
`early_media`, `answered`, or `ended`. Treat either as a point-in-time
snapshot for inspection and reconciliation. Webhooks are the asynchronous
event stream for reacting to lifecycle changes as they happen. Every Session
finishes with exactly one terminal
[`call.ended`](/webhooks/call-events#callended) webhook, whether it was
answered, rejected, timed out, disconnected, or explicitly deleted.

## What you can do with a Session

Use the `session_uuid` to:

* inspect one Session or list the Sessions owned by your application;
* answer an incoming call or request termination;
* play audio and collect DTMF digits;
* start and control a Session recording;
* attach a bidirectional WebSocket audio relay; and
* add the Session to a Room, then control its membership there.

Most control commands are asynchronous. An accepted command returns
`202 Accepted` with an `operation_uuid`; the command's reference identifies the
webhook that confirms completion or reports the resulting lifecycle change.

## Methods

* [Originate an outbound call](api:voice-api:POST/v1/sessions:dial)
* [Create a standalone WebSocket session](api:voice-api:POST/v1/sessions:connectWebsocket)
* [List sessions](api:voice-api:GET/v1/sessions)
* [Get session details](api:voice-api:GET/v1/sessions/\{uuid})
* [Answer an incoming session](api:voice-api:POST/v1/sessions/\{uuid}/answer)
* [Delete a session](api:voice-api:DELETE/v1/sessions/\{uuid})

Session lifecycle, Playback, DTMF, and WebSocket commands operate on a session by
placing its `session_uuid` in the `{uuid}` path parameter. Recording commands
create and control a [Recording](/api/recording) owned by that Session.

## Resource representation

### The Session resource

```json
{
  "caller_id": "string",
  "created_at": "2023-01-01T00:00:00Z",
  "did": "string",
  "session_uuid": "string",
  "state": "new",
  "type": "phone_in"
}
```

## Properties

### Schema (`Session`)

```yaml
components:
  schemas:
    SessionState:
      type: string
      enum:
        - new
        - connecting
        - ringing
        - early_media
        - answered
        - ended
      description: |-
        Current lifecycle state of the session. `connecting` applies to a
        `websocket` session whose backend WebSocket has not yet connected.
      title: SessionState
    SessionType:
      type: string
      enum:
        - phone_in
        - phone_out
        - sip
        - webrtc
        - websocket
        - unknown
      description: |-
        The nature of the session:
        - `phone_in`: inbound phone call from a carrier
        - `phone_out`: outbound phone call placed with `dial`
        - `sip`: a registered SIP device
        - `webrtc`: a WebRTC client
        - `websocket`: a standalone WebSocket session with no phone leg
        - `unknown`: could not be determined
      title: SessionType
    Session:
      type: object
      properties:
        caller_id:
          type: string
          description: >-
            Caller ID in canonical international E.164 format with leading `+`

            (e.g. `+972527121102`). Empty for `websocket` sessions (no phone
            leg).
        created_at:
          type: string
          format: date-time
          description: |-
            When the session was created, as an RFC 3339 / ISO 8601 UTC string
            (e.g. "2025-05-06T12:41:36.000Z"). Storage resolution is one second,
            so the millisecond fraction is always `.000`. Empty string if the
            originating timestamp is missing or unparseable.
        did:
          type: string
          description: >-
            Called DID in canonical E.164 format with leading `+` (e.g.
            `+972747713001`).

            Empty for `websocket` sessions (no phone leg).
        session_uuid:
          type: string
          description: Opaque session identifier. Return it to the API exactly as received.
        state:
          $ref: '#/components/schemas/SessionState'
          description: |-
            Current lifecycle state of the session. `connecting` applies to a
            `websocket` session whose backend WebSocket has not yet connected.
        type:
          $ref: '#/components/schemas/SessionType'
          description: |-
            The nature of the session:
            - `phone_in`: inbound phone call from a carrier
            - `phone_out`: outbound phone call placed with `dial`
            - `sip`: a registered SIP device
            - `webrtc`: a WebRTC client
            - `websocket`: a standalone WebSocket session with no phone leg
            - `unknown`: could not be determined
      required:
        - created_at
        - session_uuid
        - state
        - type
      title: Session
```