{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/corebee-ai/json-schema/corebee-ai-voice-bridge-test-call-request-schema.json",
  "title": "VoiceBridgeTestCallRequest",
  "description": "Fields a test call owns are ignored if sent: briefing_only (always true), consumer_number, business_number, consent, request_recording_consent, metadata and dtmf_plan.",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/corebee-ai-openapi.yml#/components/schemas/VoiceBridgeTestCallRequest",
  "type": "object",
  "required": [
    "destination"
  ],
  "properties": {
    "destination": {
      "type": "string",
      "pattern": "^\\+[1-9]\\d{6,14}$",
      "description": "The phone to ring, in E.164. Must be on your test-call list (GET /voice/bridge/test-calls/destinations)."
    },
    "from_number": {
      "type": "string",
      "pattern": "^\\+[1-9]\\d{6,14}$",
      "description": "One of your bridge numbers to call from; its voice and lines apply, as on a real call from it. Omitted: your default number. Not yours: 403 forbidden. The destination may not be this number."
    },
    "voice": {
      "type": "object",
      "additionalProperties": false,
      "description": "OPTIONAL. The voice and lines for THIS call only, so a dealer keeps its voice whichever of your numbers dials it. Leave it out and the call uses the calling number's voice and lines, exactly as before. Send at least one field. Each field you send wins over the same field on the voice profile you name; lines are merged key by key, and are then merged over the calling number's own lines. Nothing here is stored on your account: it applies to this call and is recorded on it.\n\nA voice_id must be a voice we have already checked for your organization: one from GET /voice/bridge/voices, or one you saved on a voice profile, on one of your numbers, or as your organization default. Any other voice is refused with 400 voice_not_verified (save it in one of those places first; saving checks it). A custom voice you revoked is refused the same way, wherever it is still saved. Creating a call never waits on a voice check.\n\nmetadata.voice_stamp is reserved: we record the call's voice under that key, so a value you send there is removed.\n\nRETRIES: send an idempotency_key whenever you send `voice`. Without one, a retry is matched on the request body plus the resolved voice settings, so a voice profile edited between your first attempt and a retry makes the retry a NEW call.",
      "properties": {
        "profile_id": {
          "type": "string",
          "pattern": "^vp_[a-z2-7]{12}$",
          "description": "A voice profile from GET /voice/bridge/profiles. Its voice, lines, speed, volume and language apply unless this object sends the same field. Unknown id: 404 profile_not_found. Voice profiles switched off for your organization: 403 feature_not_enabled."
        },
        "voice_id": {
          "type": "string",
          "format": "uuid",
          "description": "The agent voice for this call. Must be a recommended voice (GET /voice/bridge/voices) or one already saved and checked for your organization; otherwise 400 voice_not_verified. Not a voice id at all: 400 voice_not_found."
        },
        "speech_overrides": {
          "type": "object",
          "description": "The agent lines for this call: {\"templates\": {<key>: <line>}, \"variables\": {\"dealership\": ..., \"department\": ...}}. Same keys and rules as PATCH /voice/bridge/numbers/instructions, at most 2048 bytes. Refused lines give 400 invalid_speech_overrides naming each problem.",
          "properties": {
            "templates": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            },
            "variables": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        },
        "speed": {
          "type": "number",
          "minimum": 0.7,
          "maximum": 1.3,
          "description": "Speaking pace for this call, 0.7 to 1.3 (1.0 is normal). Refused with field_not_yet_supported until switched on for this deployment."
        },
        "volume": {
          "type": "number",
          "minimum": 0.5,
          "maximum": 1.5,
          "description": "Speaking level for this call, 0.5 to 1.5 (1.0 is normal). Refused with field_not_yet_supported until switched on for this deployment."
        },
        "language": {
          "type": "string",
          "enum": [
            "en",
            "es"
          ],
          "description": "'en' is accepted (it is what every call speaks today); 'es' is refused with field_not_yet_supported until switched on."
        }
      }
    },
    "prep_line": {
      "type": "string",
      "maxLength": 500,
      "description": "The briefing the agent gives when the call is answered, as on POST /voice/bridge."
    },
    "idempotency_key": {
      "type": "string",
      "pattern": "^[A-Za-z0-9._:-]{1,255}$",
      "description": "Send one so a retry never rings the phone twice. A reused key answers 409 conflict with the existing call."
    }
  }
}