Layercode · AsyncAPI Specification

Layercode Realtime Voice WebSocket API

Version 1.0.0

AsyncAPI 2.6 description of Layercode's **realtime voice transport**, a genuine bidirectional WebSocket documented at https://docs.layercode.com/api-reference/frontend-ws-api. Unlike one-way HTTP SSE, this is a true full-duplex WebSocket. The browser opens the connection at `wss://api.layercode.com/v1/agents/web/websocket?client_session_key=...` using a short-lived `client_session_key` obtained from the REST endpoint `POST /v1/agents/web/authorize_session` (modeled in `openapi/layercode-openapi.yml`). Over the socket the client streams base64-encoded 16-bit PCM microphone audio (8000 Hz, mono) to Layercode, and Layercode streams back synthesized speech (base64 16-bit PCM, 16000 Hz, mono), interim and final transcripts, streamed assistant text, and structured data, organized into user and assistant turns identified by `turn_id`. The companion webhook surface - where Layercode POSTs transcript events to your backend and your backend streams response.tts / response.data / response.end events back as Server-Sent Events - is documented at https://docs.layercode.com/api-reference/webhook-sse-api and summarized in `info.x-webhook-notes` below; it is a separate HTTP+SSE channel and is not modeled as WebSocket here.

View Spec View on GitHub AIVoiceVoice AgentsRealtimeLow LatencyAsyncAPIWebhooksEvents

Channels

/v1/agents/web/websocket
publish clientToServer
Messages the client sends to Layercode.
Realtime voice channel. Opened by the browser with `?client_session_key=...`. Both directions exchange JSON text frames; all audio payloads are carried as base64 strings inside JSON messages.

Messages

ClientReady
Client ready
Signals the client is connected and ready to stream.
ClientAudio
Client audio chunk
A chunk of microphone audio from the browser.
TriggerTurnStart
Turn start trigger (push-to-talk)
TriggerTurnEnd
Turn end trigger (push-to-talk)
TriggerAudioReplayFinished
Audio replay finished
Client finished playing back a response audio turn.
ClientResponseText
Client text message
A typed text message from the user.
ClientResponseData
Client structured data
Arbitrary structured JSON emitted by the client UI.
TurnStart
Turn start
ResponseAudio
Response audio chunk
Synthesized speech audio from Layercode.
ResponseTextDelta
Response text delta
ResponseText
Response text (complete)
UserTranscriptInterimDelta
Interim transcript delta
UserTranscriptDelta
Final transcript delta
UserTranscript
Complete turn transcript
ResponseData
Response structured data
Structured JSON pushed to the client without audio.

Servers

wss
layercode api.layercode.com/v1/agents/web/websocket
Layercode realtime voice WebSocket. The browser connects with a short-lived client_session_key query parameter. The connection is full-duplex: the client publishes microphone audio and control messages, and the server publishes audio, transcripts, text, and data events.

AsyncAPI Specification

Raw ↑
asyncapi: '2.6.0'
id: 'urn:com:layercode:agents:web:websocket'
info:
  title: Layercode Realtime Voice WebSocket API
  version: '1.0.0'
  description: |
    AsyncAPI 2.6 description of Layercode's **realtime voice transport**, a
    genuine bidirectional WebSocket documented at
    https://docs.layercode.com/api-reference/frontend-ws-api.

    Unlike one-way HTTP SSE, this is a true full-duplex WebSocket. The browser
    opens the connection at
    `wss://api.layercode.com/v1/agents/web/websocket?client_session_key=...`
    using a short-lived `client_session_key` obtained from the REST endpoint
    `POST /v1/agents/web/authorize_session` (modeled in
    `openapi/layercode-openapi.yml`).

    Over the socket the client streams base64-encoded 16-bit PCM microphone
    audio (8000 Hz, mono) to Layercode, and Layercode streams back synthesized
    speech (base64 16-bit PCM, 16000 Hz, mono), interim and final transcripts,
    streamed assistant text, and structured data, organized into user and
    assistant turns identified by `turn_id`.

    The companion webhook surface - where Layercode POSTs transcript events to
    your backend and your backend streams response.tts / response.data /
    response.end events back as Server-Sent Events - is documented at
    https://docs.layercode.com/api-reference/webhook-sse-api and summarized in
    `info.x-webhook-notes` below; it is a separate HTTP+SSE channel and is not
    modeled as WebSocket here.
  contact:
    name: API Evangelist
    email: kin@apievangelist.com
    url: https://apievangelist.com
  license:
    name: API documentation - Layercode Terms
    url: https://layercode.com/terms
  x-transport-notes:
    transport: WebSocket
    protocol: wss
    direction: bidirectional (full-duplex)
    url: 'wss://api.layercode.com/v1/agents/web/websocket'
    authorizedBy: 'client_session_key query parameter from POST /v1/agents/web/authorize_session'
    clientAudio: base64 16-bit PCM, 8000 Hz, mono
    serverAudio: base64 16-bit PCM, 16000 Hz, mono
    source: https://docs.layercode.com/api-reference/frontend-ws-api
  x-webhook-notes:
    transport: HTTP Server-Sent Events (SSE)
    direction: 'Layercode POSTs JSON events to your backend webhook; backend streams SSE back'
    requestEvents: [session.start, message, data, session.update, session.end]
    responseEvents: [response.tts, response.data, response.end, response.hangup]
    signatureHeader: layercode-signature
    source: https://docs.layercode.com/api-reference/webhook-sse-api
defaultContentType: application/json
servers:
  layercode:
    url: api.layercode.com/v1/agents/web/websocket
    protocol: wss
    description: |
      Layercode realtime voice WebSocket. The browser connects with a
      short-lived client_session_key query parameter. The connection is
      full-duplex: the client publishes microphone audio and control messages,
      and the server publishes audio, transcripts, text, and data events.
