{
  "openapi": "3.1.0",
  "info": {
    "title": "Vexaphone customer API",
    "version": "1.0.0",
    "description": "Implementation candidate; not publicly enabled. Text SMS and short-lived handset calls; no browser audio. Action-status reads belong to this logical client. Explicit export scopes read selected-phone events and call/media resources from all origins. Shared voicemail requires an additional account-level scope."
  },
  "servers": [
    {
      "url": "https://api.vexaphone.com"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/senders": {
      "get": {
        "operationId": "listSenders",
        "description": "Requires senders:read. Lists only selected authorized phones; readiness is a recent phone report, not a reservation or service guarantee.",
        "responses": {
          "200": {
            "description": "Current authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Senders"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "sendSms",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 160,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmsRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Durably accepted; not proof of sending or connection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedMessage"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires messages:send. Recipient must include +country code. expiresAt must be in the future, at most 24 hours away. Retries use the same key and unchanged body, including expiry."
      }
    },
    "/v1/messages/{messageId}": {
      "get": {
        "operationId": "getMessageStatus",
        "parameters": [
          {
            "in": "path",
            "name": "messageId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageStatus"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires messages:read. This API client’s accepted SMS only; no other clients, CRMs or inbound history."
      }
    },
    "/v1/call-commands": {
      "post": {
        "operationId": "startHandsetCall",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 160,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CallRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Durably accepted; not proof of sending or connection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallCommand"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires calls:write. Requests a call on the selected Android phone. 202 is not proof of dialling or answering. Replay returns the original acceptance and cannot extend the short expiry."
      }
    },
    "/v1/call-commands/{commandId}": {
      "get": {
        "operationId": "getCallCommand",
        "parameters": [
          {
            "in": "path",
            "name": "commandId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallCommand"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires calls:read. This client’s commands only; callId is included when actual phone history arrives."
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "readEvents",
        "description": "Requires events:read. Retained selected-phone events from every origin. Shared voicemail also requires voicemail:read. Filtered rows advance the cursor; an empty page does not imply end-of-stream. Stale nonzero cursors return 410. after=0 explicitly restarts the retained window.",
        "parameters": [
          {
            "in": "query",
            "name": "after",
            "schema": {
              "$ref": "#/components/schemas/Cursor"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessEventPage"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/calls/{callId}": {
      "get": {
        "operationId": "getCall",
        "parameters": [
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallData"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires calls:read. Ended calls on selected current phone/SIM grants, from any origin. Safe details and optional protected artifact references."
      }
    },
    "/v1/calls/{callId}/recording": {
      "get": {
        "operationId": "downloadCallRecording",
        "parameters": [
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,15}$"
            },
            "description": "Use the exact artifact reference supplied by the event/call. Replaced or retired content is unavailable."
          },
          {
            "in": "header",
            "name": "Range",
            "schema": {
              "type": "string",
              "pattern": "^bytes=[0-9]+-[0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized private artifact; never a permanent public URL.",
            "content": {
              "audio/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Requested supported byte range."
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires calls:read and media:read. Audio content; supports a single byte range. A later transcript revision does not invalidate unchanged audio."
      }
    },
    "/v1/calls/{callId}/transcript": {
      "get": {
        "operationId": "downloadCallTranscript",
        "parameters": [
          {
            "in": "path",
            "name": "callId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,15}$"
            },
            "description": "Use the exact artifact reference supplied by the event/call. Replaced or retired content is unavailable."
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized private artifact; never a permanent public URL.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires calls:read and media:read. Phone-provided UTF-8 plain text when available."
      }
    },
    "/v1/voicemails/{voicemailId}/recording": {
      "get": {
        "operationId": "downloadVoicemail",
        "parameters": [
          {
            "in": "path",
            "name": "voicemailId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,15}$"
            },
            "description": "Use the exact artifact reference supplied by the event/call. Replaced or retired content is unavailable."
          },
          {
            "in": "header",
            "name": "Range",
            "schema": {
              "type": "string",
              "pattern": "^bytes=[0-9]+-[0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized private artifact; never a permanent public URL.",
            "content": {
              "audio/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Requested supported byte range."
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Requires voicemail:read and media:read. Explicit account-shared mailbox, no handset inference. Revision is 1."
      }
    },
    "/v1/messages/{messageId}/attachments/{mediaId}": {
      "get": {
        "operationId": "downloadMessageAttachment",
        "description": "Requires events:read and media:read. Exact selected-phone message/attachment identity, from any origin. No arbitrary storage-key access.",
        "parameters": [
          {
            "in": "path",
            "name": "messageId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "path",
            "name": "mediaId",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized private attachment.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "default": {
            "description": "Sanitized error. 401 invalid/expired/revoked key; 403 scope/access; 404 unavailable; 409 conflict; 410 replay/artifact expired; 416 unsupported/outside byte range; 422 readiness/expiry; 429/503 retry with original action identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "code",
                    "message",
                    "retryable",
                    "requestId"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "retryable": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Owner-created vxa_ key, scoped to actions and selected sender IDs. Never use dashboard, device or CRM credentials."
      }
    },
    "schemas": {
      "SmsRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "to": {
            "type": "string",
            "pattern": "^\\+[1-9][0-9]{4,14}$"
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16000
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "senderId",
          "to",
          "text",
          "expiresAt"
        ]
      },
      "CallRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "to": {
            "type": "string",
            "pattern": "^\\+[1-9][0-9]{4,14}$"
          }
        },
        "required": [
          "senderId",
          "to"
        ]
      },
      "AcceptedMessage": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "messageId": {
            "type": "string",
            "format": "uuid"
          },
          "commandId": {
            "type": "string",
            "format": "uuid"
          },
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "state": {
            "const": "queued"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "messageId",
          "commandId",
          "senderId",
          "state",
          "createdAt"
        ]
      },
      "MessageStatus": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "messageId": {
            "type": "string",
            "format": "uuid"
          },
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "deviceId": {
            "type": "string",
            "format": "uuid"
          },
          "to": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "submissionState": {
            "enum": [
              "queued",
              "sending",
              "sent",
              "failed",
              "partially_sent",
              "unknown",
              "expired",
              "cancelled"
            ]
          },
          "deliveryState": {
            "enum": [
              "not_requested",
              "pending",
              "delivered",
              "partial",
              "failed",
              "unknown"
            ]
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "messageId",
          "senderId",
          "deviceId",
          "to",
          "text",
          "submissionState",
          "deliveryState",
          "revision",
          "createdAt",
          "updatedAt"
        ]
      },
      "CallCommand": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "commandId": {
            "type": "string",
            "format": "uuid"
          },
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "deviceId": {
            "type": "string",
            "format": "uuid"
          },
          "to": {
            "type": "string"
          },
          "state": {
            "enum": [
              "queued",
              "submitted",
              "rejected",
              "unknown",
              "expired"
            ]
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "callId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "commandId",
          "senderId",
          "deviceId",
          "to",
          "state",
          "reason",
          "expiresAt"
        ]
      },
      "Sender": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "senderId": {
            "type": "string",
            "format": "uuid"
          },
          "deviceId": {
            "type": "string",
            "format": "uuid"
          },
          "deviceName": {
            "type": "string"
          },
          "vexaphoneNumber": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "numberCountry": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "smsEnabled": {
            "type": "boolean"
          },
          "callAvailable": {
            "type": "boolean"
          },
          "lastSeenAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "senderId",
          "deviceId",
          "deviceName",
          "vexaphoneNumber",
          "numberCountry",
          "smsEnabled",
          "callAvailable",
          "lastSeenAt"
        ]
      },
      "Senders": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "senders": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/Sender"
            }
          }
        },
        "required": [
          "senders"
        ]
      },
      "Cursor": {
        "type": "string",
        "pattern": "^(0|[1-9][0-9]{0,17})$"
      },
      "MessageEvent": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "eventId": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "enum": [
              "message.received",
              "message.sent",
              "message.status_updated"
            ]
          },
          "schemaVersion": {
            "const": "1"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "recordedAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "$ref": "#/components/schemas/MessageData"
          }
        },
        "required": [
          "eventId",
          "type",
          "schemaVersion",
          "occurredAt",
          "recordedAt",
          "data"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "const": "message.received"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "direction": {
                      "const": "inbound"
                    }
                  }
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "message.sent"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "direction": {
                      "const": "outbound"
                    },
                    "submissionState": {
                      "const": "sent"
                    }
                  }
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "message.status_updated"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "direction": {
                      "const": "outbound"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageData": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "messageId": {
            "type": "string",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "deviceId": {
            "type": "string",
            "format": "uuid"
          },
          "deviceName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "vexaphoneNumber": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\+[1-9][0-9]{4,14}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "contactNumber": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\+[1-9][0-9]{4,14}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "contactAddress": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "raw": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 128
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "kind": {
                "enum": [
                  "phone",
                  "alphanumeric",
                  "unknown"
                ]
              }
            },
            "required": [
              "raw",
              "kind"
            ]
          },
          "numberCountry": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "normalizationSource": {
            "enum": [
              "already_international",
              "phone_country",
              null
            ]
          },
          "direction": {
            "enum": [
              "inbound",
              "outbound"
            ]
          },
          "transport": {
            "enum": [
              "sms",
              "mms"
            ]
          },
          "origin": {
            "enum": [
              "phone",
              "api",
              "integration",
              "dashboard",
              "unknown"
            ]
          },
          "originId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "commandId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 16000
          },
          "submissionState": {
            "enum": [
              "not_applicable",
              "queued",
              "sending",
              "sent",
              "failed",
              "partially_sent",
              "unknown",
              "expired",
              "cancelled"
            ]
          },
          "deliveryState": {
            "enum": [
              "not_applicable",
              "not_requested",
              "pending",
              "delivered",
              "partial",
              "failed",
              "unknown"
            ]
          },
          "attachments": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "mediaId": {
                  "type": "string",
                  "format": "uuid"
                },
                "contentType": {
                  "type": "string",
                  "maxLength": 128
                },
                "size": {
                  "type": "integer",
                  "minimum": 1
                }
              },
              "required": [
                "mediaId",
                "contentType",
                "size"
              ]
            }
          }
        },
        "required": [
          "messageId",
          "revision",
          "deviceId",
          "deviceName",
          "vexaphoneNumber",
          "contactNumber",
          "contactAddress",
          "numberCountry",
          "normalizationSource",
          "direction",
          "transport",
          "origin",
          "originId",
          "commandId",
          "text",
          "submissionState",
          "deliveryState",
          "attachments"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "origin": {
                  "enum": [
                    "api",
                    "integration"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "originId": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "else": {
              "properties": {
                "originId": {
                  "const": null
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "origin": {
                  "const": "phone"
                }
              }
            },
            "then": {
              "properties": {
                "commandId": {
                  "const": null
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "origin": {
                  "enum": [
                    "api",
                    "integration",
                    "dashboard"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "commandId": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        ]
      },
      "Artifact": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "contentType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "size": {
            "type": "integer",
            "minimum": 1
          },
          "downloadPath": {
            "type": "string",
            "pattern": "^/v1/(calls|voicemails)/[a-f0-9-]{36}/(recording|transcript)\\?revision=[1-9][0-9]*$"
          }
        },
        "required": [
          "contentType",
          "size",
          "downloadPath"
        ]
      },
      "CallData": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "callId": {
            "type": "string",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "deviceId": {
            "$ref": "#/components/schemas/MessageData/properties/deviceId"
          },
          "deviceName": {
            "$ref": "#/components/schemas/MessageData/properties/deviceName"
          },
          "vexaphoneNumber": {
            "$ref": "#/components/schemas/MessageData/properties/vexaphoneNumber"
          },
          "contactNumber": {
            "$ref": "#/components/schemas/MessageData/properties/contactNumber"
          },
          "contactAddress": {
            "$ref": "#/components/schemas/MessageData/properties/contactAddress"
          },
          "numberCountry": {
            "$ref": "#/components/schemas/MessageData/properties/numberCountry"
          },
          "normalizationSource": {
            "$ref": "#/components/schemas/MessageData/properties/normalizationSource"
          },
          "origin": {
            "$ref": "#/components/schemas/MessageData/properties/origin"
          },
          "originId": {
            "$ref": "#/components/schemas/MessageData/properties/originId"
          },
          "commandId": {
            "$ref": "#/components/schemas/MessageData/properties/commandId"
          },
          "direction": {
            "enum": [
              "inbound",
              "outbound",
              "unknown"
            ]
          },
          "outcome": {
            "enum": [
              "connected",
              "missed",
              "not_answered",
              "not_connected",
              "answered_elsewhere"
            ]
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "connectedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "endedAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationSeconds": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "timePrecision": {
            "enum": [
              "telecom",
              "call_log_estimated",
              null
            ]
          },
          "recording": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Artifact"
              },
              {
                "type": "null"
              }
            ]
          },
          "transcript": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Artifact"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "callId",
          "revision",
          "deviceId",
          "deviceName",
          "vexaphoneNumber",
          "contactNumber",
          "contactAddress",
          "numberCountry",
          "normalizationSource",
          "origin",
          "originId",
          "commandId",
          "direction",
          "outcome",
          "startedAt",
          "connectedAt",
          "endedAt",
          "durationSeconds",
          "timePrecision",
          "recording",
          "transcript"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "origin": {
                  "enum": [
                    "api",
                    "integration"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "originId": {
                  "type": "string",
                  "format": "uuid"
                },
                "commandId": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "else": {
              "properties": {
                "originId": {
                  "const": null
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "origin": {
                  "const": "phone"
                }
              }
            },
            "then": {
              "properties": {
                "commandId": {
                  "const": null
                }
              }
            }
          }
        ]
      },
      "CallCommandData": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "commandId": {
            "type": "string",
            "format": "uuid"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "deviceId": {
            "$ref": "#/components/schemas/MessageData/properties/deviceId"
          },
          "deviceName": {
            "$ref": "#/components/schemas/MessageData/properties/deviceName"
          },
          "vexaphoneNumber": {
            "$ref": "#/components/schemas/MessageData/properties/vexaphoneNumber"
          },
          "contactNumber": {
            "$ref": "#/components/schemas/MessageData/properties/contactNumber"
          },
          "contactAddress": {
            "$ref": "#/components/schemas/MessageData/properties/contactAddress"
          },
          "numberCountry": {
            "$ref": "#/components/schemas/MessageData/properties/numberCountry"
          },
          "normalizationSource": {
            "$ref": "#/components/schemas/MessageData/properties/normalizationSource"
          },
          "origin": {
            "enum": [
              "api",
              "integration",
              "dashboard",
              "unknown"
            ]
          },
          "originId": {
            "$ref": "#/components/schemas/MessageData/properties/originId"
          },
          "state": {
            "enum": [
              "queued",
              "submitted",
              "rejected",
              "unknown",
              "expired"
            ]
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128
              },
              {
                "type": "null"
              }
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "commandId",
          "revision",
          "deviceId",
          "deviceName",
          "vexaphoneNumber",
          "contactNumber",
          "contactAddress",
          "numberCountry",
          "normalizationSource",
          "origin",
          "originId",
          "state",
          "reason",
          "expiresAt"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "origin": {
                  "enum": [
                    "api",
                    "integration"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "originId": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "else": {
              "properties": {
                "originId": {
                  "const": null
                }
              }
            }
          }
        ]
      },
      "VoicemailData": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "voicemailId": {
            "type": "string",
            "format": "uuid"
          },
          "revision": {
            "const": 1
          },
          "mailboxScope": {
            "const": "account_shared"
          },
          "deviceId": {
            "type": "null"
          },
          "vexaphoneNumber": {
            "type": "null"
          },
          "numberCountry": {
            "type": "null"
          },
          "mailboxNumber": {
            "type": "string",
            "pattern": "^\\+[1-9][0-9]{4,14}$"
          },
          "caller": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128
              },
              {
                "type": "null"
              }
            ]
          },
          "contactNumber": {
            "$ref": "#/components/schemas/MessageData/properties/contactNumber"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationSeconds": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "recording": {
            "$ref": "#/components/schemas/Artifact"
          }
        },
        "required": [
          "voicemailId",
          "revision",
          "mailboxScope",
          "deviceId",
          "vexaphoneNumber",
          "numberCountry",
          "mailboxNumber",
          "caller",
          "contactNumber",
          "occurredAt",
          "durationSeconds",
          "expiresAt",
          "recording"
        ]
      },
      "CommunicationEvent": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "eventId": {
            "type": "string",
            "format": "uuid"
          },
          "schemaVersion": {
            "const": "1"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "recordedAt": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "enum": [
              "call.ended",
              "call.command_updated",
              "call.recording_available",
              "call.transcript_available",
              "voicemail.received"
            ]
          },
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CallData"
              },
              {
                "$ref": "#/components/schemas/CallCommandData"
              },
              {
                "$ref": "#/components/schemas/VoicemailData"
              }
            ]
          }
        },
        "required": [
          "eventId",
          "schemaVersion",
          "occurredAt",
          "recordedAt",
          "type",
          "data"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "type": {
                  "enum": [
                    "call.ended",
                    "call.recording_available",
                    "call.transcript_available"
                  ]
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/CallData"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "call.command_updated"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/CallCommandData"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "voicemail.received"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/VoicemailData"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "call.recording_available"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "recording": {
                      "$ref": "#/components/schemas/Artifact"
                    }
                  }
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "type": {
                  "const": "call.transcript_available"
                }
              }
            },
            "then": {
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "transcript": {
                      "$ref": "#/components/schemas/Artifact"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "BusinessEvent": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/MessageEvent"
          },
          {
            "$ref": "#/components/schemas/CommunicationEvent"
          }
        ]
      },
      "BusinessEventPage": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "events": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/BusinessEvent"
            }
          },
          "nextCursor": {
            "$ref": "#/components/schemas/Cursor"
          }
        },
        "required": [
          "events",
          "nextCursor"
        ]
      }
    }
  }
}
