{
  "asyncapi": "3.0.0",
  "info": {
    "title": "Realtime WebSocket API",
    "version": "1.0.0",
    "description": "Bidirectional WebSocket API for real-time speech translation. The client sends a session.update event first, streams microphone audio with JSON events that contain base64-encoded audio, and receives transcripts, translated text, and translated audio events."
  },
  "servers": {
    "production": {
      "host": "realtime.camb.ai",
      "protocol": "wss",
      "pathname": "/v1/realtime",
      "description": "Production realtime WebSocket server. This endpoint is separate from the `/apis/*` WebSocket endpoints documented elsewhere."
    }
  },
  "channels": {
    "realtime": {
      "address": "/v1/realtime",
      "messages": {
        "SessionUpdate": {
          "$ref": "#/components/messages/SessionUpdate"
        },
        "InputAudioBufferAppend": {
          "$ref": "#/components/messages/InputAudioBufferAppend"
        },
        "InputAudioBufferClear": {
          "$ref": "#/components/messages/InputAudioBufferClear"
        },
        "InputAudioBufferCommit": {
          "$ref": "#/components/messages/InputAudioBufferCommit"
        },
        "ResponseCancel": {
          "$ref": "#/components/messages/ResponseCancel"
        },
        "SessionCreated": {
          "$ref": "#/components/messages/SessionCreated"
        },
        "SessionUpdated": {
          "$ref": "#/components/messages/SessionUpdated"
        },
        "InputAudioTranscriptionCompleted": {
          "$ref": "#/components/messages/InputAudioTranscriptionCompleted"
        },
        "ResponseTextDelta": {
          "$ref": "#/components/messages/ResponseTextDelta"
        },
        "ResponseTextDone": {
          "$ref": "#/components/messages/ResponseTextDone"
        },
        "ResponseAudioDelta": {
          "$ref": "#/components/messages/ResponseAudioDelta"
        },
        "ResponseAudioDone": {
          "$ref": "#/components/messages/ResponseAudioDone"
        },
        "Error": {
          "$ref": "#/components/messages/Error"
        }
      }
    }
  },
  "operations": {
    "clientSendEvents": {
      "action": "send",
      "channel": {
        "$ref": "#/channels/realtime"
      },
      "summary": "Client sends session configuration and audio input events",
      "messages": [
        {
          "$ref": "#/channels/realtime/messages/SessionUpdate"
        },
        {
          "$ref": "#/channels/realtime/messages/InputAudioBufferAppend"
        },
        {
          "$ref": "#/channels/realtime/messages/InputAudioBufferClear"
        },
        {
          "$ref": "#/channels/realtime/messages/InputAudioBufferCommit"
        },
        {
          "$ref": "#/channels/realtime/messages/ResponseCancel"
        }
      ]
    },
    "serverSendEvents": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/realtime"
      },
      "summary": "Server sends session lifecycle, transcript, text, audio, and error events",
      "messages": [
        {
          "$ref": "#/channels/realtime/messages/SessionCreated"
        },
        {
          "$ref": "#/channels/realtime/messages/SessionUpdated"
        },
        {
          "$ref": "#/channels/realtime/messages/InputAudioTranscriptionCompleted"
        },
        {
          "$ref": "#/channels/realtime/messages/ResponseTextDelta"
        },
        {
          "$ref": "#/channels/realtime/messages/ResponseTextDone"
        },
        {
          "$ref": "#/channels/realtime/messages/ResponseAudioDelta"
        },
        {
          "$ref": "#/channels/realtime/messages/ResponseAudioDone"
        },
        {
          "$ref": "#/channels/realtime/messages/Error"
        }
      ]
    }
  },
  "components": {
    "messages": {
      "SessionUpdate": {
        "name": "SessionUpdate",
        "title": "Update Session",
        "summary": "First client event. Authorizes and activates the realtime session.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/SessionUpdatePayload"
        }
      },
      "InputAudioBufferAppend": {
        "name": "InputAudioBufferAppend",
        "title": "Append Input Audio",
        "summary": "Append base64-encoded microphone audio bytes to the realtime input stream.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InputAudioBufferAppendPayload"
        }
      },
      "InputAudioBufferClear": {
        "name": "InputAudioBufferClear",
        "title": "Clear Input Audio Buffer",
        "summary": "Recognized but not supported in this version. The server responds with an error event.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InputAudioBufferClearPayload"
        }
      },
      "InputAudioBufferCommit": {
        "name": "InputAudioBufferCommit",
        "title": "Commit Input Audio Buffer",
        "summary": "Recognized but not supported in this version. The server responds with an error event.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InputAudioBufferCommitPayload"
        }
      },
      "ResponseCancel": {
        "name": "ResponseCancel",
        "title": "Cancel Response",
        "summary": "Recognized but not supported in this version. The server responds with an error event.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ResponseCancelPayload"
        }
      },
      "SessionCreated": {
        "name": "SessionCreated",
        "title": "Session Created",
        "summary": "Sent after authorization, startup, and activation complete.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/SessionCreatedPayload"
        }
      },
      "SessionUpdated": {
        "name": "SessionUpdated",
        "title": "Session Updated",
        "summary": "Sent immediately after session.created with the active session configuration.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/SessionUpdatedPayload"
        }
      },
      "InputAudioTranscriptionCompleted": {
        "name": "InputAudioTranscriptionCompleted",
        "title": "Input Audio Transcription Completed",
        "summary": "Completed user transcript produced by the realtime pipeline.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InputAudioTranscriptionCompletedPayload"
        }
      },
      "ResponseTextDelta": {
        "name": "ResponseTextDelta",
        "title": "Response Text Delta",
        "summary": "Incremental translated text. The delta is additive for the current response.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ResponseTextDeltaPayload"
        }
      },
      "ResponseTextDone": {
        "name": "ResponseTextDone",
        "title": "Response Text Done",
        "summary": "Final translated text for the current response.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ResponseTextDonePayload"
        }
      },
      "ResponseAudioDelta": {
        "name": "ResponseAudioDelta",
        "title": "Response Audio Delta",
        "summary": "Base64-encoded synthesized output audio bytes.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ResponseAudioDeltaPayload"
        }
      },
      "ResponseAudioDone": {
        "name": "ResponseAudioDone",
        "title": "Response Audio Done",
        "summary": "Current assistant audio response is complete.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ResponseAudioDonePayload"
        }
      },
      "Error": {
        "name": "Error",
        "title": "Error",
        "summary": "Structured error for unsupported recognized events and billing stop decisions.",
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/ErrorPayload"
        }
      }
    },
    "schemas": {
      "SessionConfig": {
        "type": "object",
        "properties": {
          "source_language": {
            "type": "string",
            "description": "Source language tag, for example `en-US`.",
            "example": "en-US"
          },
          "target_language": {
            "type": "string",
            "description": "Target language tag, for example `de-DE`.",
            "example": "de-DE"
          },
          "output_modalities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "text",
                "audio"
              ]
            },
            "default": [
              "text",
              "audio"
            ]
          },
          "voice": {
            "$ref": "#/components/schemas/VoiceConfig",
            "description": "Output voice selection. Defaults to the built-in voice for the target language."
          }
        },
        "required": [
          "source_language",
          "target_language"
        ]
      },
      "VoiceConfig": {
        "type": "object",
        "description": "Output voice selection. Use the built-in voice or one of your cloned voices.",
        "oneOf": [
          {
            "type": "object",
            "title": "Default voice",
            "properties": {
              "type": {
                "type": "string",
                "const": "default"
              }
            },
            "required": [
              "type"
            ]
          },
          {
            "type": "object",
            "title": "Cloned voice",
            "properties": {
              "type": {
                "type": "string",
                "const": "cloned"
              },
              "voice_id": {
                "type": "integer",
                "format": "int64",
                "description": "ID of a voice you own, from List Voices or Create Custom Voice. Stock voice IDs are rejected.",
                "example": 12345
              }
            },
            "required": [
              "type",
              "voice_id"
            ]
          }
        ]
      },
      "Auth": {
        "type": "object",
        "properties": {
          "api_key": {
            "type": "string"
          }
        },
        "required": [
          "api_key"
        ]
      },
      "SessionUpdatePayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "session.update"
          },
          "session": {
            "$ref": "#/components/schemas/SessionConfig"
          },
          "auth": {
            "$ref": "#/components/schemas/Auth",
            "description": "Optional credentials. If the WebSocket request header also includes `x-api-key`, the header credential is used."
          }
        },
        "required": [
          "type",
          "session"
        ]
      },
      "InputAudioBufferAppendPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "input_audio_buffer.append"
          },
          "audio": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "Base64-encoded audio bytes. The decoded payload can be up to 256 KiB."
          }
        },
        "required": [
          "type",
          "audio"
        ]
      },
      "InputAudioBufferClearPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "input_audio_buffer.clear"
          }
        },
        "required": [
          "type"
        ]
      },
      "InputAudioBufferCommitPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "input_audio_buffer.commit"
          }
        },
        "required": [
          "type"
        ]
      },
      "ResponseCancelPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "response.cancel"
          }
        },
        "required": [
          "type"
        ]
      },
      "SessionCreatedPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "session.created"
          },
          "session": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SessionConfig"
              },
              {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Durable realtime session ID."
                  }
                },
                "required": [
                  "id"
                ]
              }
            ]
          }
        },
        "required": [
          "type",
          "session"
        ]
      },
      "SessionUpdatedPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "session.updated"
          },
          "session": {
            "$ref": "#/components/schemas/SessionConfig"
          }
        },
        "required": [
          "type",
          "session"
        ]
      },
      "InputAudioTranscriptionCompletedPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "conversation.item.input_audio_transcription.completed"
          },
          "transcript": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "transcript"
        ]
      },
      "ResponseTextDeltaPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "response.text.delta"
          },
          "delta": {
            "type": "string",
            "description": "Additive translated text delta for the current response."
          }
        },
        "required": [
          "type",
          "delta"
        ]
      },
      "ResponseTextDonePayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "response.text.done"
          },
          "text": {
            "type": "string",
            "description": "Final translated text."
          }
        },
        "required": [
          "type",
          "text"
        ]
      },
      "ResponseAudioDeltaPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "response.audio.delta"
          },
          "delta": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "Base64-encoded synthesized output audio bytes."
          }
        },
        "required": [
          "type",
          "delta"
        ]
      },
      "ResponseAudioDonePayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "response.audio.done"
          }
        },
        "required": [
          "type"
        ]
      },
      "ErrorPayload": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "error"
          },
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              }
            },
            "required": [
              "message"
            ]
          }
        },
        "required": [
          "type",
          "error"
        ]
      }
    }
  }
}