channels:
  /v1/agents/web/websocket:
    description: |
      Realtime voice channel. Opened by the browser with
      `?client_session_key=...`. Both directions exchange JSON text frames; all
      audio payloads are carried as base64 strings inside JSON messages.
    bindings:
      ws:
        query:
          type: object
          properties:
            client_session_key:
              type: string
              description: Short-lived session key from authorize_session.
          required:
            - client_session_key
    publish:
      operationId: clientToServer
      summary: Messages the client sends to Layercode.
      message:
        oneOf:
          - $ref: '#/components/messages/ClientReady'
          - $ref: '#/components/messages/ClientAudio'
          - $ref: '#/components/messages/TriggerTurnStart'
          - $ref: '#/components/messages/TriggerTurnEnd'
          - $ref: '#/components/messages/TriggerAudioReplayFinished'
          - $ref: '#/components/messages/ClientResponseText'
          - $ref: '#/components/messages/ClientResponseData'
    subscribe:
      operationId: serverToClient
      summary: Messages Layercode sends to the client.
      message:
        oneOf:
          - $ref: '#/components/messages/TurnStart'
          - $ref: '#/components/messages/ResponseAudio'
          - $ref: '#/components/messages/ResponseTextDelta'
          - $ref: '#/components/messages/ResponseText'
          - $ref: '#/components/messages/UserTranscriptInterimDelta'
          - $ref: '#/components/messages/UserTranscriptDelta'
          - $ref: '#/components/messages/UserTranscript'
          - $ref: '#/components/messages/ResponseData'
components:
  messages:
    ClientReady:
      name: client.ready
      title: Client ready
      summary: Signals the client is connected and ready to stream.
      payload:
        type: object
        properties:
          type:
            type: string
            const: client.ready
    ClientAudio:
      name: client.audio
      title: Client audio chunk
      summary: A chunk of microphone audio from the browser.
      payload:
        type: object
        properties:
          type:
            type: string
            const: client.audio
          content:
            type: string
            description: Base64-encoded 16-bit PCM audio, 8000 Hz, mono.
    TriggerTurnStart:
      name: trigger.turn.start
      title: Turn start trigger (push-to-talk)
      payload:
        type: object
        properties:
          type:
            type: string
            const: trigger.turn.start
          role:
            type: string
            const: user
    TriggerTurnEnd:
      name: trigger.turn.end
      title: Turn end trigger (push-to-talk)
      payload:
        type: object
        properties:
          type:
            type: string
            const: trigger.turn.end
          role:
            type: string
            const: user
    TriggerAudioReplayFinished:
      name: trigger.response.audio.replay_finished
      title: Audio replay finished
      summary: Client finished playing back a response audio turn.
      payload:
        type: object
        properties:
          type:
            type: string
            const: trigger.response.audio.replay_finished
          reason:
            type: string
          turn_id:
            type: string
            format: uuid
    ClientResponseText:
      name: client.response.text
      title: Client text message
      summary: A typed text message from the user.
      payload:
        type: object
        properties:
          type:
            type: string
            const: client.response.text
          content:
            type: string
    ClientResponseData:
      name: client.response.data
      title: Client structured data
      summary: Arbitrary structured JSON emitted by the client UI.
      payload:
        type: object
        properties:
          type:
            type: string
            const: client.response.data
          data:
            type: object
            additionalProperties: true
    TurnStart:
      name: turn.start
      title: Turn start
      payload:
        type: object
        properties:
          type:
            type: string
            const: turn.start
          role:
            type: string
            enum:
              - user
              - assistant
          turn_id:
            type: string
            format: uuid
    ResponseAudio:
      name: response.audio
      title: Response audio chunk
      summary: Synthesized speech audio from Layercode.
      payload:
        type: object
        properties:
          type:
            type: string
            const: response.audio
          content:
            type: string
            description: Base64-encoded 16-bit PCM audio, 16000 Hz, mono.
          delta_id:
            type: string
            format: uuid
          turn_id:
            type: string
            format: uuid
    ResponseTextDelta:
      name: response.text.delta
      title: Response text delta
      payload:
        type: object
        properties:
          type:
            type: string
            const: response.text.delta
          content:
            type: string
          turn_id:
            type: string
            format: uuid
    ResponseText:
      name: response.text
      title: Response text (complete)
      payload:
        type: object
        properties:
          type:
            type: string
            const: response.text
          content:
            type: string
          turn_id:
            type: string
            format: uuid
    UserTranscriptInterimDelta:
      name: user.transcript.interim_delta
      title: Interim transcript delta
      payload:
        type: object
        properties:
          type:
            type: string
            const: user.transcript.interim_delta
          content:
            type: string
          turn_id:
            type: string
            format: uuid
    UserTranscriptDelta:
      name: user.transcript.delta
      title: Final transcript delta
      payload:
        type: object
        properties:
          type:
            type: string
            const: user.transcript.delta
          content:
            type: string
          turn_id:
            type: string
            format: uuid
    UserTranscript:
      name: user.transcript
      title: Complete turn transcript
      payload:
        type: object
        properties:
          type:
            type: string
            const: user.transcript
          content:
            type: string
          turn_id:
            type: string
            format: uuid
    ResponseData:
      name: response.data
      title: Response structured data
      summary: Structured JSON pushed to the client without audio.
      payload:
        type: object
        properties:
          type:
            type: string
            const: response.data
          content:
            type: object
            additionalProperties: true
          turn_id:
            type: string
            format: uuid