{
  "asyncapi": "3.1.0",
  "info": {
    "title": "Converse Realtime API",
    "version": "1.0.0",
    "description": "Full-duplex voice conversations over one WebSocket. Send a JSON start frame first, then binary microphone audio and JSON controls. Authenticate with api_key in the start frame or an Authorization: Bearer header on the WebSocket handshake."
  },
  "servers": {
    "production": {
      "host": "converse.trelis.com",
      "protocol": "wss",
      "description": "Production realtime endpoint. A bearer handshake header may carry the API key instead of the start frame.",
      "security": [
        {
          "$ref": "#/components/securitySchemes/bearerAuth"
        }
      ]
    }
  },
  "channels": {
    "conversation": {
      "address": "/ws",
      "messages": {
        "start": {
          "$ref": "#/components/messages/start"
        },
        "reset": {
          "$ref": "#/components/messages/reset"
        },
        "setVoice": {
          "$ref": "#/components/messages/setVoice"
        },
        "toolResult": {
          "$ref": "#/components/messages/toolResult"
        },
        "toolProgress": {
          "$ref": "#/components/messages/toolProgress"
        },
        "toolCancelClient": {
          "$ref": "#/components/messages/toolCancelClient"
        },
        "playbackStopped": {
          "$ref": "#/components/messages/playbackStopped"
        },
        "microphoneAudio": {
          "$ref": "#/components/messages/microphoneAudio"
        },
        "ready": {
          "$ref": "#/components/messages/ready"
        },
        "turn": {
          "$ref": "#/components/messages/turn"
        },
        "asr": {
          "$ref": "#/components/messages/asr"
        },
        "utterance": {
          "$ref": "#/components/messages/utterance"
        },
        "done": {
          "$ref": "#/components/messages/done"
        },
        "interrupted": {
          "$ref": "#/components/messages/interrupted"
        },
        "canceled": {
          "$ref": "#/components/messages/canceled"
        },
        "playbackPause": {
          "$ref": "#/components/messages/playbackPause"
        },
        "playbackResume": {
          "$ref": "#/components/messages/playbackResume"
        },
        "ack": {
          "$ref": "#/components/messages/ack"
        },
        "toolCall": {
          "$ref": "#/components/messages/toolCall"
        },
        "toolCancelServer": {
          "$ref": "#/components/messages/toolCancelServer"
        },
        "voiceChanged": {
          "$ref": "#/components/messages/voiceChanged"
        },
        "error": {
          "$ref": "#/components/messages/error"
        },
        "assistantAudio": {
          "$ref": "#/components/messages/assistantAudio"
        },
        "ambience": {
          "$ref": "#/components/messages/ambience"
        },
        "playbackPaused": {
          "$ref": "#/components/messages/playbackPaused"
        },
        "playbackResumed": {
          "$ref": "#/components/messages/playbackResumed"
        },
        "playbackPauseFailed": {
          "$ref": "#/components/messages/playbackPauseFailed"
        }
      },
      "bindings": {
        "ws": {
          "method": "GET"
        }
      }
    }
  },
  "operations": {
    "sendClientMessages": {
      "action": "send",
      "channel": {
        "$ref": "#/channels/conversation"
      },
      "summary": "Send the start frame, microphone audio, and client controls",
      "messages": [
        {
          "$ref": "#/channels/conversation/messages/start"
        },
        {
          "$ref": "#/channels/conversation/messages/reset"
        },
        {
          "$ref": "#/channels/conversation/messages/setVoice"
        },
        {
          "$ref": "#/channels/conversation/messages/toolResult"
        },
        {
          "$ref": "#/channels/conversation/messages/toolProgress"
        },
        {
          "$ref": "#/channels/conversation/messages/toolCancelClient"
        },
        {
          "$ref": "#/channels/conversation/messages/ambience"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackStopped"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackPaused"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackResumed"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackPauseFailed"
        },
        {
          "$ref": "#/channels/conversation/messages/microphoneAudio"
        }
      ]
    },
    "receiveServerMessages": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/conversation"
      },
      "summary": "Receive lifecycle events, assistant audio, transcripts, and tool calls",
      "messages": [
        {
          "$ref": "#/channels/conversation/messages/ready"
        },
        {
          "$ref": "#/channels/conversation/messages/turn"
        },
        {
          "$ref": "#/channels/conversation/messages/asr"
        },
        {
          "$ref": "#/channels/conversation/messages/utterance"
        },
        {
          "$ref": "#/channels/conversation/messages/done"
        },
        {
          "$ref": "#/channels/conversation/messages/interrupted"
        },
        {
          "$ref": "#/channels/conversation/messages/canceled"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackPause"
        },
        {
          "$ref": "#/channels/conversation/messages/playbackResume"
        },
        {
          "$ref": "#/channels/conversation/messages/ack"
        },
        {
          "$ref": "#/channels/conversation/messages/toolCall"
        },
        {
          "$ref": "#/channels/conversation/messages/toolCancelServer"
        },
        {
          "$ref": "#/channels/conversation/messages/voiceChanged"
        },
        {
          "$ref": "#/channels/conversation/messages/error"
        },
        {
          "$ref": "#/channels/conversation/messages/assistantAudio"
        }
      ]
    }
  },
  "components": {
    "messages": {
      "start": {
        "name": "start",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "session_id",
            "audio",
            "mode"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "start"
            },
            "session_id": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-][A-Za-z0-9._-]{0,63}$",
              "minLength": 1,
              "maxLength": 64
            },
            "api_key": {
              "type": "string",
              "description": "Persistent or scoped key. Optional when supplied in the WebSocket Authorization header."
            },
            "audio": {
              "$ref": "#/components/schemas/AudioConfig"
            },
            "client": {
              "$ref": "#/components/schemas/ClientInfo"
            },
            "mode": {
              "$ref": "#/components/schemas/Mode"
            }
          },
          "additionalProperties": false
        },
        "description": "Opens a conversation. api_key may be omitted when the WebSocket handshake supplied Authorization: Bearer <key>."
      },
      "reset": {
        "name": "reset",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "reset"
            }
          },
          "additionalProperties": false
        }
      },
      "setVoice": {
        "name": "setVoice",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "voice"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "set_voice"
            },
            "voice": {
              "type": "string"
            }
          },
          "additionalProperties": false
        }
      },
      "toolResult": {
        "name": "toolResult",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "id",
            "content"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "tool_result"
            },
            "id": {
              "type": "string"
            },
            "content": {}
          },
          "additionalProperties": false
        }
      },
      "toolProgress": {
        "name": "toolProgress",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "id",
            "note"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "tool_progress"
            },
            "id": {
              "type": "string"
            },
            "note": {
              "type": "string",
              "maxLength": 500
            }
          },
          "additionalProperties": false
        }
      },
      "toolCancelClient": {
        "name": "toolCancelClient",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "id"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "tool_cancel"
            },
            "id": {
              "type": "string"
            }
          },
          "additionalProperties": false
        }
      },
      "playbackStopped": {
        "name": "playbackStopped",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "event"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "client_event"
            },
            "event": {
              "type": "string",
              "const": "playback_stopped"
            },
            "remaining_ms": {
              "type": "number",
              "minimum": 0
            },
            "discarded_ms": {
              "type": "number",
              "minimum": 0
            },
            "barge_seq": {
              "type": "integer",
              "minimum": 0,
              "description": "Optional interruption sequence; the server uses the current sequence when omitted."
            }
          },
          "additionalProperties": false,
          "anyOf": [
            {
              "required": [
                "remaining_ms"
              ]
            },
            {
              "required": [
                "discarded_ms"
              ]
            }
          ]
        }
      },
      "ready": {
        "name": "ready",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "voice",
            "name",
            "voices"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "ready"
            },
            "voice": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "voices": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Voice"
              }
            }
          },
          "additionalProperties": true
        }
      },
      "turn": {
        "name": "turn",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "turn"
            }
          },
          "additionalProperties": true
        }
      },
      "asr": {
        "name": "asr",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "text"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "asr"
            },
            "text": {
              "type": "string"
            }
          },
          "additionalProperties": true
        }
      },
      "utterance": {
        "name": "utterance",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "text"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "utterance"
            },
            "text": {
              "type": "string"
            },
            "barge_seq": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        }
      },
      "done": {
        "name": "done",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "done"
            }
          },
          "additionalProperties": true
        }
      },
      "interrupted": {
        "name": "interrupted",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "interrupted"
            },
            "clear": {
              "type": "boolean"
            },
            "barge_seq": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        }
      },
      "canceled": {
        "name": "canceled",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "canceled"
            }
          },
          "additionalProperties": true
        }
      },
      "playbackPause": {
        "name": "playbackPause",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "pause_seq"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "playback_pause"
            },
            "pause_seq": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        }
      },
      "playbackResume": {
        "name": "playbackResume",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "pause_seq"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "playback_resume"
            },
            "pause_seq": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        }
      },
      "ack": {
        "name": "ack",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "frames"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "ack"
            },
            "frames": {
              "type": "integer"
            }
          },
          "additionalProperties": true
        }
      },
      "toolCall": {
        "name": "toolCall",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "id",
            "name",
            "args"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "tool_call"
            },
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "args": {
              "type": "object"
            }
          },
          "additionalProperties": true
        }
      },
      "toolCancelServer": {
        "name": "toolCancelServer",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "id"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "tool_cancel"
            },
            "id": {
              "type": "string"
            }
          },
          "additionalProperties": true
        }
      },
      "voiceChanged": {
        "name": "voiceChanged",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "voice",
            "name"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "voice"
            },
            "voice": {
              "type": "string"
            },
            "name": {
              "type": "string"
            }
          },
          "additionalProperties": true
        }
      },
      "error": {
        "name": "error",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "detail"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "error"
            },
            "detail": {
              "type": "string"
            }
          },
          "additionalProperties": true
        }
      },
      "microphoneAudio": {
        "name": "microphoneAudio",
        "contentType": "application/octet-stream",
        "payload": {
          "type": "string",
          "description": "PCM16 little-endian mono microphone audio at audio.sr, sent in binary WebSocket frames.",
          "format": "binary"
        }
      },
      "assistantAudio": {
        "name": "assistantAudio",
        "contentType": "application/octet-stream",
        "payload": {
          "type": "string",
          "description": "Float32 little-endian mono assistant audio at 16 kHz, received in binary WebSocket frames.",
          "format": "binary"
        }
      },
      "ambience": {
        "name": "ambience",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "active"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "ambience"
            },
            "active": {
              "type": "boolean"
            }
          },
          "additionalProperties": false
        }
      },
      "playbackPaused": {
        "name": "playbackPaused",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "event",
            "pause_seq"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "client_event"
            },
            "event": {
              "type": "string",
              "const": "playback_paused"
            },
            "pause_seq": {
              "type": "integer",
              "minimum": 0
            },
            "pending_ms": {
              "type": "number",
              "minimum": 0
            }
          },
          "additionalProperties": false
        }
      },
      "playbackResumed": {
        "name": "playbackResumed",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "event",
            "pause_seq"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "client_event"
            },
            "event": {
              "type": "string",
              "const": "playback_resumed"
            },
            "pause_seq": {
              "type": "integer",
              "minimum": 0
            },
            "pending_ms": {
              "type": "number",
              "minimum": 0
            }
          },
          "additionalProperties": false
        }
      },
      "playbackPauseFailed": {
        "name": "playbackPauseFailed",
        "contentType": "application/json",
        "payload": {
          "type": "object",
          "required": [
            "type",
            "event",
            "pause_seq"
          ],
          "properties": {
            "type": {
              "type": "string",
              "const": "client_event"
            },
            "event": {
              "type": "string",
              "const": "playback_pause_failed"
            },
            "pause_seq": {
              "type": "integer",
              "minimum": 0
            },
            "detail": {
              "type": "string",
              "maxLength": 160
            }
          },
          "additionalProperties": false
        }
      }
    },
    "schemas": {
      "Voice": {
        "type": "object",
        "required": [
          "key",
          "name"
        ],
        "properties": {
          "key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "AudioConfig": {
        "type": "object",
        "required": [
          "sr"
        ],
        "properties": {
          "sr": {
            "type": "integer",
            "minimum": 8000,
            "maximum": 192000
          },
          "uplink_format": {
            "type": "string"
          },
          "raw_assist": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ClientInfo": {
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "audio_frontend": {
            "type": "string",
            "description": "Diagnostic label for the active microphone echo-cancellation frontend, or unknown before SDK-owned capture starts."
          }
        },
        "additionalProperties": false
      },
      "Mode": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ConverseMode"
          },
          {
            "$ref": "#/components/schemas/RelayMode"
          }
        ]
      },
      "ConverseMode": {
        "type": "object",
        "required": [
          "kind"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "converse"
          },
          "voice": {
            "type": "string"
          },
          "instructions": {
            "type": "string"
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolDefinition"
            }
          },
          "web_search": {
            "type": "boolean",
            "description": "Enables the explicit managed web_search tool. False does not disable search inside other platform-managed reasoning tools when those capabilities are enabled."
          },
          "flow": {
            "type": "boolean"
          },
          "greeting": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "boolean",
                "const": false
              }
            ]
          },
          "temperature": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "ToolDefinition": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Client tool name. Platform-managed names such as think_deeply and web_search are reserved when those capabilities are enabled."
          },
          "description": {"type": "string", "default": ""},
          "parameters": {"type": "object"},
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Allows early speculative execution. Use only for harmless, cheap lookups."
          },
          "requires_permission": {
            "type": "boolean",
            "default": false,
            "description": "Hold the exact call until Converse verifies clear user approval."
          },
          "timeout": {
            "type": "number",
            "minimum": 1,
            "maximum": 120,
            "default": 30
          }
        },
        "additionalProperties": false
      },
      "RelayMode": {
        "type": "object",
        "required": [
          "kind",
          "provider"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "const": "relay"
          },
          "provider": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "voice": {
            "type": "string"
          },
          "web_search": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Converse API key",
        "description": "Persistent or session-scoped Converse key in the WebSocket Authorization header. Browser clients that cannot set handshake headers may instead send api_key in the start frame."
      }
    }
  }
}
