{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/corebee-ai/json-schema/corebee-ai-bridge-list-item-schema.json",
  "title": "BridgeListItem",
  "description": "One bridge session in the list feed. Field names match BridgeStatus for every field they share, so a client can reuse one mapper. The per-session timeline (events) and transcript are NOT included here, fetch status_url for those.",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/corebee-ai-openapi.yml#/components/schemas/BridgeListItem",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer"
    },
    "state": {
      "type": "string",
      "enum": [
        "created",
        "dialing_business",
        "ivr_nav",
        "amd_verdict",
        "human",
        "voicemail",
        "prep_line",
        "converse",
        "dialing_consumer",
        "bridging",
        "bridged",
        "completed",
        "failed"
      ]
    },
    "failure_reason": {
      "type": [
        "string",
        "null"
      ],
      "description": "Why the bridge failed; null unless state=failed. OPEN set, see BridgeStatus.failure_reason for the full catalogue and the caution about treating unrecognized values as generic failures."
    },
    "amd_result": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "human_residence",
        "human_business",
        "machine",
        "silence",
        "fax_detected",
        "not_sure"
      ],
      "description": "Premium AMD detection.ended result, null until determined."
    },
    "business_number": {
      "type": [
        "string",
        "null"
      ],
      "description": "The business leg, unmasked (you supplied it)."
    },
    "consumer_number": {
      "type": [
        "string",
        "null"
      ],
      "description": "The consumer leg, unmasked (you supplied it)."
    },
    "from_number": {
      "type": [
        "string",
        "null"
      ],
      "description": "The originating DID owned by your organization that placed the calls."
    },
    "customer_ref": {
      "type": [
        "string",
        "null"
      ],
      "description": "Your own identifier, echoed from metadata.customer_ref at create time."
    },
    "leg_a_call_control_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Business leg."
    },
    "leg_b_call_control_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Consumer leg."
    },
    "created_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the bridge was requested. This is the field both `from`/`to` and the cursor order on."
    },
    "updated_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "bridged_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When both legs were actually connected; null if they never were."
    },
    "recording_duration_sec": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0,
      "description": "Seconds of SAVED AUDIO for this call, the length of the mp3, as reported by the carrier (whole seconds). This is NOT the billed duration and it is NOT the whole call: see `joined_seconds` for what you are invoiced for.\n\n⛔ SCOPE: the audio covers the AI-TO-BUSINESS leg ONLY. Recording stops before the consumer is dialed, so the consumer is never in it and was never recorded. Do not label this \"call recording\" in a UI shown to anyone who might reasonably read that as including the consumer.\n\nnull when no recording exists for the session, which is the ORDINARY case, not an error: recording is a per-account feature and most sessions have no recording row at all. null ALSO when a recording exists but its length was never stored. It is never 0 for \"unknown\": a 0 would be a claim about the call, a null is a claim about our knowledge. This field never fails the request and never carries a link to audio."
    },
    "joined_seconds": {
      "type": [
        "number",
        "null"
      ],
      "minimum": 0,
      "description": "Seconds two HUMANS were on the line together, THE BILLED INTERVAL. Identical in name, source and value to `joined_seconds` on GET /voice/bridge/usage, so the operational feed and the billing feed cannot quote you different numbers.\n\nRead from the carrier's own call.bridged start_time, NOT from `bridged_at`: that field is stamped by our webhook worker a median 7.73s after the fact and on three historical sessions post-dates the hangup, so differencing it yields a negative conversation. null when the evidence pass has not run over this session or the carrier stamps did not survive its checks. Never negative, never guessed from a clock, and never silently falling back to `bridged_at`.\n\nIt is unrelated to `recording_duration_sec` and the two routinely disagree: a call can be recorded for 41 seconds and never join anybody."
    },
    "sandbox": {
      "type": "boolean",
      "description": "True when this session was produced by a reserved magic test number. Shaped exactly like a real call on purpose, exclude it from your own totals."
    },
    "mock": {
      "type": "boolean",
      "description": "True for seeded sample data shown before real traffic exists. Never a real call."
    },
    "briefing_only": {
      "type": "boolean",
      "description": "True when the request asked for a briefing-only test: the business leg was dialed and the prep line played, but the consumer was NEVER dialed."
    },
    "status_url": {
      "type": "string",
      "description": "Path to the full single-session projection (timeline, transcript)."
    }
  }
}