{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/osis-co/json-schema/osis-co-call-schema.json",
  "title": "Call",
  "description": "A phone or FaceTime call on one of your lines, as Comms last recorded it.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/osis-co-openapi.json#/components/schemas/Call",
  "type": "object",
  "required": [
    "id",
    "bridge_call_id",
    "org_id",
    "agent_id",
    "line",
    "direction",
    "kind",
    "state",
    "remote",
    "conversation_id",
    "contact_id",
    "media_mode",
    "ring_started_at",
    "answered_at",
    "ended_at",
    "duration_ms",
    "end_reason",
    "turn_count",
    "error",
    "provider",
    "voicemail",
    "created_at",
    "updated_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Comms call ID (`call_…`)."
    },
    "bridge_call_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "The call's secondary ID. Use `id`."
    },
    "org_id": {
      "type": "string",
      "description": "Your workspace ID."
    },
    "agent_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "The agent attached to the line, if any."
    },
    "line": {
      "type": "object",
      "required": [
        "e164"
      ],
      "properties": {
        "e164": {
          "type": [
            "string",
            "null"
          ],
          "description": "Your line's number in E.164 format."
        }
      }
    },
    "direction": {
      "type": "string",
      "enum": [
        "inbound",
        "outbound"
      ]
    },
    "kind": {
      "type": "string",
      "enum": [
        "phone_call",
        "facetime_audio",
        "facetime_video"
      ],
      "description": "`phone_call` is a regular cellular call. The others are FaceTime."
    },
    "state": {
      "type": "string",
      "enum": [
        "queued",
        "ringing",
        "answered",
        "in_progress",
        "ended",
        "missed",
        "declined",
        "failed",
        "canceled"
      ],
      "description": "`queued`, `ringing`, `answered` and `in_progress` are live. `ended`, `missed`, `declined`, `failed` and `canceled` are final; a call never leaves a final state."
    },
    "remote": {
      "type": "object",
      "required": [
        "handle",
        "display_name"
      ],
      "properties": {
        "handle": {
          "type": [
            "string",
            "null"
          ],
          "description": "The other party: a phone number, or for FaceTime possibly an email address."
        },
        "display_name": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "conversation_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "The conversation this call belongs to, shared with the contact's messages."
    },
    "contact_id": {
      "type": [
        "string",
        "null"
      ]
    },
    "media_mode": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "transcript",
        "relay",
        null
      ],
      "description": "`relay` when you can stream the call's audio, `transcript` when you work with text turns. `null` before the call is answered or placed."
    },
    "ring_started_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "answered_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "ended_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "duration_ms": {
      "type": [
        "integer",
        "null"
      ]
    },
    "end_reason": {
      "type": [
        "string",
        "null"
      ],
      "description": "Why the call ended, such as `remote_hangup`, `local_hangup`, `timeout`, `declined`, `failed`, `busy` or `max_duration`."
    },
    "turn_count": {
      "type": "integer",
      "description": "How many transcript turns the call has had."
    },
    "error": {
      "type": [
        "string",
        "null"
      ],
      "description": "Why the call failed, when it did."
    },
    "provider": {
      "type": "object",
      "additionalProperties": true,
      "description": "Extra failure detail (`name`, `code`, `reason`, `details`). Often empty. Use it for troubleshooting, not for program logic."
    },
    "voicemail": {
      "oneOf": [
        {
          "$ref": "#/$defs/CallVoicemail"
        },
        {
          "type": "null"
        }
      ]
    },
    "created_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "updated_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  },
  "$defs": {
    "CallVoicemail": {
      "type": "object",
      "description": "Voicemail for a missed inbound call. `null` on the call when no voicemail was attempted.",
      "required": [
        "status",
        "duration_ms",
        "recorded_at",
        "expires_at",
        "content_type",
        "recording_url"
      ],
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "recording",
            "recorded",
            "empty",
            "unavailable",
            "failed",
            "expired"
          ],
          "description": "`recording` while the caller is leaving a message. `recorded` means a message is ready to download. `empty`: the caller hung up without speaking. `unavailable`: Comms could not pick up, so the call rang out. `failed`: the recording could not be completed. `expired`: the recording passed retention and was deleted."
        },
        "duration_ms": {
          "type": [
            "integer",
            "null"
          ]
        },
        "recorded_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "expires_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the recording will be deleted."
        },
        "content_type": {
          "type": [
            "string",
            "null"
          ],
          "description": "`audio/wav` when `status` is `recorded`, otherwise `null`."
        },
        "recording_url": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri",
          "description": "Where to download the audio with your API key. Set only when `status` is `recorded`."
        }
      }
    }
  }
}