{
  "openapi": "3.1.0",
  "info": {
    "title": "DialStack API",
    "version": "1.0.0",
    "description": "DialStack — Business Voice for Vertical SaaS\n\n## Authentication\nDialStack supports three authentication methods:\n\n### Platform API Keys (Backend)\nFor server-side integrations, use your secret API key (starts with `sk_live_`) in the Authorization header.\n\nExample: `Authorization: Bearer sk_live_YOUR_SECRET_KEY`\n\n### Session Tokens (Embedded Components)\nFor embedded voice components in your frontend, create a session using the Account Session API\nand use the client_secret JWT token in the Authorization header.\n\nExample: `Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`\n\nSessions are account-scoped and expire after 1 hour.\n\n### User Tokens (Softphones & User-Facing Apps)\nFor client-side applications where end users interact directly (softphones, call history,\nvoicemail), authenticate users via `POST /v1/auth/token` and use the returned user token.\n\nExample: `Authorization: Bearer eyJhbGciOiJFZERTQSIs...`\n\nUser tokens are scoped to a single user within an account and grant access to the WebRTC\nsignalling channel, call history, voicemails, and presence. See the\n[Authentication guide](/authentication#user-tokens) for setup details.\n\n## Account Context\nMost API endpoints require an account context. This is specified differently depending on the authentication method:\n\n### Platform API Keys\nInclude the `DialStack-Account` header with the account ID:\n```\nDialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41\n```\n\n### Session Tokens\nThe account is automatically derived from the JWT claims. No header is needed.\n\n## Pagination\nAll list API methods support URL-based cursor pagination. Results are returned in reverse chronological order.\n\n### Request Parameters\n- `limit` - Number of objects to return (1-100, default 10)\n- `page` - Opaque cursor token (only used when following pagination URLs)\n\n### Response Structure\nList responses include:\n- `object` - Always \"list\"\n- `url` - The endpoint URL\n- `next_page_url` - URL to fetch the next page (null if no more pages)\n- `previous_page_url` - URL to fetch the previous page (null if on first page)\n- `data` - Array of objects\n\n### Usage\nTo paginate, simply follow the URLs provided in `next_page_url` and `previous_page_url`.\nDo not construct pagination URLs manually - the cursor format is opaque and may change.\n\n## Expanding Responses\nSome endpoints support the `expand[]` parameter to include related resources inline.\nWithout expansion, the related data is omitted from the response.\n\nFor example, to include extensions when listing users:\n```\nGET /v1/users?expand[]=extensions\n```\n\nThe expanded field appears as a nested list object:\n```json\n{\n  \"id\": \"user_01h2xcejqtf2nbrexx3vqjhp42\",\n  \"name\": \"Dr. Alice Smith\",\n  \"extensions\": {\n    \"object\": \"list\",\n    \"data\": [\n      {\n        \"number\": \"105\",\n        \"target\": \"user_01h2xcejqtf2nbrexx3vqjhp42\",\n        \"status\": \"active\",\n        \"created_at\": \"2025-10-18T10:00:00Z\",\n        \"updated_at\": \"2025-10-18T10:00:00Z\"\n      }\n    ]\n  }\n}\n```\n\nExpandable fields are noted in endpoint descriptions.\n\n## Base URL\n- `https://api.dialstack.ai`\n\n## Voice Apps\nFor building programmable voice applications with webhooks and real-time audio streaming,\nsee the [Voice Apps Guide](/guides/voice-apps).\n\n## Routing Targets\nA **routing target** is a resource that can receive calls. The following resource\ntypes are valid routing targets:\n- **User** — rings all of the user's registered devices (desk phones, softphones)\n- **Voice App** — delivers the call via webhook notification for programmatic control or monitoring\n- **Dial Plan** — routes the call through a dial plan graph\n- **Ring Group** — rings all group members simultaneously\n- **Shared Voicemail** — sends the call directly to a shared voicemail box\n\n## Resource IDs\nAll resource IDs in the API are opaque strings of at most 255 characters.\nDo not parse or make assumptions about their format — treat them as identifiers\nto store and pass back to the API.\n",
    "contact": {
      "name": "DialStack API Support",
      "email": "info@dialstack.ai",
      "url": "https://docs.dialstack.ai/api"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://dialstack.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.dialstack.ai"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    },
    {
      "SessionAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_live_*",
        "description": "Platform secret API key (starts with sk_live_) for server-side integrations.\nInclude in Authorization header:\n`Authorization: Bearer sk_live_YOUR_SECRET_KEY`\n\nFor account-scoped operations, also include the `DialStack-Account` header.\n"
      },
      "SessionAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Account session JWT token for embedded components.\nCreate a session using POST /v1/account_sessions\nand use the client_secret JWT in the Authorization header:\n`Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`\n\nSessions are account-scoped and expire after 1 hour.\nThe account context is automatically derived from the JWT claims.\n\nNote: Session tokens cannot be used to create new sessions.\n"
      },
      "UserAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "User token for softphones and user-facing applications.\nObtain a token via POST /v1/auth/token and include it in the Authorization header:\n`Authorization: Bearer eyJhbGciOiJFZERTQSIs...`\n\nUser tokens are scoped to a single user within an account.\nThey grant access to the WebRTC signalling channel and user-scoped\nREST endpoints (/v1/me/*). They cannot access platform-level endpoints.\n\nTokens expire after 1 hour. Use POST /v1/auth/refresh to extend.\n"
      }
    },
    "parameters": {
      "DialStackAccount": {
        "name": "DialStack-Account",
        "in": "header",
        "required": true,
        "description": "Account identifier for API key authentication.\nNot required when using session tokens (account is derived from JWT).\n",
        "schema": {
          "type": "string",
          "example": "acct_01h2xcejqtf2nbrexx3vqjhp41"
        }
      },
      "AccountId": {
        "name": "account_id",
        "in": "path",
        "required": true,
        "description": "Account identifier",
        "schema": {
          "type": "string",
          "example": "acct_01h2xcejqtf2nbrexx3vqjhp41"
        }
      },
      "UserId": {
        "name": "user_id",
        "in": "path",
        "required": true,
        "description": "User identifier",
        "schema": {
          "type": "string",
          "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
        }
      },
      "VoicemailId": {
        "name": "voicemail_id",
        "in": "path",
        "required": true,
        "description": "Voicemail identifier",
        "schema": {
          "type": "string",
          "example": "vm_01h2xcejqtf2nbrexx3vqjhp44"
        }
      },
      "VoiceAppId": {
        "name": "voice_app_id",
        "in": "path",
        "required": true,
        "description": "Voice app identifier",
        "schema": {
          "type": "string",
          "example": "va_01h2xcejqtf2nbrexx3vqjhp49"
        }
      },
      "AIAgentId": {
        "name": "ai_agent_id",
        "in": "path",
        "required": true,
        "description": "AI agent identifier",
        "schema": {
          "type": "string",
          "example": "aia_01h2xcejqtf2nbrexx3vqjhp60"
        }
      },
      "ScheduleId": {
        "name": "schedule_id",
        "in": "path",
        "required": true,
        "description": "Schedule identifier",
        "schema": {
          "type": "string",
          "example": "sched_01h2xcejqtf2nbrexx3vqjhp50"
        }
      },
      "RingGroupId": {
        "name": "ring_group_id",
        "in": "path",
        "required": true,
        "description": "Ring group identifier",
        "schema": {
          "type": "string",
          "example": "rg_01h2xcejqtf2nbrexx3vqjhp51"
        }
      },
      "RingGroupMemberId": {
        "name": "member_id",
        "in": "path",
        "required": true,
        "description": "Ring group member identifier",
        "schema": {
          "type": "string",
          "example": "rgm_01h2xcejqtf2nbrexx3vqjhp52"
        }
      },
      "SharedVoicemailBoxId": {
        "name": "shared_voicemail_box_id",
        "in": "path",
        "required": true,
        "description": "Shared voicemail box identifier",
        "schema": {
          "type": "string",
          "example": "svm_01h2xcejqtf2nbrexx3vqjhp60"
        }
      },
      "AudioClipId": {
        "name": "audio_clip_id",
        "in": "path",
        "required": true,
        "description": "Audio clip identifier",
        "schema": {
          "type": "string"
        }
      },
      "ExtensionNumber": {
        "name": "number",
        "in": "path",
        "required": true,
        "description": "Extension number (dial code)",
        "schema": {
          "type": "string",
          "example": "105"
        }
      },
      "ExtensionTargetFilter": {
        "name": "target",
        "in": "query",
        "required": false,
        "description": "Filter extensions by routing target ID",
        "schema": {
          "type": "string",
          "maxLength": 255,
          "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
        }
      },
      "CallId": {
        "name": "call_id",
        "in": "path",
        "required": true,
        "description": "Call log identifier",
        "schema": {
          "type": "string",
          "example": "call_01h2xcejqtf2nbrexx3vqjhp45"
        }
      },
      "ListenerId": {
        "name": "listener_id",
        "in": "path",
        "required": true,
        "description": "Listener identifier",
        "schema": {
          "type": "string",
          "example": "lstn_01h2xcejqtf2nbrexx3vqjhp50"
        }
      },
      "OrderId": {
        "name": "order_id",
        "in": "path",
        "required": true,
        "description": "Phone number order identifier",
        "schema": {
          "type": "string",
          "example": "nord_01h2xcejqtf2nbrexx3vqjhp47"
        }
      },
      "PortOrderId": {
        "name": "order_id",
        "in": "path",
        "required": true,
        "description": "Port order identifier",
        "schema": {
          "type": "string",
          "example": "por_01h2xcejqtf2nbrexx3vqjhp53"
        }
      },
      "PhoneNumberId": {
        "name": "phone_number_id",
        "in": "path",
        "required": true,
        "description": "Phone number identifier",
        "schema": {
          "type": "string",
          "example": "did_01h2xcejqtf2nbrexx3vqjhp46"
        }
      },
      "PhoneNumberStatus": {
        "name": "status",
        "in": "query",
        "required": false,
        "description": "Filter by phone number status",
        "schema": {
          "type": "string",
          "enum": [
            "active",
            "inactive",
            "pending",
            "released"
          ],
          "example": "active"
        }
      },
      "NumberOrderStatus": {
        "name": "status",
        "in": "query",
        "required": false,
        "description": "Filter by order status",
        "schema": {
          "type": "string",
          "enum": [
            "pending",
            "complete",
            "partial",
            "failed"
          ]
        }
      },
      "NumberOrderType": {
        "name": "order_type",
        "in": "query",
        "required": false,
        "description": "Filter by order type",
        "schema": {
          "type": "string",
          "enum": [
            "order",
            "disconnect"
          ]
        }
      },
      "LocationId": {
        "name": "location_id",
        "in": "path",
        "required": true,
        "description": "Location identifier",
        "schema": {
          "type": "string",
          "example": "loc_01h2xcejqtf2nbrexx3vqjhp50"
        }
      },
      "LocationStatus": {
        "name": "status",
        "in": "query",
        "required": false,
        "description": "Filter by location status",
        "schema": {
          "type": "string",
          "enum": [
            "active",
            "inactive"
          ],
          "example": "active"
        }
      },
      "DeviceLineId": {
        "name": "line_id",
        "in": "path",
        "required": true,
        "description": "Device line identifier",
        "schema": {
          "type": "string",
          "example": "dln_01h2xcejqtf2nbrexx3vqjhp55"
        }
      },
      "DeviceTypeFilter": {
        "name": "type",
        "in": "query",
        "required": false,
        "description": "Filter devices by type",
        "schema": {
          "type": "string",
          "enum": [
            "deskphone",
            "dect_base"
          ]
        }
      },
      "PortOrderStatus": {
        "name": "status",
        "in": "query",
        "required": false,
        "description": "Filter by port order status",
        "schema": {
          "type": "string",
          "enum": [
            "draft",
            "approved",
            "submitted",
            "exception",
            "foc",
            "complete",
            "cancelled"
          ]
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Number of objects to return.\nDefaults to 10. Maximum is 100.\n",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 10,
          "example": 10
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Account does not belong to this platform",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AccountNotFound": {
        "description": "Account not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "UserNotFound": {
        "description": "User not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "VoicemailNotFound": {
        "description": "Voicemail not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "CallNotFound": {
        "description": "Call log not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ListenerNotFound": {
        "description": "Listener not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "CallNotActive": {
        "description": "Call is not in a state that supports listeners (e.g., still ringing, already ended)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "TranscriptNotFound": {
        "description": "Transcript not found (no recording exists for this call)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RecordingNotFound": {
        "description": "Recording not found (no recording exists for this call)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "VoiceAppNotFound": {
        "description": "Voice app not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AccountDeleted": {
        "description": "Account deleted successfully"
      },
      "UserDeleted": {
        "description": "User deleted successfully"
      },
      "VoicemailDeleted": {
        "description": "Voicemail deleted successfully"
      },
      "VoiceAppDeleted": {
        "description": "Voice app deleted successfully"
      },
      "AIAgentNotFound": {
        "description": "AI agent not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AIAgentDeleted": {
        "description": "AI agent deleted successfully"
      },
      "ScheduleNotFound": {
        "description": "Schedule not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ScheduleDeleted": {
        "description": "Schedule deleted successfully"
      },
      "DialPlanNotFound": {
        "description": "Dial plan not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DialPlanDeleted": {
        "description": "Dial plan deleted successfully"
      },
      "RoutingLoop": {
        "description": "Operation would create a routing loop",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "routing loop detected: rg_01h2x... → dp_01h2x... → rg_01h2x..."
            }
          }
        }
      },
      "ExtensionNotFound": {
        "description": "Extension not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ExtensionDeleted": {
        "description": "Extension deleted successfully"
      },
      "ExtensionConflict": {
        "description": "Extension number already exists in this account",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DialPlanConflict": {
        "description": "Dial plan cannot be deleted because it is referenced by an extension",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RingGroupNotFound": {
        "description": "Ring group not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RingGroupMemberNotFound": {
        "description": "Ring group member not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RingGroupDeleted": {
        "description": "Ring group deleted successfully"
      },
      "RingGroupMemberDeleted": {
        "description": "Ring group member removed successfully"
      },
      "RingGroupConflict": {
        "description": "Ring group cannot be deleted because it is referenced by an extension",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AudioClipNotFound": {
        "description": "Audio clip not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AudioClipDeleted": {
        "description": "Audio clip deleted successfully"
      },
      "SharedVoicemailBoxNotFound": {
        "description": "Shared voicemail box not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "SharedVoicemailBoxDeleted": {
        "description": "Shared voicemail box deleted successfully"
      },
      "SharedVoicemailBoxConflict": {
        "description": "Shared voicemail box cannot be deleted because it is referenced by an extension",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PhoneNumberNotFound": {
        "description": "Phone number not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NumberOrderNotFound": {
        "description": "Number order not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "LocationNotFound": {
        "description": "Location not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PortOrderNotFound": {
        "description": "Port order not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "LocationDeleted": {
        "description": "Location deleted successfully"
      },
      "DeviceNotFound": {
        "description": "Device not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DeviceLineNotFound": {
        "description": "Device line not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DeviceDeleted": {
        "description": "Device deleted successfully"
      },
      "DeviceLineDeleted": {
        "description": "Device line deleted successfully"
      },
      "DocumentNotFound": {
        "description": "Document not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "HardwareOrderNotFound": {
        "description": "Hardware order not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict with current state of the resource",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadGateway": {
        "description": "Upstream provider error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "AuthTokenRequest": {
        "type": "object",
        "required": [
          "grant_type",
          "account_id",
          "subject_token",
          "subject_token_type"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": [
              "token_exchange"
            ],
            "description": "Authentication method. Currently only `token_exchange` is supported."
          },
          "account_id": {
            "type": "string",
            "description": "Account the user belongs to",
            "examples": [
              "acct_01h2xcejqtf2nbrexx3vqjhp41"
            ]
          },
          "subject_token": {
            "type": "string",
            "description": "Your platform's JWT for the user being authenticated"
          },
          "subject_token_type": {
            "type": "string",
            "description": "Token type URI",
            "examples": [
              "urn:ietf:params:oauth:token-type:jwt"
            ]
          }
        }
      },
      "AuthTokenResponse": {
        "type": "object",
        "required": [
          "token",
          "token_type",
          "expires_at",
          "expires_in",
          "user"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "User token for authenticating client-side requests",
            "examples": [
              "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
            ]
          },
          "token_type": {
            "type": "string",
            "const": "bearer",
            "description": "Always `bearer`"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp when the token expires"
          },
          "expires_in": {
            "type": "integer",
            "description": "Seconds until the token expires",
            "examples": [
              3600
            ]
          },
          "user": {
            "$ref": "#/components/schemas/AuthUser"
          }
        }
      },
      "AuthUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "User identifier"
          },
          "name": {
            "type": "string",
            "description": "User's display name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User's email address"
          },
          "account_id": {
            "type": "string",
            "description": "Account the user belongs to"
          }
        }
      },
      "AuthRefreshRequest": {
        "type": "object",
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "Current user token to refresh"
          }
        }
      },
      "AuthRevokeRequest": {
        "type": "object",
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "User token to revoke"
          }
        }
      },
      "IceServersResponse": {
        "type": "object",
        "required": [
          "ice_servers",
          "expires_at"
        ],
        "properties": {
          "ice_servers": {
            "type": "array",
            "description": "List of ICE server configurations for WebRTC peer connections",
            "items": {
              "$ref": "#/components/schemas/IceServer"
            }
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the TURN credentials expire. Fetch new credentials before this time."
          }
        }
      },
      "IceServer": {
        "type": "object",
        "required": [
          "urls"
        ],
        "properties": {
          "urls": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "STUN or TURN server URL(s)",
            "examples": [
              "stun:stun.dialstack.ai:3478",
              "turn:turn.dialstack.ai:443?transport=tcp"
            ]
          },
          "username": {
            "type": "string",
            "description": "TURN username (not present for STUN servers)"
          },
          "credential": {
            "type": "string",
            "description": "TURN credential (not present for STUN servers)"
          }
        }
      },
      "UserProfile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "User identifier"
          },
          "name": {
            "type": "string",
            "description": "User's display name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User's email address"
          },
          "account_id": {
            "type": "string",
            "description": "Account the user belongs to"
          },
          "extensions": {
            "type": "array",
            "description": "User's assigned extension dial codes",
            "items": {
              "type": "object",
              "properties": {
                "number": {
                  "type": "string",
                  "description": "Extension dial code"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "active",
                    "inactive"
                  ]
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PresenceStatus": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "user_id": {
            "type": "string",
            "description": "User identifier"
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "on_call",
              "dnd",
              "away",
              "offline"
            ],
            "description": "Current presence status:\n- `available` — user is online and can receive calls\n- `on_call` — user is currently on an active call\n- `dnd` — user has enabled Do Not Disturb\n- `away` — user is away (idle timeout or manual)\n- `offline` — no active WebRTC or SIP registration\n"
          },
          "status_text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional custom status message"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the presence status last changed"
          }
        }
      },
      "PresenceUpdateRequest": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "available",
              "dnd",
              "away"
            ],
            "description": "Desired presence status (cannot set `on_call` or `offline` manually)"
          },
          "status_text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional custom status message (max 100 characters)"
          }
        }
      },
      "EmergencyAddress": {
        "type": "object",
        "description": "Validated emergency address for E911",
        "required": [
          "street",
          "city",
          "state",
          "zip",
          "country",
          "validated"
        ],
        "properties": {
          "street": {
            "type": "string",
            "description": "Street address",
            "examples": [
              "123 Main St"
            ]
          },
          "street2": {
            "type": [
              "string",
              "null"
            ],
            "description": "Suite, floor, apartment, or room number",
            "examples": [
              "Suite 400"
            ]
          },
          "city": {
            "type": "string",
            "examples": [
              "San Francisco"
            ]
          },
          "state": {
            "type": "string",
            "description": "Two-letter state/province code",
            "examples": [
              "CA"
            ]
          },
          "zip": {
            "type": "string",
            "examples": [
              "94105"
            ]
          },
          "country": {
            "type": "string",
            "description": "Two-letter country code (ISO 3166-1 alpha-2)",
            "examples": [
              "US"
            ]
          },
          "validated": {
            "type": "boolean",
            "description": "Whether the address has been validated against the MSAG"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EmergencyAddressRequest": {
        "type": "object",
        "required": [
          "street",
          "city",
          "state",
          "zip",
          "country"
        ],
        "properties": {
          "street": {
            "type": "string",
            "description": "Street address"
          },
          "street2": {
            "type": [
              "string",
              "null"
            ],
            "description": "Suite, floor, apartment, or room number"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "description": "Two-letter state/province code"
          },
          "zip": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "description": "Two-letter country code (ISO 3166-1 alpha-2)"
          }
        }
      },
      "HardwareCatalogItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Hardware catalog item ID"
          },
          "manufacturer": {
            "type": "string",
            "description": "Hardware manufacturer",
            "example": "SNOM"
          },
          "model": {
            "type": "string",
            "description": "Product model name",
            "example": "M500"
          },
          "sku": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stock-keeping unit identifier"
          },
          "device_type": {
            "type": "string",
            "enum": [
              "deskphone",
              "dect_base",
              "dect_handset"
            ],
            "description": "Type of device"
          },
          "active": {
            "type": "boolean",
            "description": "Whether the item is available for selection"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "HardwareOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Hardware order ID"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "fulfilled",
              "cancelled"
            ],
            "description": "Order lifecycle status"
          },
          "items": {
            "type": "array",
            "description": "Line items in the order",
            "items": {
              "$ref": "#/components/schemas/HardwareOrderItem"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "HardwareOrderItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Hardware order item ID"
          },
          "hardware_catalog_id": {
            "type": "string",
            "description": "Reference to hardware catalog item"
          },
          "quantity": {
            "type": "integer",
            "description": "Number of units",
            "minimum": 1,
            "maximum": 100
          },
          "hardware_catalog": {
            "$ref": "#/components/schemas/HardwareCatalogItem"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "HardwareOrderRequest": {
        "type": "object",
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "hardware_catalog_id",
                "quantity"
              ],
              "properties": {
                "hardware_catalog_id": {
                  "type": "string",
                  "description": "ID of the hardware catalog item"
                },
                "quantity": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 100
                }
              }
            }
          }
        }
      },
      "EntityId": {
        "type": "string",
        "description": "Unique identifier",
        "example": "acct_01h2xcejqtf2nbrexx3vqjhp41"
      },
      "EntityName": {
        "type": [
          "string",
          "null"
        ],
        "minLength": 1,
        "maxLength": 255,
        "description": "Display name",
        "example": "Spineline"
      },
      "CreatedAt": {
        "type": "string",
        "format": "date-time",
        "description": "Timestamp when it was created",
        "example": "2025-10-17T14:30:00Z"
      },
      "UpdatedAt": {
        "type": "string",
        "format": "date-time",
        "description": "Timestamp when it was last updated",
        "example": "2025-10-17T14:30:00Z"
      },
      "ClientSecret": {
        "type": "string",
        "description": "JWT token for account-scoped authentication",
        "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50X2lkIjoiYWNjdF8wMWgyeGNlanF0ZjJuYnJleHgzdnFqaHA0MSIsImp0aSI6IjAxaDJ4Y2VqcXRmMm5icmV4eDN2cWpocDQ2IiwiZXhwIjoxNzI2NzU3MjAwfQ.1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2"
      },
      "SessionExpiresAt": {
        "type": "string",
        "format": "date-time",
        "description": "When the session expires",
        "example": "2025-11-13T15:00:00Z"
      },
      "ListObject": {
        "type": "string",
        "enum": [
          "list"
        ],
        "description": "String representing the object's type. Always \"list\" for list responses."
      },
      "ListUrl": {
        "type": "string",
        "description": "The URL for accessing this list.",
        "example": "/v1/accounts"
      },
      "NextPageUrl": {
        "type": [
          "string",
          "null"
        ],
        "description": "URL to fetch the next page of results. If `null`, there are no more pages.\nThe URL includes all necessary parameters including the pagination cursor.\n",
        "example": "/v1/accounts?page=eyJzdGFydGluZ19hZnRlciI6ImFjY3RfMDFoMnhjZWpxdGYybmJyZXh4M3ZxamhwNDEiLCJsaW1pdCI6MTB9"
      },
      "PreviousPageUrl": {
        "type": [
          "string",
          "null"
        ],
        "description": "URL to fetch the previous page of results. If `null`, this is the first page.\nThe URL includes all necessary parameters including the pagination cursor.\n",
        "example": "/v1/accounts?page=eyJlbmRpbmdfYmVmb3JlIjoiYWNjdF8wMWgyeGNlanF0ZjJuYnJleHgzdnFqaHA0MSIsImxpbWl0IjoxMH0"
      },
      "Account": {
        "type": "object",
        "description": "A customer organization of a vSaaS platform (e.g., Jones Chiropractic using Spineline)",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "description": "Email address for the account (optional)",
            "example": "contact@example.com"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Company or organization name",
            "example": "Acme Corp"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Phone number in E.164 format",
            "example": "+12125550100"
          },
          "primary_contact_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name of the primary contact",
            "example": "Jane Doe"
          },
          "config": {
            "$ref": "#/components/schemas/AccountConfig"
          },
          "default_outbound_did_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of the phone number to use as the default outbound caller ID. When null, the first outbound-enabled number is used."
          },
          "provisioning_base_url": {
            "type": [
              "string",
              "null"
            ],
            "readOnly": true,
            "description": "The full provisioning base URL for this account. Phones use this URL prefix for auto-provisioning configuration files.",
            "example": "https://prov.netvoice.io/a/abc12345"
          },
          "billing_address": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ],
            "description": "The account's billing/business address, geocoded via address validation. Null if not set."
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "config",
          "created_at"
        ]
      },
      "AccountConfig": {
        "type": "object",
        "description": "Account-level configuration settings",
        "properties": {
          "region": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code for the account. Used for region-specific features. Defaults to \"US\".",
            "example": "US"
          },
          "extension_length": {
            "type": "integer",
            "minimum": 3,
            "maximum": 6,
            "description": "Number of digits for extension numbers (3-6). Defaults to 4.",
            "example": 4
          },
          "transcription_enabled": {
            "type": "boolean",
            "description": "Whether calls are transcribed. Defaults to true.",
            "example": true
          },
          "recording_enabled": {
            "type": "boolean",
            "description": "Whether call audio recordings are retained. Defaults to true.",
            "example": true
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for the account (e.g., \"America/New_York\"). Used as the default timezone for schedules when not explicitly set. Defaults to \"UTC\".",
            "example": "America/New_York"
          },
          "max_phone_numbers": {
            "type": "integer",
            "minimum": 1,
            "description": "Maximum number of phone numbers the account can hold. Defaults to 25.",
            "example": 25
          },
          "parking_timeout_seconds": {
            "type": "integer",
            "minimum": 1,
            "description": "Duration in seconds before a parked call rings back the parker. Defaults to 300 (5 minutes).",
            "example": 300
          }
        }
      },
      "User": {
        "type": "object",
        "description": "A person with phone service (may have multiple devices/endpoints)",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityName"
              }
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "description": "Email address (optional)",
            "example": "alice@spineline.dev"
          },
          "account_role": {
            "type": [
              "string",
              "null"
            ],
            "description": "The user's role within the account (null for regular users)",
            "enum": [
              "account_admin",
              null
            ],
            "example": null
          },
          "outbound_caller_id_did_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of the phone number to use as this user's outbound caller ID, overriding the account default. When null, the account default is used."
          },
          "voicemail_pin": {
            "type": [
              "string",
              "null"
            ],
            "description": "Numeric PIN for remote voicemail access (4-10 digits). When null, no PIN is set.",
            "example": "1234"
          },
          "config": {
            "$ref": "#/components/schemas/UserConfig"
          },
          "extensions": {
            "description": "List of extensions assigned to this user. Only included when `expand[]=extensions` is requested.\n",
            "type": "object",
            "properties": {
              "object": {
                "type": "string",
                "enum": [
                  "list"
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id"
        ]
      },
      "UserConfig": {
        "type": "object",
        "description": "User-level configuration settings",
        "properties": {
          "voicemail_notifications": {
            "$ref": "#/components/schemas/VoicemailNotificationConfig"
          },
          "find_me_follow_me": {
            "$ref": "#/components/schemas/FMFM"
          }
        }
      },
      "FMFM": {
        "type": "object",
        "description": "Find Me / Follow Me call routing configuration. Steps are tried sequentially; within each step, all targets ring simultaneously.",
        "required": [
          "steps",
          "fallback"
        ],
        "properties": {
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FMFMStep"
            },
            "minItems": 1,
            "maxItems": 5
          },
          "fallback": {
            "type": "string",
            "enum": [
              "voicemail",
              "hangup",
              "target"
            ],
            "description": "Action when all steps are exhausted without an answer. When `target`, routes to the resource specified by `fallback_target_id`."
          },
          "fallback_target_id": {
            "type": "string",
            "description": "ID of the routing target for fallback. Required when fallback is `target`. Accepts user, ring group, voice app, dial plan, or shared voicemail IDs."
          }
        }
      },
      "FMFMStep": {
        "type": "object",
        "description": "A single ring step. All targets ring simultaneously with a shared timeout.",
        "required": [
          "targets",
          "timeout"
        ],
        "properties": {
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FMFMTarget"
            },
            "minItems": 1,
            "maxItems": 10
          },
          "timeout": {
            "type": "integer",
            "minimum": 1,
            "maximum": 120,
            "description": "How long to ring all targets in this step (seconds)."
          }
        }
      },
      "FMFMTarget": {
        "type": "object",
        "description": "A target to ring within a step.",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "external",
              "user"
            ],
            "description": "Target type:\n- `external` — dial a PSTN phone number.\n- `user` — ring a user's SIP endpoints (can be the current user or another user).\n"
          },
          "number": {
            "type": "string",
            "description": "Phone number in E.164 format. Required when type is `external`.",
            "example": "+15551234567"
          },
          "id": {
            "type": "string",
            "description": "ID of the user to ring. Required when type is `user`."
          }
        }
      },
      "VoicemailNotificationConfig": {
        "type": "object",
        "description": "Voicemail email notification preferences",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether voicemail email notifications are enabled (user voicemails only)",
            "default": false
          },
          "attach_audio": {
            "type": "boolean",
            "description": "Attach the voicemail audio file (MP3) to the email. Forced true when delete_after_email is true.",
            "default": true
          },
          "include_summary": {
            "type": "boolean",
            "description": "Include the AI-generated summary in the email. When true, email is sent after transcription completes.",
            "default": true
          },
          "include_transcript": {
            "type": "boolean",
            "description": "Include the full transcript in the email. When true, email is sent after transcription completes.",
            "default": true
          },
          "delete_after_email": {
            "type": "boolean",
            "description": "Automatically delete the voicemail after the notification email is sent. Implies attach_audio.",
            "default": false
          }
        }
      },
      "Voicemail": {
        "type": "object",
        "description": "A voicemail message with audio recording. Each voicemail has exactly\none owner — either a user or a shared voicemail box.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "owner": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "ID of the owner — either the user who received the voicemail or the shared voicemail box it was left in."
              }
            ]
          },
          "from_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Caller's phone number",
            "example": "+14155551234"
          },
          "from_name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 255,
            "description": "Caller's name (if available from caller ID)",
            "example": "John Smith"
          },
          "duration_seconds": {
            "type": "integer",
            "minimum": 0,
            "description": "Length of the voicemail recording in seconds",
            "example": 42
          },
          "format": {
            "type": "string",
            "maxLength": 10,
            "description": "Audio format",
            "example": "mp3"
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "URL for downloading the audio recording",
            "example": "https://voicemails.dialstack.ai/550e8400-e29b-41d4-a716-446655440000/20251018-143000_John_Smith.mp3"
          },
          "is_read": {
            "type": "boolean",
            "description": "Whether the voicemail has been listened to",
            "example": false
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "read_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the voicemail was marked as read",
            "example": "2025-10-18T15:00:00Z"
          },
          "summary": {
            "type": [
              "string",
              "null"
            ],
            "description": "AI-generated summary of the voicemail content. Null if transcription not yet processed.",
            "example": "John Smith called to reschedule his Thursday appointment to Friday."
          }
        },
        "required": [
          "id",
          "owner",
          "from_number",
          "duration_seconds",
          "format",
          "audio_url",
          "is_read",
          "created_at"
        ]
      },
      "VoicemailGreetingResponse": {
        "type": "object",
        "description": "A custom voicemail greeting that replaces the system-default prompts\nfor a user mailbox or a shared voicemail box. Each (owner, type) pair\nhas at most one greeting — re-uploading overwrites.\n",
        "properties": {
          "owner": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "ID of the owner — either the user whose mailbox the greeting belongs to, or the shared voicemail box it belongs to."
              }
            ]
          },
          "greeting_type": {
            "type": "string",
            "description": "The greeting variant. Today only `unavailable` is supported —\nthe full custom greeting that replaces the system prompts\n(caller hears it when the owner does not answer).\n",
            "enum": [
              "unavailable"
            ]
          },
          "format": {
            "type": "string",
            "description": "Audio format of the stored greeting.",
            "enum": [
              "wav"
            ],
            "example": "wav"
          },
          "duration_seconds": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "description": "Length of the greeting audio in seconds.",
            "example": 12.4
          },
          "size_bytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Size of the stored greeting audio in bytes (post-transcode).",
            "example": 98560
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Short-lived signed URL (5 minutes) for downloading the greeting audio."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the greeting was last uploaded or replaced."
          }
        },
        "required": [
          "owner",
          "greeting_type",
          "format",
          "duration_seconds",
          "size_bytes",
          "url",
          "updated_at"
        ]
      },
      "AuditLogEntry": {
        "type": "object",
        "description": "A single audit log entry recording an API operation",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the audit log entry"
          },
          "actor": {
            "type": "string",
            "description": "Identifier of the actor that performed the operation"
          },
          "event": {
            "type": "string",
            "description": "Type of event (e.g., `user.create`, `auth.denied`)"
          },
          "resource": {
            "type": "string",
            "description": "Identifier of the affected resource"
          },
          "outcome": {
            "type": "string",
            "description": "Result of the operation",
            "enum": [
              "success",
              "failure",
              "denied"
            ]
          },
          "ip_address": {
            "type": "string",
            "description": "Client IP address"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the event occurred"
          }
        },
        "required": [
          "id",
          "event",
          "outcome",
          "ip_address",
          "timestamp"
        ]
      },
      "CallLog": {
        "type": "object",
        "description": "Record of a completed or attempted call. The `id` is an opaque call\nlog identifier — a single call log may span multiple underlying call\nlegs, so it does not correspond to any single leg.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "user_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "type": "null"
              }
            ],
            "description": "The user associated with this call"
          },
          "endpoint_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "type": "null"
              }
            ],
            "description": "The endpoint (device) that handled this call"
          },
          "did_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "type": "null"
              }
            ],
            "description": "The DID (phone number) used for this call"
          },
          "direction": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound",
              "internal"
            ],
            "description": "Call direction (inbound from PSTN, outbound to PSTN, or internal extension-to-extension)",
            "example": "inbound"
          },
          "from_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Caller's phone number",
            "example": "+14155551234"
          },
          "from_label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display label for the caller, resolved from the extension's target name (user, dial plan, voice app, or ring group). Null if the number does not match an extension.",
            "example": "Front Desk"
          },
          "to_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Recipient's phone number",
            "example": "+14155559876"
          },
          "to_label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display label for the recipient, resolved from the extension's target name (user, dial plan, voice app, or ring group). Null if the number does not match an extension.",
            "example": "Sales Queue"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the call was initiated",
            "example": "2025-10-18T14:30:00Z"
          },
          "answered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the call was answered",
            "example": "2025-10-18T14:30:05Z"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the call ended",
            "example": "2025-10-18T14:35:30Z"
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Call duration in seconds (from answer to hangup)",
            "example": 325
          },
          "status": {
            "type": "string",
            "enum": [
              "completed",
              "no-answer",
              "busy",
              "failed",
              "voicemail"
            ],
            "description": "Final call status",
            "example": "completed"
          },
          "summary": {
            "type": [
              "string",
              "null"
            ],
            "description": "AI-generated summary of the call. Null if call wasn't recorded or transcript not yet processed.",
            "example": "Customer called to reschedule appointment from Thursday to Friday due to work conflict."
          },
          "recording_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Signed URL to download the call recording audio. Null if the call was not recorded. The URL expires after 10 minutes.",
            "example": "https://cdn.example.com/recordings/2026-03-05/call.wav?Expires=1709654400&Signature=abc123"
          },
          "quality_metrics": {
            "type": "array",
            "description": "RTP quality metrics per call leg. Each call may have multiple legs (e.g., PSTN + endpoint for inbound calls). Empty for unanswered calls.",
            "items": {
              "$ref": "#/components/schemas/QualityMetricLeg"
            }
          }
        },
        "required": [
          "id",
          "direction",
          "from_number",
          "to_number",
          "started_at",
          "status"
        ]
      },
      "QualityMetricLeg": {
        "type": "object",
        "description": "RTP quality metrics for a single call leg (PSTN or endpoint)",
        "properties": {
          "leg": {
            "type": "string",
            "enum": [
              "pstn",
              "endpoint"
            ],
            "description": "Type of call leg",
            "example": "endpoint"
          },
          "endpoint_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "type": "null"
              }
            ],
            "description": "The endpoint ID for endpoint legs. Null for PSTN legs."
          },
          "jitter_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Average jitter in milliseconds during the call leg",
            "example": 5.2
          },
          "jitter_min_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Minimum jitter observed during the call leg in milliseconds",
            "example": 1
          },
          "jitter_max_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Maximum jitter observed during the call leg in milliseconds",
            "example": 15.5
          },
          "jitter_stddev_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Standard deviation of jitter during the call leg in milliseconds",
            "example": 2.3
          },
          "packet_loss_pct": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "maximum": 100,
            "description": "Packet loss percentage during the call leg",
            "example": 0.5
          },
          "rtt_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Average round-trip time (RTT) in milliseconds during the call leg",
            "example": 45
          },
          "rtt_min_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Minimum round-trip time observed during the call leg in milliseconds",
            "example": 30
          },
          "rtt_max_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Maximum round-trip time observed during the call leg in milliseconds",
            "example": 80
          },
          "rtt_stddev_ms": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "description": "Standard deviation of round-trip time during the call leg in milliseconds",
            "example": 12.5
          },
          "rx_count": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0,
            "description": "Total number of RTP packets received during the call leg",
            "example": 10000
          },
          "tx_count": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0,
            "description": "Total number of RTP packets transmitted during the call leg",
            "example": 10050
          },
          "mos": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 1,
            "maximum": 4.5,
            "description": "Mean Opinion Score (MOS) computed from RTP quality metrics using ITU-T G.107 E-model. Ranges from 1.0 (bad) to 4.5 (excellent).",
            "example": 4.2
          }
        },
        "required": [
          "leg"
        ]
      },
      "Transcript": {
        "type": "object",
        "description": "Call transcript containing transcription status and text",
        "properties": {
          "call_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The call this transcript belongs to"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "description": "Current status of the transcription:\n- `pending`: Recording uploaded, transcription not started\n- `processing`: Transcription in progress\n- `completed`: Transcription finished successfully\n- `failed`: Transcription failed\n",
            "example": "completed"
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Full text transcript. Null if transcription is not completed.",
            "example": "Hello, this is Dr. Smith calling to confirm your appointment..."
          }
        },
        "required": [
          "call_id",
          "status"
        ]
      },
      "Recording": {
        "type": "object",
        "description": "Call recording metadata with a signed download URL",
        "properties": {
          "call_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The call this recording belongs to"
              }
            ]
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Duration of the recording in seconds. Null if not available.",
            "example": 185
          },
          "file_size_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Size of the recording file in bytes. Null if not available.",
            "example": 2960000
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "Signed URL to download the recording audio file. Expires after 10 minutes.",
            "example": "https://cdn.example.com/recordings/2026-03-05/call.wav?Expires=1709654400&Signature=abc123"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the download URL expires",
            "example": "2026-03-05T15:40:00Z"
          }
        },
        "required": [
          "call_id",
          "download_url",
          "expires_at"
        ]
      },
      "VoicemailTranscript": {
        "type": "object",
        "description": "Voicemail transcript containing transcription status and text",
        "properties": {
          "voicemail_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The voicemail this transcript belongs to"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "description": "Current status of the transcription:\n- `pending`: Voicemail uploaded, transcription not started\n- `processing`: Transcription in progress\n- `completed`: Transcription finished successfully\n- `failed`: Transcription failed\n",
            "example": "completed"
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Full text transcript. Null if transcription is not completed.",
            "example": "Hi, this is John Smith calling about my appointment tomorrow..."
          }
        },
        "required": [
          "voicemail_id",
          "status"
        ]
      },
      "PhoneNumber": {
        "type": "object",
        "description": "A phone number (DID) assigned to an account for inbound/outbound calling",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "phone_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Phone number in E.164 format",
            "example": "+14155551234"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "released"
            ],
            "description": "Current status of the phone number",
            "example": "active"
          },
          "outbound_enabled": {
            "type": "boolean",
            "description": "Whether this phone number can be used for outbound calling",
            "example": true
          },
          "caller_id_name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 15,
            "description": "The caller ID name (CNAM) configured for this phone number, or null if not set",
            "example": "ACME Corp"
          },
          "directory_listing_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The business name used for directory listing (411/white pages), or null if not set",
            "example": "Acme Corporation"
          },
          "directory_listing_type": {
            "type": "string",
            "enum": [
              "listed",
              "non_listed",
              "non_published",
              "non_registered"
            ],
            "description": "How the number appears in directory services",
            "example": "listed"
          },
          "directory_listing_location_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of the location whose address is published in the directory listing, or null",
            "example": null
          },
          "routing_target": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of the target that inbound calls to this number are routed to, or null if no routing is configured",
            "example": null
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "phone_number",
          "status",
          "outbound_enabled",
          "routing_target",
          "created_at",
          "updated_at"
        ]
      },
      "AvailablePhoneNumber": {
        "type": "object",
        "description": "A phone number available for purchase",
        "properties": {
          "phone_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Phone number in E.164 format",
            "example": "+19195551234"
          },
          "city": {
            "type": "string",
            "description": "City where the number is registered",
            "example": "RALEIGH"
          },
          "state": {
            "type": "string",
            "description": "Two-letter state abbreviation",
            "example": "NC"
          },
          "rate_center": {
            "type": "string",
            "description": "Rate center for the number",
            "example": "RALEIGH"
          },
          "lata": {
            "type": "string",
            "description": "Local access and transport area",
            "example": "422"
          }
        },
        "required": [
          "phone_number"
        ]
      },
      "NumberOrder": {
        "type": "object",
        "description": "Tracks the status of a phone number purchase or disconnect request.\nPurchase orders acquire new numbers — number porting is not supported.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "order_type": {
            "type": "string",
            "enum": [
              "purchase",
              "disconnect"
            ],
            "description": "`purchase` — acquire new phone numbers.\n`disconnect` — release existing phone numbers back to the provider.\n",
            "example": "purchase"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "complete",
              "partial",
              "failed"
            ],
            "description": "`pending` — order submitted, awaiting provider confirmation.\n`complete` — all requested numbers were successfully provisioned (or released).\n`partial` — some numbers succeeded, others failed.\n`failed` — the entire order was rejected.\n",
            "example": "pending"
          },
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Phone numbers included in the order (E.164 format)",
            "example": [
              "+19195551234",
              "+19195555678"
            ]
          },
          "completed_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Phone numbers that completed successfully",
            "example": [
              "+19195551234"
            ]
          },
          "failed_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Phone numbers that failed",
            "example": []
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Error details if the order failed"
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "order_type",
          "status",
          "phone_numbers",
          "completed_numbers",
          "failed_numbers",
          "created_at",
          "updated_at"
        ]
      },
      "VoiceApp": {
        "type": "object",
        "description": "A voice app handles calls via HTTP webhook notification and optional WebSocket\naudio streaming. When a call is routed to a voice app, DialStack sends an HTTP\nPOST notification to the configured URL. The platform can then use the Update\nCall API to control the call (e.g., attach a WebSocket for bidirectional audio\nstreaming, or transfer to another extension).\n\nVoice apps also receive notifications from Voice App (Notify) dial plan nodes,\nenabling real-time call monitoring via the Listeners API without affecting call routing.\n\n## Webhook Events\n\nVoice apps receive two types of webhooks, distinguished by the `event` field:\n\n- `call.received` — The call has been routed to this voice app for handling.\n  Your server takes control of the call via the Update Call API.\n- `call.notify` — A call is passing through a Voice App (Notify) node in a dial plan.\n  The call continues routing normally. Use the Listeners API to stream audio.\n\n## Webhook Notification\n\nWhen a call arrives, DialStack sends a POST request to the voice app's URL:\n\n```\nPOST https://your-app.example.com/calls\nContent-Type: application/json\nX-DialStack-Signature: t=1697634600,v1=5257a869...\n\n{\n  \"event\": \"call.received\",\n  \"call_id\": \"call_...\",\n  \"account_id\": \"acct_...\",\n  \"voice_app_id\": \"va_...\",\n  \"from_number\": \"+14155551234\",\n  \"from_name\": \"John Smith\",\n  \"to_number\": \"+14155559876\"\n}\n```\n\n**Signature Verification:**\nThe `X-DialStack-Signature` header contains a timestamp and HMAC-SHA256 signature:\n- `t` = Unix timestamp (seconds) when signature was generated\n- `v1` = HMAC-SHA256 signature\n\nTo verify: compute `HMAC-SHA256(\"${t}.${request_body}\", voice_app_secret)` and compare.\nReject timestamps older than 5 minutes to prevent replay attacks.\n\n**Response:** Return `200 OK` to acknowledge. Response body is ignored.\n\n**Delivery:** Failed webhooks are retried with exponential backoff (3 attempts, 5-second timeout).\n\nSee [Voice Apps Guide](/guides/voice-apps) for complete examples.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "va_01h2xcejqtf2nbrexx3vqjhp49"
          },
          "name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityName"
              }
            ],
            "example": "AI Receptionist"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS webhook URL for call control notifications",
            "example": "https://ai.platform.example.com/calls"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Current status of the voice app",
            "example": "active"
          },
          "secret": {
            "type": "string",
            "description": "Webhook signing secret for this voice app. Used to verify webhook signatures.",
            "example": "whsec_abc123def456..."
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          },
          "extensions": {
            "description": "List of extensions assigned to this voice app. Only included when `expand[]=extensions` is requested.\n",
            "type": "object",
            "properties": {
              "object": {
                "type": "string",
                "enum": [
                  "list"
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "status",
          "secret",
          "created_at"
        ]
      },
      "TimeRange": {
        "type": "object",
        "description": "A time range within a specific day of the week",
        "properties": {
          "day": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6,
            "description": "Day of the week (0=Sunday, 1=Monday, ..., 6=Saturday)",
            "example": 1
          },
          "start": {
            "type": "string",
            "format": "time-local",
            "description": "Start time in HH:MM format (24-hour)",
            "example": "09:00"
          },
          "end": {
            "type": "string",
            "format": "time-local",
            "description": "End time in HH:MM format (24-hour)",
            "example": "17:00"
          }
        },
        "required": [
          "day",
          "start",
          "end"
        ]
      },
      "DateRange": {
        "type": "object",
        "description": "A date range for holidays (full days only)",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "description": "Start date (YYYY-MM-DD)",
            "example": "2025-12-25"
          },
          "end": {
            "type": "string",
            "format": "date",
            "description": "End date (YYYY-MM-DD), inclusive",
            "example": "2025-12-25"
          }
        },
        "required": [
          "start",
          "end"
        ]
      },
      "ScheduleHold": {
        "type": "object",
        "description": "Temporary hold override for a schedule. When set, the hold value overrides\nthe normal schedule calculation until the specified time.\n",
        "properties": {
          "value": {
            "type": "boolean",
            "description": "Override value (true=force open, false=force closed)",
            "example": false
          },
          "until": {
            "type": "string",
            "format": "date-time-local",
            "description": "When the hold expires. Interpreted in the schedule's timezone.\n",
            "example": "2025-12-20T17:00:00"
          }
        },
        "required": [
          "value",
          "until"
        ]
      },
      "Schedule": {
        "type": "object",
        "description": "A business hours schedule for call routing. Schedules define when the business\nis open based on weekly time ranges and holidays. A temporary hold can override\nthe schedule calculation.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "sched_01h2xcejqtf2nbrexx3vqjhp50"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the schedule",
            "example": "Business Hours"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ],
            "description": "IANA timezone for interpreting times (e.g., \"America/New_York\"). If null, uses account default.",
            "example": "America/New_York"
          },
          "ranges": {
            "type": "array",
            "description": "Weekly time ranges when the schedule is considered \"open\"",
            "items": {
              "$ref": "#/components/schemas/TimeRange"
            },
            "example": [
              {
                "day": 1,
                "start": "09:00",
                "end": "17:00"
              },
              {
                "day": 2,
                "start": "09:00",
                "end": "17:00"
              }
            ]
          },
          "holidays": {
            "type": "array",
            "description": "Date ranges when the schedule is closed regardless of weekly ranges",
            "items": {
              "$ref": "#/components/schemas/DateRange"
            },
            "example": [
              {
                "start": "2025-12-25",
                "end": "2025-12-25"
              }
            ]
          },
          "hold": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ScheduleHold"
              },
              {
                "type": "null"
              }
            ],
            "description": "Temporary override for the schedule"
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "ranges",
          "created_at"
        ]
      },
      "AccountRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address for the account",
            "example": "contact@example.com"
          },
          "name": {
            "type": "string",
            "description": "Company or organization name",
            "example": "Acme Corp"
          },
          "phone": {
            "type": "string",
            "description": "Phone number in E.164 format",
            "example": "+12125550100"
          },
          "primary_contact_name": {
            "type": "string",
            "description": "Name of the primary contact",
            "example": "Jane Doe"
          },
          "config": {
            "$ref": "#/components/schemas/AccountConfig"
          }
        }
      },
      "CreateAccountRequest": {
        "$ref": "#/components/schemas/AccountRequest"
      },
      "UpdateAccountRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AccountRequest"
          },
          {
            "type": "object",
            "properties": {
              "default_outbound_did_id": {
                "type": "string",
                "description": "ID of the phone number to use as the default outbound caller ID. Send null to clear."
              },
              "billing_address": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/AddressInput"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Billing/business address. When present, the address is geocoded via address validation. Send null to clear. Omit to leave unchanged."
              }
            }
          }
        ]
      },
      "UserRequest": {
        "type": "object",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/EntityName"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address (optional)",
            "example": "bob@spineline.dev"
          }
        }
      },
      "CreateUserRequest": {
        "$ref": "#/components/schemas/UserRequest"
      },
      "UpdateUserRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/UserRequest"
          },
          {
            "type": "object",
            "properties": {
              "outbound_caller_id_did_id": {
                "type": "string",
                "description": "ID of the phone number to use as this user's outbound caller ID, overriding the account default. Send null to clear."
              },
              "voicemail_pin": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Numeric PIN for remote voicemail access (4-10 digits). Send null to clear.",
                "example": "1234"
              },
              "config": {
                "type": "object",
                "description": "User configuration. Only provided fields are updated; omitted fields are left unchanged.",
                "properties": {
                  "voicemail_notifications": {
                    "$ref": "#/components/schemas/VoicemailNotificationConfig"
                  },
                  "find_me_follow_me": {
                    "description": "Find Me / Follow Me configuration. Send null to clear and revert to default behavior.",
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/FMFM"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          }
        ]
      },
      "UpdateVoicemailRequest": {
        "type": "object",
        "properties": {
          "is_read": {
            "type": "boolean",
            "description": "Mark voicemail as read or unread"
          }
        }
      },
      "CreateVoiceAppRequest": {
        "type": "object",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/EntityName"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS webhook URL for call control notifications",
            "example": "https://ai.platform.example.com/calls"
          }
        },
        "required": [
          "name",
          "url"
        ]
      },
      "UpdateCallRequest": {
        "type": "object",
        "description": "Request to control an active call by sending actions",
        "properties": {
          "actions": {
            "type": "array",
            "description": "List of actions to execute on the call. Actions are processed sequentially.\nEach action may block processing or allow it to continue based on its outcome.\n\n**Supported Actions:**\n\n### attach\nConnect bidirectional audio streaming to a WebSocket URL.\n\n- `type`: `\"attach\"`\n- `url`: WebSocket URL (wss://) for bidirectional audio streaming\n\n**Processing behavior:** This action blocks processing while the WebSocket\nconnection is active. When the WebSocket disconnects (either side closes),\nprocessing resumes with the next action.\n\nSee [WebSocket API](/websocket-api) for the message protocol.\n\n### transfer\nBlind transfer the call to an extension number.\n\n- `type`: `\"transfer\"`\n- `extension`: Extension number to transfer to\n\n**Processing behavior:** If the transfer target answers or the caller hangs up,\nprocessing stops. If the transfer cannot be completed (no answer, busy, rejected),\nprocessing continues with the next action.\n",
            "items": {
              "$ref": "#/components/schemas/CallAction"
            },
            "minItems": 1
          }
        },
        "required": [
          "actions"
        ]
      },
      "CallAction": {
        "type": "object",
        "oneOf": [
          {
            "$ref": "#/components/schemas/AttachAction"
          },
          {
            "$ref": "#/components/schemas/TransferAction"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "attach": "#/components/schemas/AttachAction",
            "transfer": "#/components/schemas/TransferAction"
          }
        }
      },
      "AttachAction": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "attach"
            ],
            "description": "Action type"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "WebSocket URL (wss://) for bidirectional audio streaming",
            "example": "wss://ai.platform.example.com/voice"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Optional key/value pairs echoed on the media WebSocket `begin`\nmessage. Useful for correlating the stream with application-side\nstate (agent ID, queue, trace ID, etc.) without a separate lookup.\n",
            "example": {
              "agent_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
              "queue": "support"
            }
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "TransferAction": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "transfer"
            ],
            "description": "Action type"
          },
          "extension": {
            "type": "string",
            "description": "Extension number to transfer to",
            "example": "100"
          }
        },
        "required": [
          "type",
          "extension"
        ]
      },
      "Listener": {
        "type": "object",
        "description": "A listener streams real-time audio from an active call over a WebSocket connection.\nAudio flows unidirectionally from DialStack to your server. The call is not affected\nby the listener — both parties remain unaware that audio is being streamed.\n\nSee the [WebSocket API](/websocket-api) for the listener message protocol.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "lstn_01h2xcejqtf2nbrexx3vqjhp50"
          },
          "call_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "description": "The active call being listened to",
            "example": "call_01h2xcejqtf2nbrexx3vqjhp45"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "WebSocket URL where audio is being streamed",
            "example": "wss://your-server.example.com/audio"
          },
          "channel": {
            "type": "string",
            "enum": [
              "caller",
              "callee",
              "both"
            ],
            "description": "Which audio channel(s) to stream:\n- `caller`: audio from the party that initiated the call\n- `callee`: audio from the party that received the call\n- `both`: both channels, delivered as separate tagged messages\n",
            "example": "both"
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "call_id",
          "url",
          "channel",
          "created_at"
        ]
      },
      "CreateListenerRequest": {
        "type": "object",
        "description": "Request to create a listener on an active call",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "WebSocket URL (wss://) where DialStack will stream audio",
            "example": "wss://your-server.example.com/audio"
          },
          "channel": {
            "type": "string",
            "enum": [
              "caller",
              "callee",
              "both"
            ],
            "default": "both",
            "description": "Which audio channel(s) to stream:\n- `caller`: audio from the party that initiated the call\n- `callee`: audio from the party that received the call\n- `both`: both channels, delivered as separate tagged messages\n",
            "example": "both"
          }
        },
        "required": [
          "url"
        ]
      },
      "UpdateVoiceAppRequest": {
        "type": "object",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/EntityName"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS webhook URL for call control notifications",
            "example": "https://ai.platform.example.com/calls"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Voice app status"
          }
        }
      },
      "FAQItem": {
        "type": "object",
        "description": "A question-answer pair for the AI agent's FAQ responses.",
        "properties": {
          "question": {
            "type": "string",
            "description": "The question the AI agent should recognize",
            "maxLength": 2000,
            "example": "What are your business hours?"
          },
          "answer": {
            "type": "string",
            "description": "The answer the AI agent should provide",
            "maxLength": 2000,
            "example": "We are open Monday through Friday, 9 AM to 5 PM."
          }
        },
        "required": [
          "question",
          "answer"
        ]
      },
      "AIAgent": {
        "type": "object",
        "description": "An AI agent provides an AI-powered voice receptionist for handling incoming calls.\nEach AI agent automatically manages a voice app and extension for call routing.\nOptional instructions and FAQ responses customize the agent's behavior at call time.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "aia_01h2xcejqtf2nbrexx3vqjhp60"
          },
          "name": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityName"
              }
            ],
            "example": "Front Desk Receptionist"
          },
          "voice_app_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "description": "The managed voice app used for call routing",
            "example": "va_01h2xcejqtf2nbrexx3vqjhp49"
          },
          "persona_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name the AI agent uses to introduce itself on calls (e.g. \"Tony\"). Defaults to \"the receptionist\" if not set.",
            "maxLength": 255,
            "example": "Tony"
          },
          "greeting_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The business name used in call greetings (e.g. \"Thanks for calling [Greeting Name]\"). When not set, the account name is used as a fallback.",
            "maxLength": 255,
            "example": "Jones Family Dental"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "Custom instructions for the AI agent's behavior",
            "maxLength": 10000,
            "example": "You are the receptionist for Jones Family Dental. Be warm and professional."
          },
          "faq_responses": {
            "type": "array",
            "description": "Pre-configured question-answer pairs",
            "items": {
              "$ref": "#/components/schemas/FAQItem"
            }
          },
          "scheduling": {
            "$ref": "#/components/schemas/SchedulingConfig"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "name",
          "voice_app_id",
          "faq_responses",
          "created_at",
          "updated_at"
        ]
      },
      "CreateAIAgentRequest": {
        "type": "object",
        "description": "Request body for creating an AI agent.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the AI agent",
            "example": "Front Desk Receptionist"
          },
          "extension_number": {
            "type": "string",
            "description": "Extension number to assign for routing calls to this agent",
            "example": "200"
          },
          "persona_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name the AI agent uses to introduce itself on calls",
            "maxLength": 255,
            "example": "Tony"
          },
          "greeting_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The business name used in call greetings (e.g. \"Thanks for calling [Greeting Name]\"). When not set, the account name is used as a fallback.",
            "maxLength": 255,
            "example": "Jones Family Dental"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "Custom instructions for the AI agent's behavior",
            "maxLength": 10000,
            "example": "You are the receptionist for Jones Family Dental."
          },
          "faq_responses": {
            "type": "array",
            "description": "Pre-configured question-answer pairs",
            "items": {
              "$ref": "#/components/schemas/FAQItem"
            }
          },
          "scheduling": {
            "$ref": "#/components/schemas/SchedulingConfig"
          }
        },
        "required": [
          "name",
          "extension_number"
        ]
      },
      "UpdateAIAgentRequest": {
        "type": "object",
        "description": "Request body for updating an AI agent. All fields are optional.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the AI agent",
            "example": "Updated Receptionist"
          },
          "persona_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name the AI agent uses to introduce itself on calls",
            "maxLength": 255,
            "example": "Tony"
          },
          "greeting_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The business name used in call greetings (e.g. \"Thanks for calling [Greeting Name]\"). When not set, the account name is used as a fallback.",
            "maxLength": 255,
            "example": "Jones Family Dental"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "Custom instructions for the AI agent's behavior",
            "maxLength": 10000
          },
          "faq_responses": {
            "type": "array",
            "description": "Pre-configured question-answer pairs (replaces all existing items)",
            "items": {
              "$ref": "#/components/schemas/FAQItem"
            }
          },
          "scheduling": {
            "description": "Scheduling configuration. Replaces the entire scheduling object (not merged field-by-field). Omit entirely to leave unchanged.",
            "$ref": "#/components/schemas/SchedulingConfig"
          }
        }
      },
      "SchedulingConfig": {
        "type": "object",
        "description": "Scheduling webhook configuration. Scheduling is on when webhook_url is provided, off when absent or empty. DialStack appends standard paths to the base URL for each operation. This is a replace-all object — send the complete configuration on every update.",
        "properties": {
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "Base HTTPS URL for scheduling webhooks. DialStack appends paths for each operation: /customers/lookup, /availability/search, /bookings. Provide a URL to enable scheduling; omit or send empty to disable.",
            "maxLength": 2048
          }
        }
      },
      "CreateScheduleRequest": {
        "type": "object",
        "description": "Request body for creating a new schedule",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the schedule",
            "example": "Business Hours"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for interpreting times (e.g., \"America/New_York\")",
            "example": "America/New_York"
          },
          "ranges": {
            "type": "array",
            "description": "Weekly time ranges when the schedule is considered \"open\"",
            "items": {
              "$ref": "#/components/schemas/TimeRange"
            },
            "example": [
              {
                "day": 1,
                "start": "09:00",
                "end": "17:00"
              },
              {
                "day": 2,
                "start": "09:00",
                "end": "17:00"
              }
            ]
          },
          "holidays": {
            "type": "array",
            "description": "Date ranges when the schedule is closed regardless of weekly ranges",
            "items": {
              "$ref": "#/components/schemas/DateRange"
            }
          }
        },
        "required": [
          "name",
          "ranges"
        ]
      },
      "UpdateScheduleRequest": {
        "type": "object",
        "description": "Request body for updating a schedule (all fields optional).\nNote: The `hold` field cannot be updated via this endpoint.\nUse POST /schedules/{schedule_id}/hold to set a hold, or\nDELETE /schedules/{schedule_id}/hold to clear it.\n",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the schedule",
            "example": "Updated Business Hours"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for interpreting times",
            "example": "America/Los_Angeles"
          },
          "ranges": {
            "type": "array",
            "description": "Weekly time ranges when the schedule is considered \"open\"",
            "items": {
              "$ref": "#/components/schemas/TimeRange"
            }
          },
          "holidays": {
            "type": "array",
            "description": "Date ranges when the schedule is closed regardless of weekly ranges",
            "items": {
              "$ref": "#/components/schemas/DateRange"
            }
          }
        }
      },
      "HoldScheduleRequest": {
        "type": "object",
        "description": "Request body for setting a hold on a schedule.\nThe hold temporarily overrides the normal schedule calculation.\n",
        "properties": {
          "value": {
            "type": "boolean",
            "description": "Override value (true=force open, false=force closed)",
            "example": false
          },
          "until": {
            "type": "string",
            "format": "date-time-local",
            "description": "When the hold expires. Interpreted in the schedule's timezone.\nIf not provided, defaults to midnight (00:00:00) the next day.\n",
            "example": "2025-12-20T17:00:00"
          }
        },
        "required": [
          "value"
        ]
      },
      "DialPlan": {
        "type": "object",
        "description": "A dial plan defines how calls are routed through a series of steps,\nrepresented as a flowchart. Each step is called a **node**.\n\nSee the [Dial Plans Guide](/guides/dial-plans) for detailed documentation\nand examples.\n",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the dial plan",
            "example": "dp_01h2xcejqtf2nbrexx3vqjhp60"
          },
          "name": {
            "type": "string",
            "description": "Display name for the dial plan",
            "example": "Main Line Routing"
          },
          "entry_node": {
            "type": "string",
            "description": "ID of the first node to execute (the implicit Start node connects here)",
            "example": "check_hours"
          },
          "nodes": {
            "type": "array",
            "description": "All nodes in the dial plan graph",
            "items": {
              "$ref": "#/components/schemas/DialPlanNode"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the dial plan was created",
            "example": "2025-10-18T10:00:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the dial plan was last modified",
            "example": "2025-10-18T10:00:00Z"
          },
          "extensions": {
            "description": "List of extensions assigned to this dial plan. Only included when `expand[]=extensions` is requested.\n",
            "type": "object",
            "properties": {
              "object": {
                "type": "string",
                "enum": [
                  "list"
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "name",
          "entry_node",
          "nodes",
          "created_at",
          "updated_at"
        ]
      },
      "DialPlanNode": {
        "type": "object",
        "description": "A single step in a dial plan flowchart. Each node has a type that\ndetermines its behavior:\n\n- `schedule` — routes based on whether a schedule is currently open or closed (holidays count as closed)\n- `internal_dial` — rings an internal target (user, ring group, dial plan, voice app, or shared voicemail) with timeout handling\n- `ring_all_users` — rings every user in the account at the same time\n- `external_dial` — dials an external phone number\n- `menu` — plays an audio prompt and routes based on DTMF input (IVR)\n- `sound_clip` — plays an audio clip then routes to the next node\n\nThe shape of `config` is determined by `type` — see the individual\n`*NodeConfig` schemas.\n",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this node within the dial plan",
            "example": "check_hours"
          },
          "type": {
            "type": "string",
            "enum": [
              "schedule",
              "internal_dial",
              "ring_all_users",
              "external_dial",
              "menu",
              "sound_clip"
            ],
            "description": "The node type. Determines which `*NodeConfig` schema the `config`\nfield conforms to.\n",
            "example": "schedule"
          },
          "position": {
            "$ref": "#/components/schemas/DialPlanPosition"
          },
          "config": {
            "description": "Type-specific configuration. The schema is selected by the `type`\nfield:\n- `schedule` → `ScheduleNodeConfig`\n- `internal_dial` → `InternalDialNodeConfig`\n- `ring_all_users` → `RingAllUsersNodeConfig`\n- `external_dial` → `ExternalDialNodeConfig`\n- `menu` → `MenuNodeConfig`\n- `sound_clip` → `SoundClipNodeConfig`\n\nExit targets (the next node to execute) are embedded in the config\n(e.g. `open`/`closed` on schedule, `next` on dial nodes). A missing\nor null exit target terminates the call.\n",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ScheduleNodeConfig"
              },
              {
                "$ref": "#/components/schemas/InternalDialNodeConfig"
              },
              {
                "$ref": "#/components/schemas/RingAllUsersNodeConfig"
              },
              {
                "$ref": "#/components/schemas/ExternalDialNodeConfig"
              },
              {
                "$ref": "#/components/schemas/MenuNodeConfig"
              },
              {
                "$ref": "#/components/schemas/SoundClipNodeConfig"
              }
            ]
          }
        },
        "required": [
          "id",
          "type",
          "config"
        ]
      },
      "DialPlanPosition": {
        "type": "object",
        "description": "X/Y coordinates for visual rendering in the dial plan editor.\nOptional - if not provided, the node will be auto-positioned.\n",
        "properties": {
          "x": {
            "type": "number",
            "format": "float",
            "description": "X coordinate in the visual editor",
            "example": 200
          },
          "y": {
            "type": "number",
            "format": "float",
            "description": "Y coordinate in the visual editor",
            "example": 100
          }
        },
        "required": [
          "x",
          "y"
        ]
      },
      "ScheduleNodeConfig": {
        "type": "object",
        "description": "Configuration for `schedule` nodes. Routes the call based on whether\nthe referenced schedule is currently open or closed (holidays are\ntreated as closed).\n\nExit targets are optional — if omitted or null, the call terminates.\n",
        "properties": {
          "schedule_id": {
            "type": "string",
            "description": "ID of the schedule to check (returned by the Schedules API)",
            "example": "sched_01h2xcejqtf2nbrexx3vqjhp50"
          },
          "open": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to when the schedule is open (null = terminate call)",
            "example": "reception"
          },
          "closed": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to when the schedule is closed or on holiday (null = terminate call)",
            "example": "voicemail"
          }
        }
      },
      "InternalDialNodeConfig": {
        "type": "object",
        "description": "Configuration for `internal_dial` nodes. Rings an internal target and\nhandles no-answer / busy outcomes. If the call is answered the dial\nplan ends; otherwise it follows the `next` path (or terminates if\n`next` is missing or null).\n\n`target_id` may reference any of the following resources:\n\n- a **user** (returned by the Users API)\n- a **ring group** (returned by the Ring Groups API)\n- a nested **dial plan** (returned by the Dial Plans API)\n- a **voice app** (returned by the Voice Apps API)\n- a **shared voicemail** (returned by the Voicemails API)\n\nThe runtime dispatches on the kind of resource the `target_id` points\nto. For shared-voicemail targets, and for targets with `timeout: 0`,\nthe call is delivered straight to voicemail and the dial plan ends —\n`next` is ignored in that case.\n\n**Editor note:** the hosted dial-plan editor surfaces some of these\nshapes as distinct visual nodes (\"Voicemail\", \"Voice App\") even though\nthey are serialized as `internal_dial`. The API shape is the same.\n",
        "properties": {
          "target_id": {
            "type": "string",
            "description": "ID of the internal target to dial",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp45"
          },
          "timeout": {
            "type": "integer",
            "minimum": 0,
            "maximum": 300,
            "default": 30,
            "description": "Ring timeout in seconds (0–300). A value of `0` delivers the call\ndirectly to the target without ringing; when the target is a user\nor shared voicemail, this routes straight to voicemail.\n",
            "example": 30
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to on no-answer or busy (null = terminate call)",
            "example": "voicemail"
          }
        },
        "required": [
          "timeout"
        ]
      },
      "RingAllUsersNodeConfig": {
        "type": "object",
        "description": "Configuration for `ring_all_users` nodes. Rings every user in the\naccount at the same time and connects the first one to answer. If no\nuser answers within `timeout`, the call follows the `next` path (or\nterminates if `next` is missing or null).\n",
        "properties": {
          "timeout": {
            "type": "integer",
            "minimum": 1,
            "maximum": 300,
            "description": "Ring timeout in seconds (1–300)",
            "example": 24
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to on no-answer (null = terminate call)",
            "example": "voicemail"
          }
        },
        "required": [
          "timeout"
        ]
      },
      "ExternalDialNodeConfig": {
        "type": "object",
        "description": "Configuration for `external_dial` nodes. Dials an external phone\nnumber over the PSTN. If the call is answered the dial plan ends;\notherwise it follows the `next` path (or terminates if `next` is\nmissing or null).\n",
        "properties": {
          "phone_number": {
            "type": "string",
            "pattern": "^(\\+[1-9]\\d{1,14})?$",
            "description": "Destination phone number in E.164 format (e.g. `+14155551234`).\nMay be empty on draft dial plans; must be set before the node will\ndial.\n",
            "example": "+14155551234"
          },
          "timeout": {
            "type": "integer",
            "minimum": 1,
            "maximum": 120,
            "description": "Ring timeout in seconds (1–120)",
            "example": 60
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to on no-answer or busy (null = terminate call)",
            "example": "voicemail"
          }
        },
        "required": [
          "timeout"
        ]
      },
      "MenuNodeConfig": {
        "type": "object",
        "description": "Configuration for `menu` nodes (IVR). Plays an audio prompt and waits\nfor DTMF input. Each digit maps to a next node in the dial plan.\n\nIf the caller presses an unmapped digit, the menu replays (or routes\nto `invalid_next_node` if connected). Any unconnected exit replays\nthe menu prompt.\n",
        "properties": {
          "prompt_clip_id": {
            "type": "string",
            "description": "ID of the audio clip to play as the menu prompt (returned by\nthe Audio Clips API). May be empty on draft dial plans.\n",
            "example": "aud_01h2xcejqtf2nbrexx3vqjhp50"
          },
          "timeout": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "description": "Seconds to wait for DTMF input after the prompt finishes (1–30)",
            "example": 5
          },
          "options": {
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "description": "DTMF digit-to-node mappings",
            "items": {
              "$ref": "#/components/schemas/MenuOption"
            }
          },
          "timeout_next_node": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to when no digit is pressed (null = replay menu prompt)",
            "example": "voicemail"
          },
          "invalid_next_node": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to when an unmapped digit is pressed (null = replay menu prompt)",
            "example": "operator"
          }
        },
        "required": [
          "timeout"
        ]
      },
      "MenuOption": {
        "type": "object",
        "description": "Maps a single DTMF digit to a destination node. Omit next_node to replay the menu prompt.",
        "properties": {
          "digit": {
            "type": "string",
            "pattern": "^[0-9*#]$",
            "description": "DTMF digit: 0–9, *, or #",
            "example": "1"
          },
          "next_node": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to when this digit is pressed (null = replay menu prompt).",
            "example": "sales"
          }
        },
        "required": [
          "digit"
        ]
      },
      "SoundClipNodeConfig": {
        "type": "object",
        "description": "Configuration for `sound_clip` nodes. Plays an audio clip from the\naudio library then immediately routes to the next node.\n",
        "properties": {
          "clip_id": {
            "type": "string",
            "description": "ID of the audio clip to play (returned by the Audio Clips API).\nMay be empty on draft dial plans.\n",
            "example": "aud_01h2xcejqtf2nbrexx3vqjhp50"
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "Node ID to route to after playing the clip (null = terminate call)",
            "example": "main_menu"
          }
        }
      },
      "CreateDialPlanRequest": {
        "type": "object",
        "description": "Request body for creating a new dial plan",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the dial plan",
            "example": "Main Line Routing"
          },
          "entry_node": {
            "type": "string",
            "description": "ID of the first node to execute (optional for draft dial plans)",
            "example": "check_hours"
          },
          "nodes": {
            "type": "array",
            "description": "All nodes in the dial plan graph",
            "items": {
              "$ref": "#/components/schemas/DialPlanNode"
            }
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateDialPlanRequest": {
        "type": "object",
        "description": "Request body for updating a dial plan. All fields are optional.\nWhen `nodes` is provided, it fully replaces all nodes (not a partial node update).\n",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the dial plan",
            "example": "Updated Main Line Routing"
          },
          "entry_node": {
            "type": "string",
            "description": "ID of the first node to execute",
            "example": "check_hours"
          },
          "nodes": {
            "type": "array",
            "description": "All nodes in the dial plan graph (full replacement)",
            "items": {
              "$ref": "#/components/schemas/DialPlanNode"
            }
          }
        }
      },
      "RingGroup": {
        "type": "object",
        "description": "A ring group for parallel dialing (call forking)",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Ring group identifier",
                "example": "rg_01h2xcejqtf2nbrexx3vqjhp51"
              }
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name",
            "example": "Sales Team"
          },
          "timeout_seconds": {
            "type": "integer",
            "minimum": 5,
            "maximum": 300,
            "description": "How long to ring members before giving up (seconds)",
            "example": 30
          },
          "ignore_forwarding": {
            "type": "boolean",
            "description": "When true, ignores SIP 302 redirects (call forwarding) from devices",
            "example": false
          },
          "confirm_external": {
            "type": "boolean",
            "description": "When true, requires external (phone number) members to press a key before being connected",
            "example": false
          },
          "timeout_action": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "ring_user",
              "voicemail",
              null
            ],
            "description": "Action to take when the ring group times out",
            "example": "voicemail"
          },
          "timeout_target": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of the user or shared voicemail box to ring or send to voicemail when the ring group times out. Required when timeout_action is set.",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          },
          "extensions": {
            "description": "List of extensions assigned to this ring group. Only included when `expand[]=extensions` is requested.\n",
            "type": "object",
            "properties": {
              "object": {
                "type": "string",
                "enum": [
                  "list"
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RingGroupMember"
            },
            "description": "List of members in this ring group"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "name",
          "timeout_seconds",
          "ignore_forwarding",
          "confirm_external",
          "members",
          "created_at",
          "updated_at"
        ]
      },
      "RingGroupMember": {
        "type": "object",
        "description": "A member of a ring group (either an extension or phone number)",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Member identifier",
                "example": "rgm_01h2xcejqtf2nbrexx3vqjhp52"
              }
            ]
          },
          "ring_group_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Parent ring group"
              }
            ]
          },
          "extension": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID of a routing target",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          },
          "phone_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Dial string (E.164, local number, extension, 911, etc.)",
            "example": "+14155551234"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          }
        },
        "required": [
          "id",
          "ring_group_id",
          "created_at"
        ]
      },
      "CreateRingGroupRequest": {
        "type": "object",
        "description": "Request body for creating a ring group",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the ring group",
            "example": "Sales Team"
          },
          "timeout_seconds": {
            "type": "integer",
            "minimum": 5,
            "maximum": 300,
            "description": "How long to ring members (defaults to 20)",
            "example": 30
          },
          "ignore_forwarding": {
            "type": "boolean",
            "description": "Ignore SIP 302 redirects from devices",
            "example": false
          },
          "confirm_external": {
            "type": "boolean",
            "description": "Require external (phone number) members to press a key before being connected",
            "example": false
          },
          "timeout_action": {
            "type": "string",
            "enum": [
              "ring_user",
              "voicemail"
            ],
            "description": "Action to take when the ring group times out",
            "example": "voicemail"
          },
          "timeout_target": {
            "type": "string",
            "description": "ID of the user or shared voicemail box to ring or send to voicemail on timeout. Required when timeout_action is set.",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateRingGroupRequest": {
        "type": "object",
        "description": "Request body for updating a ring group (all fields optional).\nTo clear the timeout behavior, send `timeout_action` and `timeout_target` as `null`.\n",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "New display name",
            "example": "Support Team"
          },
          "timeout_seconds": {
            "type": "integer",
            "minimum": 5,
            "maximum": 300,
            "description": "New timeout value",
            "example": 45
          },
          "ignore_forwarding": {
            "type": "boolean",
            "description": "New ignore_forwarding setting",
            "example": true
          },
          "confirm_external": {
            "type": "boolean",
            "description": "New confirm_external setting",
            "example": true
          },
          "timeout_action": {
            "type": "string",
            "enum": [
              "ring_user",
              "voicemail"
            ],
            "description": "Action to take when the ring group times out",
            "example": "voicemail"
          },
          "timeout_target": {
            "type": "string",
            "description": "ID of the user or shared voicemail box to ring or send to voicemail on timeout. Required when timeout_action is set.",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          }
        }
      },
      "AddRingGroupMemberRequest": {
        "type": "object",
        "description": "Request body for adding a member (exactly one of extension or phone_number required)",
        "properties": {
          "extension": {
            "type": "string",
            "description": "ID of a routing target",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          },
          "phone_number": {
            "type": "string",
            "description": "Dial string (E.164, local number, extension, 911, etc.)",
            "example": "+14155551234"
          }
        }
      },
      "AudioClip": {
        "type": "object",
        "description": "An uploaded audio file for hold music, IVR prompts, or other audio playback",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Audio clip identifier"
              }
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name (unique per account)",
            "example": "Hold Music"
          },
          "url": {
            "type": "string",
            "description": "Signed URL for downloading the audio file (expires after 5 minutes)",
            "example": "https://cdn.example.com/audio-clips/clip.wav?Expires=..."
          },
          "mime_type": {
            "type": "string",
            "description": "MIME type of the stored audio file",
            "example": "audio/wav"
          },
          "duration_ms": {
            "type": "integer",
            "description": "Duration of the audio clip in milliseconds",
            "example": 30000
          },
          "size_bytes": {
            "type": "integer",
            "format": "int64",
            "description": "Size of the stored audio file in bytes",
            "example": 240000
          },
          "source_sha256": {
            "type": [
              "string",
              "null"
            ],
            "description": "SHA-256 hash of the original uploaded file (before transcoding)",
            "example": "113a95dbbfd24492fb4e527b58d64aece235d6a5057ea671dbf2fe980a9cf6a3"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "mime_type",
          "duration_ms",
          "size_bytes",
          "created_at",
          "updated_at"
        ]
      },
      "UpdateAudioClipRequest": {
        "type": "object",
        "description": "Request body for updating an audio clip (all fields optional)",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "New display name",
            "example": "Updated Hold Music"
          }
        }
      },
      "SharedVoicemailBox": {
        "type": "object",
        "description": "A shared voicemail box for team or departmental voicemail",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Shared voicemail box identifier",
                "example": "svm_01h2xcejqtf2nbrexx3vqjhp60"
              }
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name",
            "example": "Sales Voicemail"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email address to send voicemail notifications to",
            "example": "sales@example.com"
          },
          "pin": {
            "type": [
              "string",
              "null"
            ],
            "description": "PIN code for accessing the voicemail box (4-10 digits)",
            "example": "1234"
          },
          "email_attach_audio": {
            "type": "boolean",
            "description": "Whether to attach the audio recording to notification emails",
            "example": true
          },
          "email_include_summary": {
            "type": "boolean",
            "description": "Whether to include a summary in notification emails",
            "example": true
          },
          "email_include_transcript": {
            "type": "boolean",
            "description": "Whether to include a transcript in notification emails",
            "example": true
          },
          "delete_after_email": {
            "type": "boolean",
            "description": "Whether to delete the voicemail after sending the email notification",
            "example": true
          },
          "extensions": {
            "description": "List of extensions assigned to this shared voicemail box. Only included when `expand[]=extensions` is requested.\n",
            "type": "object",
            "properties": {
              "object": {
                "type": "string",
                "enum": [
                  "list"
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "name",
          "email_attach_audio",
          "email_include_summary",
          "email_include_transcript",
          "delete_after_email",
          "created_at",
          "updated_at"
        ]
      },
      "CreateSharedVoicemailBoxRequest": {
        "type": "object",
        "description": "Request body for creating a shared voicemail box",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Display name for the shared voicemail box",
            "example": "Sales Voicemail"
          },
          "email": {
            "type": "string",
            "description": "Email address to send voicemail notifications to",
            "example": "sales@example.com"
          },
          "pin": {
            "type": "string",
            "pattern": "^\\d{4,10}$",
            "description": "PIN code for accessing the voicemail box (4-10 digits)",
            "example": "1234"
          },
          "email_attach_audio": {
            "type": "boolean",
            "description": "Whether to attach the audio recording to notification emails (defaults to true)",
            "example": true
          },
          "email_include_summary": {
            "type": "boolean",
            "description": "Whether to include a summary in notification emails (defaults to true)",
            "example": true
          },
          "email_include_transcript": {
            "type": "boolean",
            "description": "Whether to include a transcript in notification emails (defaults to true)",
            "example": true
          },
          "delete_after_email": {
            "type": "boolean",
            "description": "Whether to delete the voicemail after sending the email notification (defaults to true)",
            "example": true
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateSharedVoicemailBoxRequest": {
        "type": "object",
        "description": "Request body for updating a shared voicemail box (all fields optional).\nTo clear optional fields, send them as `null`.\n",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "New display name",
            "example": "Support Voicemail"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Email address to send voicemail notifications to",
            "example": "support@example.com"
          },
          "pin": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4,10}$",
            "description": "PIN code for accessing the voicemail box (4-10 digits)",
            "example": "5678"
          },
          "email_attach_audio": {
            "type": "boolean",
            "description": "Whether to attach the audio recording to notification emails",
            "example": false
          },
          "email_include_summary": {
            "type": "boolean",
            "description": "Whether to include a summary in notification emails",
            "example": false
          },
          "email_include_transcript": {
            "type": "boolean",
            "description": "Whether to include a transcript in notification emails",
            "example": false
          },
          "delete_after_email": {
            "type": "boolean",
            "description": "Whether to delete the voicemail after sending the email notification",
            "example": false
          }
        }
      },
      "AssignUserToDeviceRequest": {
        "type": "object",
        "description": "Request body for assigning a user to a device",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "The user to assign to the deskphone",
            "example": "01h2xcejqtf2nbrexx3vqjhp42"
          }
        },
        "required": [
          "user_id"
        ]
      },
      "DeviceUserAssignment": {
        "type": "object",
        "description": "A user assigned to a device",
        "properties": {
          "user_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The assigned user",
                "example": "01h2xcejqtf2nbrexx3vqjhp42"
              }
            ]
          },
          "device_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The device",
                "example": "01h2xcejqtf2nbrexx3vqjhp50"
              }
            ]
          },
          "line_number": {
            "type": "integer",
            "minimum": 1,
            "maximum": 24,
            "description": "Physical line key number assigned to this user",
            "example": 1
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          }
        },
        "required": [
          "user_id",
          "device_id",
          "created_at"
        ]
      },
      "DeviceLine": {
        "type": "object",
        "description": "A SIP line assignment on a provisioned device, mapping a line key to a SIP endpoint",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Device line identifier",
                "example": "dln_01h2xcejqtf2nbrexx3vqjhp55"
              }
            ]
          },
          "device_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Parent device",
                "example": "dev_01h2xcejqtf2nbrexx3vqjhp50"
              }
            ]
          },
          "endpoint_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The SIP endpoint assigned to this line",
                "example": "ep_01h2xcejqtf2nbrexx3vqjhp43"
              }
            ]
          },
          "line_number": {
            "type": "integer",
            "minimum": 1,
            "maximum": 24,
            "description": "Physical line key number on the device",
            "example": 1
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "device_id",
          "endpoint_id",
          "line_number",
          "created_at",
          "updated_at"
        ]
      },
      "CreateDeviceLineRequest": {
        "type": "object",
        "description": "Request body for creating a device line",
        "properties": {
          "endpoint_id": {
            "type": "string",
            "description": "ID of the SIP endpoint to assign to this line",
            "example": "ep_01h2xcejqtf2nbrexx3vqjhp43"
          }
        },
        "required": [
          "endpoint_id"
        ]
      },
      "UpdateDeviceLineRequest": {
        "type": "object",
        "description": "Request body for reassigning a device line to a different endpoint",
        "properties": {
          "endpoint_id": {
            "type": "string",
            "description": "ID of the new SIP endpoint to assign to this line",
            "example": "ep_01h2xcejqtf2nbrexx3vqjhp44"
          }
        },
        "required": [
          "endpoint_id"
        ]
      },
      "DeviceSettings": {
        "type": [
          "object",
          "null"
        ],
        "description": "Two-tier device settings with vendor-agnostic abstractions and vendor-specific overrides.\nAll fields are optional — omitted fields inherit from the parent configuration layer\n(Global defaults → Platform → Account → Device).\n\nThis schema evolves as new hardware capabilities are supported. The `vendor_overrides`\nfield provides an escape hatch for vendor-specific parameters not yet covered by\nabstractions.\n",
        "properties": {
          "abstractions": {
            "$ref": "#/components/schemas/AbstractSettings"
          },
          "vendor_overrides": {
            "type": "object",
            "description": "Vendor-specific key-value overrides applied directly to the generated configuration.\nKeys must match the vendor's allowlisted parameter names.\n",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "ntp_server": "time.nist.gov"
            }
          }
        }
      },
      "AbstractSettings": {
        "type": "object",
        "description": "Vendor-agnostic device configuration settings",
        "properties": {
          "audio": {
            "$ref": "#/components/schemas/AudioSettings"
          },
          "display": {
            "$ref": "#/components/schemas/DisplaySettings"
          },
          "regional": {
            "$ref": "#/components/schemas/RegionalSettings"
          },
          "network": {
            "$ref": "#/components/schemas/NetworkSettings"
          },
          "features": {
            "$ref": "#/components/schemas/FeatureSettings"
          },
          "provisioning": {
            "$ref": "#/components/schemas/ProvisioningSettings"
          },
          "line_keys": {
            "type": "array",
            "description": "Programmable function key assignments. Each entry configures a physical\nbutton on the device. When provided, replaces all existing line key settings.\n",
            "items": {
              "$ref": "#/components/schemas/LineKey"
            },
            "example": [
              {
                "position": 1,
                "type": "blf",
                "label": "Reception",
                "value": "100"
              },
              {
                "position": 2,
                "type": "speed_dial",
                "label": "Support",
                "value": "+15551234567"
              },
              {
                "position": 3,
                "type": "voicemail",
                "label": "Voicemail",
                "value": "*97"
              }
            ]
          }
        }
      },
      "AudioSettings": {
        "type": "object",
        "description": "Audio codec and processing settings",
        "properties": {
          "codecs": {
            "type": "array",
            "description": "Ordered list of preferred audio codecs",
            "items": {
              "type": "string",
              "enum": [
                "PCMU",
                "PCMA"
              ]
            },
            "example": [
              "PCMU",
              "PCMA"
            ]
          },
          "vad_enabled": {
            "type": "boolean",
            "description": "Voice Activity Detection — suppresses silence packets to save bandwidth"
          },
          "echo_cancellation": {
            "type": "boolean",
            "description": "Acoustic echo cancellation"
          },
          "jitter_buffer": {
            "$ref": "#/components/schemas/JitterBuffer"
          }
        }
      },
      "JitterBuffer": {
        "type": "object",
        "description": "Jitter buffer configuration for smoothing network packet timing variations",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "adaptive",
              "fixed"
            ],
            "description": "Buffer mode — adaptive adjusts to network conditions"
          },
          "min_ms": {
            "type": "integer",
            "description": "Minimum buffer size in milliseconds",
            "example": 40
          },
          "max_ms": {
            "type": "integer",
            "description": "Maximum buffer size in milliseconds",
            "example": 200
          }
        }
      },
      "DisplaySettings": {
        "type": "object",
        "description": "Screen display preferences",
        "properties": {
          "time_format": {
            "type": "string",
            "enum": [
              "12h",
              "24h"
            ],
            "description": "Clock display format"
          },
          "date_format": {
            "type": "string",
            "enum": [
              "M/D/Y",
              "D/M/Y",
              "Y-M-D"
            ],
            "description": "Date display format"
          },
          "backlight_timeout": {
            "type": "integer",
            "description": "Backlight auto-off delay in seconds",
            "example": 30
          },
          "backlight_level": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "description": "Screen backlight brightness"
          }
        }
      },
      "RegionalSettings": {
        "type": "object",
        "description": "Localization and regional preferences",
        "properties": {
          "timezone": {
            "type": "string",
            "description": "IANA timezone identifier",
            "example": "America/New_York"
          },
          "language": {
            "type": "string",
            "description": "BCP 47 language code",
            "example": "en-US"
          },
          "tone_scheme": {
            "type": "string",
            "description": "ISO country code for dial/ring tone patterns",
            "example": "us"
          }
        }
      },
      "NetworkSettings": {
        "type": "object",
        "description": "Network and QoS configuration",
        "properties": {
          "vlan_id": {
            "type": "integer",
            "description": "VLAN tag for voice traffic"
          },
          "qos_dscp_sip": {
            "type": "integer",
            "description": "DSCP value for SIP signaling packets",
            "example": 26
          },
          "qos_dscp_rtp": {
            "type": "integer",
            "description": "DSCP value for RTP media packets",
            "example": 46
          },
          "ntp_server": {
            "type": "string",
            "description": "NTP server address for time synchronization"
          },
          "rtcp_enabled": {
            "type": "boolean",
            "description": "Enable RTCP for call quality reporting"
          }
        }
      },
      "FeatureSettings": {
        "type": "object",
        "description": "Phone feature toggles",
        "properties": {
          "dnd_enabled": {
            "type": "boolean",
            "description": "Do Not Disturb"
          },
          "call_waiting_enabled": {
            "type": "boolean",
            "description": "Call waiting notification"
          },
          "call_forward_enabled": {
            "type": "boolean",
            "description": "Call forwarding controls"
          },
          "auto_answer_enabled": {
            "type": "boolean",
            "description": "Automatically answer incoming calls (e.g., for intercom)"
          },
          "srtp_enabled": {
            "type": "boolean",
            "description": "Secure RTP for encrypted media"
          }
        }
      },
      "ProvisioningSettings": {
        "type": "object",
        "description": "Automatic resync and firmware update settings",
        "properties": {
          "resync_time": {
            "type": "string",
            "description": "Time of day to resync configuration (HH:MM in 24-hour format)",
            "example": "02:00"
          },
          "resync_mode": {
            "type": "string",
            "enum": [
              "config_and_firmware",
              "configuration",
              "firmware"
            ],
            "description": "What to resync — configuration, firmware, or both"
          },
          "bootup_check_enabled": {
            "type": "boolean",
            "description": "Check for configuration updates on device boot"
          }
        }
      },
      "LineKey": {
        "type": "object",
        "description": "A programmable function key assignment",
        "properties": {
          "position": {
            "type": "integer",
            "description": "Key position (1-based index)",
            "minimum": 1,
            "example": 1
          },
          "type": {
            "type": "string",
            "enum": [
              "blf",
              "speed_dial",
              "dtmf",
              "line",
              "voicemail",
              "url",
              "multicast",
              "conference",
              "transfer",
              "forward",
              "park",
              "intercom",
              "dnd",
              "record_toggle"
            ],
            "description": "Key function type:\n- `blf` — Busy Lamp Field, monitors another extension's presence\n- `speed_dial` — dials a preconfigured number\n- `dtmf` — sends a DTMF sequence\n- `line` — SIP line appearance\n- `voicemail` — one-touch voicemail access\n- `url` — triggers an HTTP request\n- `multicast` — multicast RTP paging\n- `conference` — conference initiation\n- `transfer` — call transfer\n- `forward` — call forwarding activation\n- `park` — call park/retrieve\n- `intercom` — intercom auto-answer call\n- `dnd` — Do Not Disturb toggle\n- `record_toggle` — call recording toggle\n"
          },
          "label": {
            "type": "string",
            "description": "Display label shown on the device screen",
            "example": "Reception"
          },
          "value": {
            "type": "string",
            "description": "Value depends on the key type: extension number (blf, speed_dial),\nphone number, DTMF sequence, URL, or multicast address.\n",
            "example": "100"
          }
        }
      },
      "ProvisioningEvent": {
        "type": "object",
        "description": "An audit log entry for a device provisioning request",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Provisioning event identifier"
              }
            ]
          },
          "device_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The device that triggered this event"
              }
            ]
          },
          "event_type": {
            "type": "string",
            "enum": [
              "config_fetch_success",
              "config_fetch_failure",
              "registration",
              "error",
              "mac_detected",
              "vendor_detected"
            ],
            "description": "Type of provisioning event:\n- `config_fetch_success` — device successfully fetched its configuration\n- `config_fetch_failure` — device failed to fetch its configuration\n- `registration` — device registered with the SIP server\n- `error` — a provisioning error occurred\n- `mac_detected` — MAC address detected from provisioning request\n- `vendor_detected` — vendor identified from MAC or User-Agent\n"
          },
          "source_ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "IP address of the device making the request",
            "example": "192.168.1.100"
          },
          "user_agent": {
            "type": "string",
            "description": "HTTP User-Agent header from the device",
            "example": "snom D785/10.1.91"
          },
          "details": {
            "type": "object",
            "description": "Additional event metadata (error messages, vendor-specific info)",
            "additionalProperties": true
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          }
        },
        "required": [
          "id",
          "device_id",
          "event_type",
          "created_at"
        ]
      },
      "Device": {
        "type": "object",
        "description": "A provisioned device (desk phone or DECT base station).\nThe `type` field indicates the device kind, and type-specific fields are only present\nfor the corresponding type.\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Device identifier"
              }
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "deskphone",
              "dect_base"
            ],
            "description": "The kind of device"
          },
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address",
            "example": "00:04:13:aa:bb:cc"
          },
          "vendor": {
            "type": "string",
            "description": "Device vendor (auto-detected from MAC address)",
            "example": "snom"
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Device model",
            "example": "D785"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending-sync",
              "provisioned"
            ],
            "description": "Current provisioning status"
          },
          "overrides": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceSettings"
              }
            ],
            "description": "Device-specific settings overrides"
          },
          "current_ip_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last known IP address of the device",
            "example": "192.168.1.100"
          },
          "last_provisioned_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last fetched its configuration"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "primary_line_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary SIP line (deskphone only)"
          },
          "lines": {
            "type": "array",
            "description": "SIP line assignments (deskphone only)",
            "items": {
              "$ref": "#/components/schemas/DeviceLine"
            }
          },
          "multicell_role": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "single",
              "data_master",
              "secondary",
              null
            ],
            "description": "Role in a multicell deployment (DECT base only)"
          },
          "max_handsets": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Maximum number of handsets supported (DECT base only)",
            "example": 30
          },
          "firmware_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current firmware version (DECT base only)"
          },
          "handsets": {
            "type": "array",
            "description": "Paired handsets (DECT base only)",
            "items": {
              "$ref": "#/components/schemas/DECTHandset"
            }
          }
        },
        "required": [
          "id",
          "type",
          "mac_address",
          "vendor",
          "status",
          "created_at",
          "updated_at"
        ]
      },
      "CreateDeviceRequest": {
        "type": "object",
        "description": "Request body for creating a device",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "deskphone",
              "dect_base",
              "dect_handset"
            ],
            "description": "The kind of device to create"
          },
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address (required for deskphones and DECT bases)",
            "example": "00:04:13:aa:bb:cc"
          },
          "model": {
            "type": "string",
            "description": "Device model (optional)",
            "example": "D785"
          },
          "overrides": {
            "$ref": "#/components/schemas/DeviceSettings"
          },
          "multicell_role": {
            "type": "string",
            "enum": [
              "single",
              "data_master",
              "secondary"
            ],
            "description": "Multicell deployment role (DECT base only, defaults to single)"
          },
          "base_id": {
            "type": "string",
            "description": "Parent DECT base identifier (required for DECT handsets)",
            "example": "01h2xcejqtf2nbrexx3vqjhp50"
          },
          "ipei": {
            "type": "string",
            "description": "DECT handset IPEI (required for DECT handsets)",
            "example": "123456789012345"
          },
          "display_name": {
            "type": "string",
            "description": "Optional display name for a DECT handset",
            "example": "Front Desk"
          }
        },
        "required": [
          "type"
        ]
      },
      "CreateDeviceResponse": {
        "type": "object",
        "description": "Minimal response returned after creating a device",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Identifier of the created device"
              }
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "deskphone",
              "dect_base",
              "dect_handset"
            ],
            "description": "The kind of device that was created"
          }
        },
        "required": [
          "id",
          "type"
        ]
      },
      "ProvisionedDevice": {
        "type": "object",
        "description": "A provisioned deskphone.",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Device identifier"
              }
            ]
          },
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address",
            "example": "00:04:13:aa:bb:cc"
          },
          "vendor": {
            "type": "string",
            "description": "Device vendor (auto-detected from MAC address)",
            "example": "snom"
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Device model",
            "example": "D785"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending-sync",
              "provisioned"
            ],
            "description": "Current provisioning status"
          },
          "overrides": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceSettings"
              }
            ],
            "description": "Device-specific settings overrides"
          },
          "current_ip_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last known IP address of the device",
            "example": "192.168.1.100"
          },
          "last_provisioned_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the device last fetched its configuration"
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          },
          "primary_line_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Primary SIP line"
          },
          "lines": {
            "type": "array",
            "description": "SIP line assignments",
            "items": {
              "$ref": "#/components/schemas/DeviceLine"
            }
          }
        },
        "required": [
          "id",
          "mac_address",
          "vendor",
          "status",
          "created_at",
          "updated_at"
        ]
      },
      "CreateDeskphoneRequest": {
        "type": "object",
        "description": "Request body for creating a deskphone",
        "properties": {
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address (vendor is auto-detected)",
            "example": "00:04:13:aa:bb:cc"
          },
          "model": {
            "type": "string",
            "description": "Device model (optional)",
            "example": "D785"
          },
          "overrides": {
            "$ref": "#/components/schemas/DeviceSettings"
          }
        },
        "required": [
          "mac_address"
        ]
      },
      "UpdateDeskphoneRequest": {
        "type": "object",
        "description": "Request body for updating a deskphone",
        "properties": {
          "model": {
            "type": "string",
            "description": "Device model"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending-sync",
              "provisioned"
            ],
            "description": "Device status"
          },
          "overrides": {
            "$ref": "#/components/schemas/DeviceSettings"
          }
        }
      },
      "DECTHandset": {
        "type": "object",
        "description": "A DECT handset paired with a base station",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Handset identifier"
              }
            ]
          },
          "base_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Parent DECT base station"
              }
            ]
          },
          "ipei": {
            "type": "string",
            "description": "International Portable Equipment Identity",
            "example": "0328A0000F"
          },
          "status": {
            "type": "string",
            "enum": [
              "unpaired",
              "pending-sync",
              "registered",
              "provisioned"
            ],
            "description": "Current handset status"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional display name"
          },
          "slot_number": {
            "type": "integer",
            "description": "Slot number on the base station",
            "example": 1
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Handset model"
          },
          "firmware_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current firmware version"
          },
          "registered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the handset was registered with the base"
          },
          "extensions": {
            "type": "array",
            "description": "SIP line assignments on this handset",
            "items": {
              "$ref": "#/components/schemas/HandsetLine"
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "base_id",
          "ipei",
          "status",
          "slot_number",
          "created_at",
          "updated_at"
        ]
      },
      "CreateHandsetRequest": {
        "type": "object",
        "description": "Request body for creating a DECT handset",
        "properties": {
          "ipei": {
            "type": "string",
            "description": "International Portable Equipment Identity",
            "example": "0328A0000F"
          },
          "display_name": {
            "type": "string",
            "description": "Optional display name"
          },
          "model": {
            "type": "string",
            "description": "Handset model"
          }
        },
        "required": [
          "ipei"
        ]
      },
      "UpdateHandsetRequest": {
        "type": "object",
        "description": "Request body for updating a DECT handset",
        "properties": {
          "ipei": {
            "type": "string",
            "description": "International Portable Equipment Identity"
          },
          "display_name": {
            "type": "string",
            "description": "Display name"
          }
        }
      },
      "HandsetLine": {
        "type": "object",
        "description": "A SIP line assignment on a DECT handset",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Handset line identifier"
              }
            ]
          },
          "handset_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "Parent handset"
              }
            ]
          },
          "endpoint_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "The SIP endpoint assigned to this line"
              }
            ]
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional display name override"
          },
          "endpoint": {
            "type": [
              "object",
              "null"
            ],
            "description": "The associated SIP endpoint (included on list responses)",
            "properties": {
              "id": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityId"
                  },
                  {
                    "description": "Endpoint identifier"
                  }
                ]
              },
              "user_id": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityId"
                  },
                  {
                    "description": "Owning user"
                  }
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Endpoint display name"
              },
              "status": {
                "type": "string",
                "enum": [
                  "online",
                  "offline"
                ],
                "description": "Registration status"
              },
              "created_at": {
                "$ref": "#/components/schemas/CreatedAt"
              },
              "updated_at": {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "handset_id",
          "endpoint_id",
          "created_at",
          "updated_at"
        ]
      },
      "CreateHandsetLineRequest": {
        "type": "object",
        "description": "Request body for creating a handset line",
        "properties": {
          "endpoint_id": {
            "type": "string",
            "description": "ID of the SIP endpoint to assign"
          },
          "display_name": {
            "type": "string",
            "description": "Optional display name override"
          }
        },
        "required": [
          "endpoint_id"
        ]
      },
      "DECTBase": {
        "type": "object",
        "description": "A DECT base station with paired wireless handsets",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              },
              {
                "description": "DECT base station identifier"
              }
            ]
          },
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address",
            "example": "00:04:13:bb:cc:dd"
          },
          "vendor": {
            "type": "string",
            "description": "Device vendor (auto-detected from MAC address)",
            "example": "snom"
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Base station model",
            "example": "M500"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending-sync",
              "provisioned"
            ],
            "description": "Current provisioning status"
          },
          "multicell_role": {
            "type": "string",
            "enum": [
              "single",
              "data_master",
              "secondary"
            ],
            "description": "Role in a multicell deployment:\n- `single` — standalone base station (default)\n- `data_master` — primary base that distributes configuration\n- `secondary` — subordinate base that receives configuration from the data master\n"
          },
          "max_handsets": {
            "type": "integer",
            "description": "Maximum number of handsets this base supports",
            "example": 30
          },
          "firmware_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current firmware version"
          },
          "overrides": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeviceSettings"
              }
            ],
            "description": "Device-specific settings overrides"
          },
          "current_ip_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last known IP address of the base station",
            "example": "192.168.1.101"
          },
          "last_provisioned_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the base last fetched its configuration"
          },
          "handsets": {
            "type": "array",
            "description": "Paired wireless handsets",
            "items": {
              "$ref": "#/components/schemas/DECTHandset"
            }
          },
          "created_at": {
            "$ref": "#/components/schemas/CreatedAt"
          },
          "updated_at": {
            "$ref": "#/components/schemas/UpdatedAt"
          }
        },
        "required": [
          "id",
          "mac_address",
          "vendor",
          "status",
          "multicell_role",
          "max_handsets",
          "created_at",
          "updated_at"
        ]
      },
      "CreateDECTBaseRequest": {
        "type": "object",
        "description": "Request body for creating a DECT base station",
        "properties": {
          "mac_address": {
            "type": "string",
            "description": "Hardware MAC address (vendor is auto-detected)",
            "example": "00:04:13:bb:cc:dd"
          },
          "model": {
            "type": "string",
            "description": "Base station model (optional, can be auto-detected)",
            "example": "M500"
          },
          "multicell_role": {
            "type": "string",
            "enum": [
              "single",
              "data_master",
              "secondary"
            ],
            "description": "Role in multicell deployment (defaults to single)"
          },
          "overrides": {
            "$ref": "#/components/schemas/DeviceSettings"
          }
        },
        "required": [
          "mac_address"
        ]
      },
      "UpdateDECTBaseRequest": {
        "type": "object",
        "description": "Request body for updating a DECT base station",
        "properties": {
          "model": {
            "type": "string",
            "description": "Base station model"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending-sync",
              "provisioned"
            ],
            "description": "Device status"
          },
          "multicell_role": {
            "type": "string",
            "enum": [
              "single",
              "data_master",
              "secondary"
            ],
            "description": "Role in multicell deployment"
          },
          "overrides": {
            "$ref": "#/components/schemas/DeviceSettings"
          }
        }
      },
      "CreateCallRequest": {
        "type": "object",
        "description": "Request to initiate an outbound call",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "The user whose endpoints will ring first. When the user answers, the destination is dialed.",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          },
          "dial_string": {
            "type": "string",
            "description": "The destination to dial after the user answers.\nCan be a phone number (E.164 or local format), an extension, or an emergency number.\n",
            "example": "+15551234567"
          }
        },
        "required": [
          "user_id",
          "dial_string"
        ]
      },
      "ComponentConfig": {
        "type": "object",
        "description": "Configuration for a single component",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether this component is enabled for the session"
          }
        },
        "required": [
          "enabled"
        ]
      },
      "CreateAccountSessionRequest": {
        "type": "object",
        "description": "Request body for creating an account session",
        "properties": {
          "account": {
            "type": "string",
            "description": "Account identifier",
            "example": "acct_01h2xcejqtf2nbrexx3vqjhp41"
          },
          "components": {
            "type": "object",
            "description": "Components to enable for this session. At least one component must have `enabled: true`.\nEach key is a component name and the value configures that component.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/ComponentConfig"
            },
            "properties": {
              "call_logs": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "voicemails": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "call_history": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "phone_number_ordering": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "phone_numbers": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "account_onboarding": {
                "$ref": "#/components/schemas/ComponentConfig"
              },
              "dial_plan_viewer": {
                "$ref": "#/components/schemas/ComponentConfig"
              }
            },
            "example": {
              "call_logs": {
                "enabled": true
              },
              "voicemails": {
                "enabled": true
              }
            }
          }
        },
        "required": [
          "account",
          "components"
        ]
      },
      "CreateSessionResponse": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account identifier for the created session",
            "example": "acct_01h2xcejqtf2nbrexx3vqjhp41"
          },
          "client_secret": {
            "$ref": "#/components/schemas/ClientSecret"
          },
          "expires_at": {
            "$ref": "#/components/schemas/SessionExpiresAt"
          }
        },
        "required": [
          "account_id",
          "client_secret",
          "expires_at"
        ]
      },
      "Extension": {
        "type": "object",
        "description": "An extension maps a short dial code (e.g., \"105\") to a routing target.\nExtensions provide a simple way for internal users to reach each other or\nfor callers to be routed through dial plans.\n",
        "properties": {
          "number": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32,
            "description": "The extension number (dial code)",
            "example": "105"
          },
          "target": {
            "type": "string",
            "maxLength": 255,
            "description": "ID of the routing target",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Extension status",
            "example": "active"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the extension was created",
            "example": "2025-10-18T10:00:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the extension was last modified",
            "example": "2025-10-18T10:00:00Z"
          }
        },
        "required": [
          "number",
          "target",
          "status",
          "created_at",
          "updated_at"
        ]
      },
      "CreateExtensionRequest": {
        "type": "object",
        "description": "Request body for creating a new extension",
        "properties": {
          "number": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32,
            "description": "The extension number (dial code)",
            "example": "105"
          },
          "target": {
            "type": "string",
            "maxLength": 255,
            "description": "ID of the routing target",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp42"
          }
        },
        "required": [
          "number",
          "target"
        ]
      },
      "UpdateExtensionRequest": {
        "type": "object",
        "description": "Request body for updating an extension (all fields optional)",
        "properties": {
          "target": {
            "type": "string",
            "maxLength": 255,
            "description": "ID of the new routing target",
            "example": "user_01h2xcejqtf2nbrexx3vqjhp43"
          }
        }
      },
      "CreateNumberOrderRequest": {
        "type": "object",
        "description": "Request body for ordering phone numbers",
        "properties": {
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Phone numbers to order (E.164 format)",
            "example": [
              "+19195551234",
              "+19195555678"
            ]
          },
          "partial_allowed": {
            "type": "boolean",
            "default": false,
            "description": "When true, the order may partially complete — available numbers are provisioned and unavailable ones are marked as failed. When false (default), the entire order fails if any number is unavailable.\n"
          }
        },
        "required": [
          "phone_numbers"
        ]
      },
      "Address": {
        "type": "object",
        "description": "A validated, normalized physical address (embedded value object)",
        "properties": {
          "place_id": {
            "type": "string",
            "description": "Geocoding place identifier"
          },
          "address_number": {
            "type": "string",
            "description": "House or building number"
          },
          "street": {
            "type": "string",
            "description": "Street name"
          },
          "unit": {
            "type": "string",
            "description": "Unit, suite, or apartment number"
          },
          "city": {
            "type": "string",
            "description": "City or locality",
            "example": "New York"
          },
          "state": {
            "type": "string",
            "description": "State or province code",
            "example": "NY"
          },
          "postal_code": {
            "type": "string",
            "description": "Postal or ZIP code",
            "example": "10001"
          },
          "country": {
            "type": "string",
            "description": "Two-letter country code",
            "example": "US"
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "WGS 84 latitude"
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "WGS 84 longitude"
          },
          "formatted_address": {
            "type": "string",
            "description": "Computed formatted address string",
            "example": "123 Main St, New York, NY 10001, US"
          }
        },
        "required": [
          "city",
          "state",
          "postal_code",
          "country",
          "formatted_address"
        ]
      },
      "Location": {
        "type": "object",
        "description": "A business location with a validated physical address",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ]
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Display name of the location",
            "example": "Main Office"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "primary_did_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The primary phone number assigned to this location"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Operational status of the location",
            "example": "active"
          },
          "e911_status": {
            "type": "string",
            "enum": [
              "none",
              "pending",
              "binding",
              "provisioned",
              "failed"
            ],
            "description": "E911 provisioning status for this location. Managed by the provider; read-only.",
            "readOnly": true,
            "example": "none"
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "address",
          "status",
          "e911_status",
          "created_at",
          "updated_at"
        ]
      },
      "E911ValidationResponse": {
        "type": "object",
        "description": "Result of E911 address validation",
        "properties": {
          "adjusted": {
            "type": "boolean",
            "description": "Whether the address was adjusted during geocoding"
          },
          "address": {
            "type": "object",
            "description": "The geocoded address used for E911 registration",
            "properties": {
              "house_number": {
                "type": "string",
                "description": "House or building number"
              },
              "street_name": {
                "type": "string",
                "description": "Street name"
              },
              "pre_directional": {
                "type": "string",
                "description": "Street name pre-directional (e.g., N, S, E, W)"
              },
              "street_suffix": {
                "type": "string",
                "description": "Street type suffix (e.g., ST, AVE)"
              },
              "post_directional": {
                "type": "string",
                "description": "Street name post-directional (e.g., N, S, E, W)"
              },
              "address_line_2": {
                "type": "string",
                "description": "Secondary address line (e.g., Suite, Apt, Floor)"
              },
              "city": {
                "type": "string",
                "description": "City name"
              },
              "state_code": {
                "type": "string",
                "description": "Two-letter state code"
              },
              "zip": {
                "type": "string",
                "description": "ZIP code"
              },
              "plus_four": {
                "type": "string",
                "description": "ZIP+4 extension"
              },
              "county": {
                "type": "string",
                "description": "County name"
              },
              "country": {
                "type": "string",
                "description": "Country code"
              }
            }
          }
        },
        "required": [
          "adjusted"
        ]
      },
      "AddressInput": {
        "type": "object",
        "description": "Address fields for creating or updating a location",
        "properties": {
          "address_number": {
            "type": "string",
            "maxLength": 255,
            "description": "House or building number",
            "example": "1600"
          },
          "street": {
            "type": "string",
            "maxLength": 255,
            "description": "Street name",
            "example": "Pennsylvania Avenue NW"
          },
          "unit": {
            "type": "string",
            "maxLength": 255,
            "description": "Unit, suite, or apartment number",
            "example": "Suite 200"
          },
          "city": {
            "type": "string",
            "maxLength": 255,
            "description": "City or locality",
            "example": "New York"
          },
          "state": {
            "type": "string",
            "description": "State or province code",
            "example": "NY"
          },
          "postal_code": {
            "type": "string",
            "description": "Postal or ZIP code",
            "example": "10001"
          },
          "country": {
            "type": "string",
            "enum": [
              "US",
              "CA",
              "MX"
            ],
            "description": "Two-letter country code",
            "example": "US"
          }
        },
        "required": [
          "street",
          "city",
          "state",
          "postal_code",
          "country"
        ]
      },
      "CreateLocationRequest": {
        "type": "object",
        "description": "Request body for creating a location",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Display name of the location",
            "example": "Main Office"
          },
          "address": {
            "$ref": "#/components/schemas/AddressInput"
          },
          "primary_did_id": {
            "type": "string",
            "description": "ID of the primary phone number for this location"
          }
        },
        "required": [
          "name",
          "address"
        ]
      },
      "UpdateLocationRequest": {
        "type": "object",
        "description": "Request body for updating a location (all fields optional)",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Display name of the location",
            "example": "Updated Office"
          },
          "address": {
            "$ref": "#/components/schemas/AddressInput"
          },
          "primary_did_id": {
            "type": "string",
            "description": "ID of the primary phone number for this location"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Operational status of the location"
          }
        }
      },
      "PortOrder": {
        "type": "object",
        "description": "A port order tracks the process of transferring (porting) existing phone numbers\nfrom another carrier to DialStack. Port orders follow a draft-based\nworkflow: create a draft, have the customer approve the order, then submit\nfor processing.\n\n## Status Lifecycle\n\n```\ndraft → approved → submitted → foc (scheduled) → complete\n                              → exception → (update + resubmit) → submitted\n                              → cancelled\ndraft → cancelled\napproved → cancelled\n```\n\n- `draft` — Order created, not yet approved\n- `approved` — Customer has approved the order, ready to submit\n- `submitted` — Sent to the carrier, awaiting processing\n- `exception` — Rejected by the carrier (can be corrected and resubmitted)\n- `foc` — The port is scheduled (a Firm Order Commitment has been received from the carrier confirming the completion date)\n- `complete` — Numbers successfully ported and active\n- `cancelled` — Order was cancelled\n",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "por_01h2xcejqtf2nbrexx3vqjhp53"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "approved",
              "submitted",
              "exception",
              "foc",
              "complete",
              "cancelled"
            ],
            "description": "Current status of the port order",
            "example": "draft"
          },
          "details": {
            "$ref": "#/components/schemas/PortOrderDetails"
          },
          "submitted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the order was submitted for processing",
            "example": "2026-02-15T14:30:00Z"
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          },
          "updated_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UpdatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "status",
          "details",
          "created_at",
          "updated_at"
        ]
      },
      "PortOrderDetails": {
        "type": "object",
        "description": "Details of the port order including phone numbers, subscriber information, and document metadata",
        "properties": {
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Phone numbers to port (E.164 format)",
            "example": [
              "+12025551234"
            ]
          },
          "subscriber": {
            "$ref": "#/components/schemas/PortSubscriber"
          },
          "requested_foc_date": {
            "type": "string",
            "format": "date",
            "description": "Requested date for the port to complete (YYYY-MM-DD). Must be at least 5 business days and no more than 30 calendar days from today. \"FOC\" stands for Firm Order Commitment.",
            "example": "2026-03-01"
          },
          "requested_foc_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Requested time for the port to complete, in HH:MM format (08:00-20:00 Eastern). Optional.",
            "example": "10:00"
          },
          "actual_foc_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Actual scheduled date/time confirmed by the carrier",
            "example": "2026-03-01T10:00:00Z"
          },
          "losing_carrier": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortCarrier"
              },
              {
                "type": "null"
              }
            ],
            "description": "Losing carrier information (populated after submission)"
          },
          "approval": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortApproval"
              },
              {
                "type": "null"
              }
            ],
            "description": "Customer approval details (populated when the order is approved)"
          },
          "rejection": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortRejection"
              },
              {
                "type": "null"
              }
            ],
            "description": "Rejection details (populated when status is exception)"
          },
          "loa": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortDocumentMeta"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authorization document metadata (generated automatically on submission)"
          },
          "csr": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortDocumentMeta"
              },
              {
                "type": "null"
              }
            ],
            "description": "Customer Service Record document metadata"
          },
          "bill_copy": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PortDocumentMeta"
              },
              {
                "type": "null"
              }
            ],
            "description": "Bill copy document metadata"
          }
        },
        "required": [
          "phone_numbers"
        ]
      },
      "PortSubscriber": {
        "type": "object",
        "description": "Subscriber and authorization information for the port request",
        "properties": {
          "btn": {
            "type": "string",
            "description": "Billing Telephone Number (E.164 format)",
            "example": "+12025551234"
          },
          "business_name": {
            "type": "string",
            "description": "Business or account name as it appears on the invoice from the current service provider",
            "example": "Doe Enterprises"
          },
          "approver_name": {
            "type": "string",
            "description": "Full name of the person who will approve the port order",
            "example": "John Doe"
          },
          "account_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Account number with the losing carrier. Required for some wireless ports — check the `account_number_required` field in the eligibility response.",
            "example": "123456789"
          },
          "pin": {
            "type": [
              "string",
              "null"
            ],
            "description": "PIN or password for the losing carrier account. Often required alongside `account_number` for wireless ports.",
            "example": "1234"
          },
          "address": {
            "$ref": "#/components/schemas/PortAddress"
          }
        },
        "required": [
          "btn",
          "business_name",
          "approver_name",
          "address"
        ]
      },
      "PortAddress": {
        "type": "object",
        "description": "Service address for the port request",
        "properties": {
          "house_number": {
            "type": "string",
            "description": "House or building number",
            "example": "123"
          },
          "street_name": {
            "type": "string",
            "description": "Street name (without house number)",
            "example": "Main St"
          },
          "line2": {
            "type": [
              "string",
              "null"
            ],
            "description": "Apartment, suite, unit, etc. (optional)",
            "example": "Suite 200"
          },
          "city": {
            "type": "string",
            "description": "City",
            "example": "Anytown"
          },
          "state": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "Two-letter state code (auto-uppercased)",
            "example": "VA"
          },
          "zip": {
            "type": "string",
            "description": "ZIP code",
            "example": "22030"
          }
        },
        "required": [
          "house_number",
          "street_name",
          "city",
          "state",
          "zip"
        ]
      },
      "PortCarrier": {
        "type": "object",
        "description": "Losing carrier information",
        "properties": {
          "name": {
            "type": "string",
            "description": "Carrier name",
            "example": "Verizon"
          },
          "spid": {
            "type": "string",
            "description": "Carrier SPID",
            "example": "1234"
          },
          "port_type": {
            "type": "string",
            "description": "Port type (e.g., automated, manual)",
            "example": "automated"
          }
        }
      },
      "PortRejection": {
        "type": "object",
        "description": "Rejection details from the carrier",
        "properties": {
          "code": {
            "type": "string",
            "description": "Rejection reason code",
            "enum": [
              "address_mismatch",
              "account_number_invalid",
              "name_mismatch",
              "business_name_mismatch",
              "btn_mismatch",
              "pin_required",
              "pin_invalid",
              "unknown"
            ],
            "example": "address_mismatch"
          },
          "message": {
            "type": "string",
            "description": "Human-readable rejection message",
            "example": "Service address mismatch"
          }
        }
      },
      "PortApproval": {
        "type": "object",
        "description": "Customer approval details for a port order",
        "properties": {
          "signature": {
            "type": "string",
            "description": "Electronic signature (the customer's typed name)",
            "example": "Jane Smith"
          },
          "ip": {
            "type": "string",
            "description": "IP address of the customer at the time of approval",
            "example": "203.0.113.42"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the approval was given",
            "example": "2026-02-15T14:02:00Z"
          }
        },
        "required": [
          "signature",
          "ip",
          "timestamp"
        ]
      },
      "ApprovePortOrderRequest": {
        "type": "object",
        "description": "Request body for approving a port order",
        "properties": {
          "signature": {
            "type": "string",
            "description": "Electronic signature (the customer's typed name authorizing the port)",
            "example": "Jane Smith"
          },
          "ip": {
            "type": "string",
            "description": "IP address of the customer approving the order",
            "example": "203.0.113.42"
          }
        },
        "required": [
          "signature",
          "ip"
        ]
      },
      "PortDocumentMeta": {
        "type": "object",
        "description": "Metadata about a port order document",
        "properties": {
          "content_type": {
            "type": "string",
            "description": "MIME type of the document",
            "example": "application/pdf"
          },
          "file_size": {
            "type": "integer",
            "description": "File size in bytes",
            "example": 123456
          }
        },
        "required": [
          "content_type",
          "file_size"
        ]
      },
      "PortOrderEvent": {
        "type": "object",
        "description": "An audit event recording a status change on a port order",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "poe_01h2xcejqtf2nbrexx3vqjhp54"
          },
          "port_order_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityId"
              }
            ],
            "example": "por_01h2xcejqtf2nbrexx3vqjhp53"
          },
          "old_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "draft",
              "approved",
              "submitted",
              "exception",
              "foc",
              "complete",
              "cancelled",
              null
            ],
            "description": "Previous status (null for the initial creation event)"
          },
          "new_status": {
            "type": "string",
            "enum": [
              "draft",
              "approved",
              "submitted",
              "exception",
              "foc",
              "complete",
              "cancelled"
            ],
            "description": "New status after this event"
          },
          "bandwidth_status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Raw status string from the carrier (if applicable)"
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable event message"
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Raw upstream carrier error code for debugging (if applicable). The mapped rejection reason is in the order's `details.rejection.code` field."
          },
          "created_at": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CreatedAt"
              }
            ]
          }
        },
        "required": [
          "id",
          "port_order_id",
          "new_status",
          "created_at"
        ]
      },
      "CreatePortOrderRequest": {
        "type": "object",
        "description": "Request body for creating a draft port order",
        "properties": {
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "US phone numbers to port (E.164 format, no toll-free)",
            "example": [
              "+12025551234"
            ]
          },
          "subscriber": {
            "$ref": "#/components/schemas/PortSubscriber"
          },
          "requested_foc_date": {
            "type": "string",
            "format": "date",
            "description": "Requested date for the port to complete (YYYY-MM-DD). Must be at least 5 business days and no more than 30 calendar days from today (excludes weekends and US federal holidays).",
            "example": "2026-03-01"
          },
          "requested_foc_time": {
            "type": "string",
            "description": "Requested time for the port to complete, in HH:MM format (08:00-20:00 Eastern). Optional.",
            "example": "10:00"
          }
        },
        "required": [
          "phone_numbers",
          "subscriber",
          "requested_foc_date"
        ]
      },
      "UpdatePortOrderRequest": {
        "type": "object",
        "description": "Request body for updating a port order in `draft`, `approved`, or `exception` status.\nAll fields are optional — only provided fields are updated.\nUpdating an approved order clears the approval and reverts the status to `draft`.\nFor exception orders, setting `resubmit: true` clears the rejection and re-submits.\n",
        "properties": {
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Updated phone numbers (E.164 format, no toll-free)",
            "example": [
              "+12025551234"
            ]
          },
          "subscriber": {
            "$ref": "#/components/schemas/PortSubscriber"
          },
          "requested_foc_date": {
            "type": "string",
            "format": "date",
            "description": "Updated requested completion date (YYYY-MM-DD). Must be at least 5 business days and no more than 30 calendar days from today.",
            "example": "2026-03-15"
          },
          "requested_foc_time": {
            "type": "string",
            "description": "Updated requested completion time in HH:MM format (08:00-20:00 Eastern)",
            "example": "10:00"
          },
          "resubmit": {
            "type": "boolean",
            "description": "When true and the order is in `exception` status, clears the rejection and re-submits to the carrier.",
            "default": false
          }
        }
      },
      "PortInEligibilityRequest": {
        "type": "object",
        "description": "Request body for checking port-in eligibility",
        "properties": {
          "phone_numbers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "US phone numbers to check (E.164 format, no toll-free)",
            "example": [
              "+12025551234",
              "+14155559876"
            ]
          }
        },
        "required": [
          "phone_numbers"
        ]
      },
      "PortInEligibilityResult": {
        "type": "object",
        "description": "Port-in eligibility check result",
        "properties": {
          "portable_numbers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PortableNumber"
            },
            "description": "Numbers that can be ported"
          },
          "non_portable_numbers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NonPortableNumber"
            },
            "description": "Numbers that cannot be ported"
          }
        }
      },
      "PortableNumber": {
        "type": "object",
        "description": "A phone number that is eligible for porting",
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "Phone number in E.164 format",
            "example": "+14155559876"
          },
          "losing_carrier_name": {
            "type": "string",
            "description": "Name of the current carrier",
            "example": "T-Mobile US-SVR-10X/2"
          },
          "losing_carrier_spid": {
            "type": "string",
            "description": "Carrier SPID",
            "example": "6529"
          },
          "is_wireless": {
            "type": "boolean",
            "description": "Whether this is a wireless number",
            "example": true
          },
          "account_number_required": {
            "type": "boolean",
            "description": "Whether the losing carrier requires an account number for porting. When true, include `account_number` (and typically `pin`) in the port order subscriber details.",
            "example": false
          }
        },
        "required": [
          "phone_number",
          "is_wireless",
          "account_number_required"
        ]
      },
      "NonPortableNumber": {
        "type": "object",
        "description": "A phone number that cannot be ported",
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "Phone number in E.164 format",
            "example": "+12025559999"
          },
          "rate_center": {
            "type": "string",
            "description": "Rate center where the number is located",
            "example": "WASHINGT DC"
          },
          "city": {
            "type": "string",
            "description": "City",
            "example": "Washington"
          },
          "state": {
            "type": "string",
            "description": "State",
            "example": "DC"
          }
        },
        "required": [
          "phone_number"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message",
            "example": "Invalid request body"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code",
            "example": "validation_error"
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Additional error context (field-specific validation errors, etc.)"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "paths": {
    "/v1/accounts": {
      "post": {
        "summary": "Create a new account",
        "description": "Creates a new account (customer organization) within the platform.\nAccounts represent individual customer organizations (e.g., Jones Chiropractic)\nthat use the vSaaS platform.\n",
        "operationId": "createAccount",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Basic account creation",
                  "value": {
                    "email": "contact@example.com"
                  }
                },
                "with_config": {
                  "summary": "Account with configuration",
                  "value": {
                    "email": "contact@example.com",
                    "config": {
                      "region": "US",
                      "timezone": "America/New_York",
                      "extension_length": 4
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Account created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "examples": {
                  "success": {
                    "summary": "Successful account creation",
                    "value": {
                      "id": "acct_01h2xcejqtf2nbrexx3vqjhp41",
                      "email": "contact@example.com",
                      "config": {},
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/accounts \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"contact@example.com\",\"name\":\"Acme Corp\",\"phone\":\"+12125550100\",\"primary_contact_name\":\"Jane Doe\",\"config\":{\"region\":\"US\",\"extension_length\":4,\"transcription_enabled\":true,\"recording_enabled\":true,\"timezone\":\"America/New_York\",\"max_phone_numbers\":25,\"parking_timeout_seconds\":300}}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accounts.create(/* body params */);"
          }
        ]
      },
      "get": {
        "summary": "List all accounts",
        "description": "List all accounts for the authenticated platform.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listAccounts",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of accounts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Account"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Account list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/accounts",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "acct_01h2xcejqtf2nbrexx3vqjhp41",
                          "email": "contact@example.com",
                          "config": {},
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/accounts?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accounts.list();"
          }
        ]
      }
    },
    "/v1/accounts/{account_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "summary": "Get account details",
        "description": "Retrieve a specific account by ID.\n",
        "operationId": "getAccount",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/accounts/acct_01h2xcejqtf2nbrexx3vqjhp41 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accounts.retrieve('account_...');"
          }
        ]
      },
      "post": {
        "summary": "Update account",
        "description": "Update account details.\n",
        "operationId": "updateAccount",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAccountRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/accounts/acct_01h2xcejqtf2nbrexx3vqjhp41 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"contact@example.com\",\"name\":\"Acme Corp\",\"phone\":\"+12125550100\",\"primary_contact_name\":\"Jane Doe\",\"config\":{\"region\":\"US\",\"extension_length\":4,\"transcription_enabled\":true,\"recording_enabled\":true,\"timezone\":\"America/New_York\",\"max_phone_numbers\":25,\"parking_timeout_seconds\":300},\"default_outbound_did_id\":\"string\",\"billing_address\":{\"address_number\":\"1600\",\"street\":\"Pennsylvania Avenue NW\",\"unit\":\"Suite 200\",\"city\":\"New York\",\"state\":\"NY\",\"postal_code\":\"10001\",\"country\":\"US\"}}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accounts.update('account_...', /* body params */);"
          }
        ]
      },
      "delete": {
        "summary": "Delete account",
        "description": "Delete an account and all associated users, endpoints, and call logs.\nThis operation is irreversible. Active calls will be terminated.\n",
        "operationId": "deleteAccount",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/AccountDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/accounts/acct_01h2xcejqtf2nbrexx3vqjhp41 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accounts.del('account_...');"
          }
        ]
      }
    },
    "/v1/account_sessions": {
      "post": {
        "summary": "Create an account session",
        "description": "Creates a session with account-scoped access. Sessions expire after 1 hour.\nThe session token is scoped to the specified components — it can only access\nAPI endpoints required by those components.\n\nThe account and components are specified in the request body.\n",
        "operationId": "createAccountSession",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateSessionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AccountNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/account_sessions \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"account\":\"acct_01h2xcejqtf2nbrexx3vqjhp41\",\"components\":{\"call_logs\":{\"enabled\":true},\"voicemails\":{\"enabled\":true}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.accountSessions.create(/* body params */);"
          }
        ]
      }
    },
    "/v1/audit-logs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "get": {
        "summary": "List audit logs",
        "description": "List audit log entries for an account with optional filtering.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listAuditLogs",
        "tags": [
          "Audit Logs"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "event",
            "in": "query",
            "description": "Filter by event type (e.g., `user.create`, `auth.denied`). Supports comma-separated values.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "resource",
            "in": "query",
            "description": "Filter by resource ID (exact match)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "actor",
            "in": "query",
            "description": "Filter by actor ID (exact match)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "outcome",
            "in": "query",
            "description": "Filter by outcome",
            "schema": {
              "type": "string",
              "enum": [
                "success",
                "failure",
                "denied"
              ]
            }
          },
          {
            "name": "ip_address",
            "in": "query",
            "description": "Filter by IP address",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "created_after",
            "in": "query",
            "description": "Filter events created at or after this time (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "created_before",
            "in": "query",
            "description": "Filter events created at or before this time (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A paginated list of audit log entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AuditLogEntry"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/audit-logs?limit=10&event=SOME_STRING_VALUE&resource=SOME_STRING_VALUE&actor=SOME_STRING_VALUE&outcome=SOME_STRING_VALUE&ip_address=SOME_STRING_VALUE&created_after=SOME_STRING_VALUE&created_before=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audit-logs`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/users": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a new user",
        "description": "Create a new user within the account. Users represent people who have phone service.\nEach user can have multiple endpoints (devices).\n",
        "operationId": "createUser",
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Basic user",
                  "value": {
                    "name": "Dr. Alice Smith",
                    "email": "alice@spineline.dev"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "examples": {
                  "success": {
                    "summary": "Successful user creation",
                    "value": {
                      "id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "name": "Dr. Alice Smith",
                      "email": "alice@spineline.dev",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/users \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Spineline\",\"email\":\"bob@spineline.dev\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.users.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List all users",
        "description": "List all users for the account.\nResults are returned in reverse chronological order (newest first).\n\n**Expandable fields:** `extensions` — includes the list of extensions assigned to each user.\n",
        "operationId": "listUsers",
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "search",
            "in": "query",
            "description": "Filter users by name or email (case-insensitive partial match)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/User"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "User list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/users",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                          "name": "Dr. Alice Smith",
                          "email": "alice@spineline.dev",
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/users?limit=10&search=SOME_STRING_VALUE&expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.users.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/users/{user_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/UserId"
        }
      ],
      "get": {
        "summary": "Get user details",
        "description": "Retrieve a specific user by ID.\n\n**Expandable fields:** `extensions` — includes the list of extensions assigned to this user.\n",
        "operationId": "getUser",
        "parameters": [
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "tags": [
          "Users"
        ],
        "responses": {
          "200": {
            "description": "User details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "examples": {
                  "success": {
                    "summary": "User details",
                    "value": {
                      "id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "name": "Dr. Alice Smith",
                      "email": "alice@spineline.dev",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/UserNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/users/user_01h2xcejqtf2nbrexx3vqjhp42?expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.users.retrieve('user_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update user",
        "description": "Update user details (name, email, etc.)\n",
        "operationId": "updateUser",
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "examples": {
                  "success": {
                    "summary": "User updated successfully",
                    "value": {
                      "id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "name": "Dr. Alice Smith",
                      "email": "alice@spineline.dev",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/UserNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/users/user_01h2xcejqtf2nbrexx3vqjhp42 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Spineline\",\"email\":\"bob@spineline.dev\",\"outbound_caller_id_did_id\":\"string\",\"voicemail_pin\":\"1234\",\"config\":{\"voicemail_notifications\":{\"enabled\":false,\"attach_audio\":true,\"include_summary\":true,\"include_transcript\":true,\"delete_after_email\":false},\"find_me_follow_me\":{\"steps\":[{\"targets\":[{\"type\":\"external\",\"number\":\"+15551234567\",\"id\":\"string\"}],\"timeout\":1}],\"fallback\":\"voicemail\",\"fallback_target_id\":\"string\"}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.users.update('user_...', /* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "delete": {
        "summary": "Delete user",
        "description": "Delete a user and all associated endpoints. This operation is irreversible.\nActive calls will be terminated.\n",
        "operationId": "deleteUser",
        "tags": [
          "Users"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/UserDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/UserNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/users/user_01h2xcejqtf2nbrexx3vqjhp42 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.users.del('user_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/voicemails": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "get": {
        "summary": "List voicemails",
        "description": "List voicemails visible to the authenticated account, across both\nper-user mailboxes and shared voicemail boxes.\n\nResults are returned in reverse chronological order (newest first).\nUse `owner` (a user ID or shared voicemail box ID) to scope results\nto a single owner.\n",
        "operationId": "listVoicemails",
        "tags": [
          "Voicemails"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "owner",
            "in": "query",
            "description": "Filter to voicemails belonging to a specific owner (a user ID or a shared voicemail box ID).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "is_read",
            "in": "query",
            "description": "Filter by read status.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "from_date",
            "in": "query",
            "description": "Return voicemails created on or after this date (ISO 8601).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of voicemails",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Voicemail"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/voicemails?limit=10&owner=SOME_STRING_VALUE&is_read=SOME_BOOLEAN_VALUE&from_date=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemails`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/voicemails/{voicemail_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/VoicemailId"
        }
      ],
      "get": {
        "summary": "Get a voicemail",
        "description": "Retrieve a specific voicemail by ID, including the `audio_url` for\nplayback. Voicemail IDs are globally unique, so no owner context is\nrequired in the URL.\n",
        "operationId": "getVoicemail",
        "tags": [
          "Voicemails"
        ],
        "responses": {
          "200": {
            "description": "Voicemail details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voicemail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoicemailNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/voicemails/vm_01h2xcejqtf2nbrexx3vqjhp44 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemails/{voicemail_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a voicemail",
        "description": "Update voicemail status (mark as read/unread).\n",
        "operationId": "updateVoicemail",
        "tags": [
          "Voicemails"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateVoicemailRequest"
              },
              "examples": {
                "mark_read": {
                  "summary": "Mark as read",
                  "value": {
                    "is_read": true
                  }
                },
                "mark_unread": {
                  "summary": "Mark as unread",
                  "value": {
                    "is_read": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Voicemail updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voicemail"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoicemailNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/voicemails/vm_01h2xcejqtf2nbrexx3vqjhp44 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"is_read\":true}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemails/{voicemail_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a voicemail",
        "description": "Permanently delete a voicemail and its audio recording.\nThis operation is irreversible.\n",
        "operationId": "deleteVoicemail",
        "tags": [
          "Voicemails"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/VoicemailDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoicemailNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/voicemails/vm_01h2xcejqtf2nbrexx3vqjhp44 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemails/{voicemail_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/voicemails/{voicemail_id}/transcript": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/VoicemailId"
        }
      ],
      "get": {
        "summary": "Get a voicemail transcript",
        "description": "Retrieve the transcript for a specific voicemail.\n\n**Transcription Status:**\n- `pending`: The voicemail has been saved but transcription has not started\n- `processing`: Transcription is currently in progress\n- `completed`: Transcription is complete and text is available\n- `failed`: Transcription failed (text will be null)\n\nVoicemails are automatically transcribed after being saved.\n",
        "operationId": "getVoicemailTranscript",
        "tags": [
          "Voicemails"
        ],
        "responses": {
          "200": {
            "description": "Voicemail transcript",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoicemailTranscript"
                },
                "examples": {
                  "completed": {
                    "summary": "Completed transcription",
                    "value": {
                      "voicemail_id": "vm_01h2xcejqtf2nbrexx3vqjhp45",
                      "status": "completed",
                      "text": "Hi, this is John Smith calling about my appointment tomorrow..."
                    }
                  },
                  "pending": {
                    "summary": "Pending transcription",
                    "value": {
                      "voicemail_id": "vm_01h2xcejqtf2nbrexx3vqjhp45",
                      "status": "pending",
                      "text": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoicemailNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/voicemails/vm_01h2xcejqtf2nbrexx3vqjhp44/transcript \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemails/{voicemail_id}/transcript`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/voicemail_greetings/{owner}/{type}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "owner",
          "in": "path",
          "required": true,
          "description": "ID of the mailbox owner — either a user or a shared voicemail box.",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "type",
          "in": "path",
          "required": true,
          "description": "The greeting variant to operate on. Today only `unavailable` is\nsupported.\n",
          "schema": {
            "type": "string",
            "enum": [
              "unavailable"
            ]
          }
        }
      ],
      "post": {
        "summary": "Upload a voicemail greeting",
        "description": "Uploads (or replaces) a custom greeting for a user mailbox or a\nshared voicemail box.\n\nAccepts a multipart form with a `file` field containing the audio.\nThe audio is validated and transcoded server-side to the storage\nformat (mono µ-law 8 kHz WAV).\n\n- Maximum file size: 5 MB.\n- Maximum duration: 90 seconds.\n- Supported input formats: WAV (PCM s16 / µ-law / A-law), MP3, AAC, Ogg Vorbis, Opus.\n\nRe-uploading for the same `(owner, type)` overwrites the existing\ngreeting.\n",
        "operationId": "uploadVoicemailGreeting",
        "tags": [
          "Voicemails"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Audio file to upload."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Greeting uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoicemailGreetingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "Owner not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "File size exceeds the 5 MB limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/voicemail_greetings/%7Bowner%7D/%7Btype%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: multipart/form-data' \\\n  --form file=string"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemail_greetings/{owner}/{type}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "Get a voicemail greeting",
        "description": "Returns the current custom greeting for a mailbox owner, including a\nshort-lived signed URL for audio playback.\n",
        "operationId": "getVoicemailGreeting",
        "tags": [
          "Voicemails"
        ],
        "responses": {
          "200": {
            "description": "Greeting details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoicemailGreetingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No custom greeting is set for this (owner, type)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/voicemail_greetings/%7Bowner%7D/%7Btype%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemail_greetings/{owner}/{type}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a voicemail greeting",
        "description": "Removes the custom greeting for a mailbox owner. The mailbox reverts\nto the system-default prompts.\n\nThis operation is idempotent — returns `204 No Content` whether or\nnot a greeting was previously set.\n",
        "operationId": "deleteVoicemailGreeting",
        "tags": [
          "Voicemails"
        ],
        "responses": {
          "204": {
            "description": "Greeting removed (or was already absent)"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/voicemail_greetings/%7Bowner%7D/%7Btype%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voicemail_greetings/{owner}/{type}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Initiate a call",
        "description": "Initiates an outbound call to a destination by first establishing a connection\nwith the specified user.\n\n**Call Flow:**\n1. The system rings all of the user's registered devices simultaneously\n2. When the user answers on any device, the system dials the destination\n3. Both legs are bridged together into a single call\n\nThe `dial_string` can be:\n- A phone number in E.164 format (e.g., `+15551234567`)\n- A local phone number (normalized based on account region)\n- An internal extension\n- An emergency number (e.g., `911`)\n\nThis is an asynchronous operation. A `202 Accepted` response indicates the call\nrequest was queued successfully, not that the call has completed or even started.\n",
        "operationId": "createCall",
        "tags": [
          "Calls"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCallRequest"
              },
              "examples": {
                "pstn": {
                  "summary": "Call a phone number",
                  "value": {
                    "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                    "dial_string": "+15551234567"
                  }
                },
                "local": {
                  "summary": "Call a local number",
                  "value": {
                    "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                    "dial_string": "5551234567"
                  }
                },
                "extension": {
                  "summary": "Call an extension",
                  "value": {
                    "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                    "dial_string": "1001"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Call initiated successfully (queued for processing)"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/UserNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/calls \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"user_id\":\"user_01h2xcejqtf2nbrexx3vqjhp42\",\"dial_string\":\"+15551234567\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.calls.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List call logs",
        "description": "List call history for an account with optional filtering.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listCallLogs",
        "tags": [
          "Calls"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "user_id",
            "in": "query",
            "description": "Filter by specific user",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endpoint_id",
            "in": "query",
            "description": "Filter by specific endpoint/device",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "direction",
            "in": "query",
            "description": "Filter by call direction",
            "schema": {
              "type": "string",
              "enum": [
                "inbound",
                "outbound",
                "internal"
              ]
            }
          },
          {
            "name": "from_number",
            "in": "query",
            "description": "Filter by caller's phone number (exact match)",
            "schema": {
              "type": "string",
              "maxLength": 20
            }
          },
          {
            "name": "to_number",
            "in": "query",
            "description": "Filter by recipient's phone number (exact match)",
            "schema": {
              "type": "string",
              "maxLength": 20
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by call status",
            "schema": {
              "type": "string",
              "enum": [
                "completed",
                "no-answer",
                "busy",
                "failed",
                "voicemail"
              ]
            }
          },
          {
            "name": "from_date",
            "in": "query",
            "description": "Return calls started on or after this date (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "description": "Return calls started before this date (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of call logs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CallLog"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Call log list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/calls",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                          "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                          "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43",
                          "did_id": "did_01h2xcejqtf2nbrexx3vqjhp46",
                          "direction": "inbound",
                          "from_number": "+14155551234",
                          "to_number": "+14155559876",
                          "started_at": "2025-10-18T14:30:00Z",
                          "answered_at": "2025-10-18T14:30:05Z",
                          "ended_at": "2025-10-18T14:35:30Z",
                          "duration_seconds": 325,
                          "status": "completed"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/calls?limit=10&user_id=SOME_STRING_VALUE&endpoint_id=SOME_STRING_VALUE&direction=SOME_STRING_VALUE&from_number=SOME_STRING_VALUE&to_number=SOME_STRING_VALUE&status=SOME_STRING_VALUE&from_date=SOME_STRING_VALUE&to_date=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls/{call_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/CallId"
        }
      ],
      "get": {
        "summary": "Get call log details",
        "description": "Retrieve a specific call log by ID.\n",
        "operationId": "getCallLog",
        "tags": [
          "Calls"
        ],
        "responses": {
          "200": {
            "description": "Call log details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallLog"
                },
                "examples": {
                  "completed_call": {
                    "summary": "Completed inbound call",
                    "value": {
                      "id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                      "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43",
                      "did_id": "did_01h2xcejqtf2nbrexx3vqjhp46",
                      "direction": "inbound",
                      "from_number": "+14155551234",
                      "to_number": "+14155559876",
                      "started_at": "2025-10-18T14:30:00Z",
                      "answered_at": "2025-10-18T14:30:05Z",
                      "ended_at": "2025-10-18T14:35:30Z",
                      "duration_seconds": 325,
                      "status": "completed"
                    }
                  },
                  "missed_call": {
                    "summary": "Missed call (no answer)",
                    "value": {
                      "id": "call_01h2xcejqtf2nbrexx3vqjhp47",
                      "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "did_id": "did_01h2xcejqtf2nbrexx3vqjhp46",
                      "direction": "inbound",
                      "from_number": "+14155551234",
                      "to_number": "+14155559876",
                      "started_at": "2025-10-18T15:00:00Z",
                      "ended_at": "2025-10-18T15:00:30Z",
                      "status": "no-answer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/CallNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Control an active call",
        "description": "Send actions to control an active call. This is the central API for all call\ncontrol operations such as attaching audio streams or transferring calls.\n\nActions are processed sequentially. Each action may block processing or allow\nit to continue based on its outcome (see action descriptions for details).\n\n**Replacing actions:** If the call is currently executing actions and you send\na new update, the previous action list is completely replaced. Processing of\nthe current action is interrupted immediately, and processing resumes with the\nfirst action in the new list.\n\n**Example - Attach AI voice and fallback to human:**\n```json\n{\n  \"actions\": [\n    {\"type\": \"attach\", \"url\": \"wss://ai.example.com/voice\"},\n    {\"type\": \"transfer\", \"extension\": \"100\"}\n  ]\n}\n```\nIn this example, the AI handles the call via WebSocket. When the WebSocket\ndisconnects, the call transfers to extension 100.\n",
        "operationId": "updateCall",
        "tags": [
          "Calls"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCallRequest"
              },
              "examples": {
                "attach_ai": {
                  "summary": "Attach AI voice session",
                  "value": {
                    "actions": [
                      {
                        "type": "attach",
                        "url": "wss://ai.platform.example.com/voice"
                      }
                    ]
                  }
                },
                "transfer": {
                  "summary": "Transfer to extension",
                  "value": {
                    "actions": [
                      {
                        "type": "transfer",
                        "extension": "100"
                      }
                    ]
                  }
                },
                "attach_then_transfer": {
                  "summary": "AI with human fallback",
                  "value": {
                    "actions": [
                      {
                        "type": "attach",
                        "url": "wss://ai.platform.example.com/voice"
                      },
                      {
                        "type": "transfer",
                        "extension": "100"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Actions accepted for processing"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/CallNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"actions\":[{\"type\":\"attach\",\"url\":\"wss://ai.platform.example.com/voice\",\"metadata\":{\"agent_id\":\"user_01h2xcejqtf2nbrexx3vqjhp42\",\"queue\":\"support\"}}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls/{call_id}/transcript": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/CallId"
        }
      ],
      "get": {
        "summary": "Get call transcript",
        "description": "Retrieve the transcript for a specific call.\n\n**Transcription Status:**\n- `pending`: The call has been recorded but transcription has not started\n- `processing`: Transcription is currently in progress\n- `completed`: Transcription is complete and text is available\n- `failed`: Transcription failed (text will be null)\n\n**Note:** Returns 404 if the call exists but has no recording, or if the call\ndoes not exist. Not all calls have recordings (depends on account configuration).\n",
        "operationId": "getCallTranscript",
        "tags": [
          "Calls"
        ],
        "responses": {
          "200": {
            "description": "Call transcript",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transcript"
                },
                "examples": {
                  "completed": {
                    "summary": "Completed transcription",
                    "value": {
                      "call_id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                      "status": "completed",
                      "text": "Hello, this is Dr. Smith calling..."
                    }
                  },
                  "pending": {
                    "summary": "Pending transcription",
                    "value": {
                      "call_id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                      "status": "pending",
                      "text": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/TranscriptNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/transcript \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/transcript`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls/{call_id}/recording": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/CallId"
        }
      ],
      "get": {
        "summary": "Get call recording",
        "description": "Retrieve the recording for a specific call. Returns metadata and a signed download URL.\n\nThe download URL is valid for 10 minutes. After expiration, request a new URL by calling this endpoint again.\n\n**Note:** Returns 404 if the call exists but has no recording, or if the call\ndoes not exist. Not all calls have recordings (depends on account configuration).\n",
        "operationId": "getCallRecording",
        "tags": [
          "Calls"
        ],
        "responses": {
          "200": {
            "description": "Call recording",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Recording"
                },
                "examples": {
                  "recording": {
                    "summary": "Recording with metadata",
                    "value": {
                      "call_id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                      "duration_seconds": 185,
                      "file_size_bytes": 2960000,
                      "download_url": "https://cdn.example.com/recordings/2026-03-05/call.wav?Expires=1709654400&Signature=abc123",
                      "expires_at": "2026-03-05T15:40:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/RecordingNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/recording \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/recording`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls/{call_id}/listeners": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/CallId"
        }
      ],
      "post": {
        "summary": "Create a listener",
        "description": "Start streaming real-time audio from an active call to a WebSocket URL.\n\nDialStack opens an outbound WebSocket connection to the specified URL and\nstreams audio unidirectionally (DialStack to your server). The call is not\naffected — both parties remain unaware of the listener.\n\nUse the `channel` parameter to select which audio to receive:\n- `caller` — audio from the party that initiated the call\n- `callee` — audio from the party that received the call\n- `both` — both channels, delivered as separate tagged messages\n\nThe listener automatically stops when the call ends. You can also stop it\nexplicitly with `DELETE /v1/calls/{call_id}/listeners/{listener_id}`.\n\nReturns `409 Conflict` if the call is not in a state that supports listeners\n(e.g., still ringing or already ended). Retry after the call is answered.\n\nSee the [WebSocket API](/websocket-api) for the listener message protocol.\n",
        "operationId": "createListener",
        "tags": [
          "Calls"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateListenerRequest"
              },
              "examples": {
                "both_channels": {
                  "summary": "Listen to both sides of the call",
                  "value": {
                    "url": "wss://your-server.example.com/audio",
                    "channel": "both"
                  }
                },
                "caller_only": {
                  "summary": "Listen to caller audio only",
                  "value": {
                    "url": "wss://your-server.example.com/audio",
                    "channel": "caller"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Listener created and WebSocket connection initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Listener"
                },
                "examples": {
                  "listener": {
                    "value": {
                      "id": "lstn_01h2xcejqtf2nbrexx3vqjhp50",
                      "call_id": "call_01h2xcejqtf2nbrexx3vqjhp45",
                      "url": "wss://your-server.example.com/audio",
                      "channel": "both",
                      "created_at": "2026-04-02T14:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/CallNotFound"
          },
          "409": {
            "$ref": "#/components/responses/CallNotActive"
          },
          "422": {
            "description": "Request body failed field validation (e.g., missing url, unsupported channel)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/listeners \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"url\":\"wss://your-server.example.com/audio\",\"channel\":\"both\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/listeners`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List listeners",
        "description": "List all active listeners on a call.\n",
        "operationId": "listListeners",
        "tags": [
          "Calls"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of active listeners",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Listener"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/CallNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/listeners?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/listeners`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/calls/{call_id}/listeners/{listener_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/CallId"
        },
        {
          "$ref": "#/components/parameters/ListenerId"
        }
      ],
      "get": {
        "summary": "Get listener",
        "description": "Retrieve a listener.\n",
        "operationId": "getListener",
        "tags": [
          "Calls"
        ],
        "responses": {
          "200": {
            "description": "Listener details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Listener"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ListenerNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/listeners/lstn_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/listeners/{listener_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Stop a listener",
        "description": "Stop streaming audio and close the WebSocket connection for this listener.\nThe call is not affected.\n",
        "operationId": "deleteListener",
        "tags": [
          "Calls"
        ],
        "responses": {
          "204": {
            "description": "Listener stopped"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ListenerNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/calls/call_01h2xcejqtf2nbrexx3vqjhp45/listeners/lstn_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/calls/{call_id}/listeners/{listener_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-numbers": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "get": {
        "summary": "List phone numbers",
        "description": "List all phone numbers assigned to the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listPhoneNumbers",
        "tags": [
          "Phone Numbers"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PhoneNumberStatus"
          }
        ],
        "responses": {
          "200": {
            "description": "List of phone numbers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PhoneNumber"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Phone number list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/phone-numbers",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "did_01h2xcejqtf2nbrexx3vqjhp46",
                          "phone_number": "+14155551234",
                          "status": "active",
                          "outbound_enabled": true,
                          "routing_target": null,
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/phone-numbers?limit=10&status=active' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.phoneNumbers.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/phone-numbers/{phone_number_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PhoneNumberId"
        }
      ],
      "get": {
        "summary": "Get a phone number",
        "description": "Retrieve a phone number by ID.\n",
        "operationId": "getPhoneNumber",
        "tags": [
          "Phone Numbers"
        ],
        "responses": {
          "200": {
            "description": "Phone number details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumber"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PhoneNumberNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/phone-numbers/did_01h2xcejqtf2nbrexx3vqjhp46 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-numbers/{phone_number_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a phone number",
        "description": "Update properties of a phone number.\n",
        "operationId": "updatePhoneNumber",
        "tags": [
          "Phone Numbers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "outbound_enabled": {
                    "type": "boolean",
                    "description": "Whether this phone number can be used for outbound calling"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "inactive"
                    ],
                    "description": "Set to `inactive` to stop routing inbound calls to this number, or `active` to resume routing. Released numbers cannot be reactivated."
                  },
                  "directory_listing_name": {
                    "type": "string",
                    "description": "Business name for the directory listing"
                  },
                  "directory_listing_type": {
                    "type": "string",
                    "enum": [
                      "listed",
                      "non_listed",
                      "non_published",
                      "non_registered"
                    ],
                    "description": "How the number appears in directory services. Setting to a non-registered type removes any existing listing. Setting to listed, non_listed, or non_published submits a directory listing order."
                  },
                  "directory_listing_location_id": {
                    "type": "string",
                    "description": "ID of the location whose address to use for the listing. Required when directory_listing_type is not non_registered."
                  },
                  "caller_id_name": {
                    "type": "string",
                    "maxLength": 15,
                    "description": "Caller ID (CNAM) display name. Max 15 ASCII characters per the CNAM standard. Submits an asynchronous order to the upstream provider. The phone number must be in `active` status.",
                    "example": "ACME Corp"
                  },
                  "caller_id_visibility": {
                    "type": "string",
                    "enum": [
                      "PUBLIC",
                      "PRIVATE"
                    ],
                    "default": "PUBLIC",
                    "description": "Whether the caller ID name is publicly visible"
                  }
                }
              },
              "examples": {
                "disable_outbound": {
                  "summary": "Disable outbound calling",
                  "value": {
                    "outbound_enabled": false
                  }
                },
                "deactivate": {
                  "summary": "Deactivate a phone number",
                  "value": {
                    "status": "inactive"
                  }
                },
                "set_caller_id": {
                  "summary": "Set caller ID display name",
                  "value": {
                    "caller_id_name": "ACME Corp"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated phone number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumber"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PhoneNumberNotFound"
          },
          "409": {
            "description": "A caller ID update is already in progress for this number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The upstream provider rejected the caller ID or directory listing update",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "502": {
            "description": "Upstream provider error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Caller ID service is not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/phone-numbers/did_01h2xcejqtf2nbrexx3vqjhp46 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"outbound_enabled\":true,\"status\":\"active\",\"directory_listing_name\":\"string\",\"directory_listing_type\":\"listed\",\"directory_listing_location_id\":\"string\",\"caller_id_name\":\"ACME Corp\",\"caller_id_visibility\":\"PUBLIC\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-numbers/{phone_number_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/available-phone-numbers": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "get": {
        "summary": "Search available phone numbers",
        "description": "Search for phone numbers available for purchase.\nAt least one search filter is required: `area_code`, `state`, `zip`, `npa_nxx`, or `city` combined with `state`.\nFilters can be combined to narrow results.\n",
        "operationId": "searchAvailablePhoneNumbers",
        "tags": [
          "Phone Numbers"
        ],
        "parameters": [
          {
            "name": "area_code",
            "in": "query",
            "required": false,
            "description": "Three-digit area code to search",
            "schema": {
              "type": "string",
              "pattern": "^\\d{3}$",
              "example": "919"
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "City name (requires `state`)",
            "schema": {
              "type": "string",
              "example": "Raleigh"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Two-letter state abbreviation (can be used alone or with `city`)",
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}$",
              "example": "NC"
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "description": "Five-digit US ZIP code",
            "schema": {
              "type": "string",
              "pattern": "^\\d{5}$",
              "example": "27601"
            }
          },
          {
            "name": "npa_nxx",
            "in": "query",
            "required": false,
            "description": "Six-digit NPA-NXX prefix (area code + exchange)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{6}$",
              "example": "919555"
            }
          },
          {
            "name": "quantity",
            "in": "query",
            "required": false,
            "description": "Number of results to return (1-100, default 10)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of available phone numbers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AvailablePhoneNumber"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "examples": {
                  "results": {
                    "summary": "Available numbers found",
                    "value": {
                      "data": [
                        {
                          "phone_number": "+19195551234",
                          "city": "RALEIGH",
                          "state": "NC",
                          "rate_center": "RALEIGH",
                          "lata": "422"
                        },
                        {
                          "phone_number": "+19195555678",
                          "city": "RALEIGH",
                          "state": "NC",
                          "rate_center": "RALEIGH",
                          "lata": "422"
                        }
                      ]
                    }
                  },
                  "empty": {
                    "summary": "No numbers available",
                    "value": {
                      "data": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/available-phone-numbers?area_code=919&city=Raleigh&state=NC&zip=27601&npa_nxx=919555&quantity=SOME_INTEGER_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/available-phone-numbers`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-number-orders": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Order new phone numbers",
        "description": "Order one or more new phone numbers. Numbers must have been found via the\nsearch endpoint (`GET /v1/available-phone-numbers`). This endpoint is for\nacquiring new numbers only — it does not support porting existing numbers\nfrom another provider.\n\nThe order is created in `pending` status and typically completes within\nseconds. Poll the order via `GET /v1/phone-number-orders/{order_id}` or\nconfigure a webhook to be notified when it reaches a terminal status\n(`complete`, `partial`, or `failed`).\n",
        "operationId": "createNumberOrder",
        "tags": [
          "Phone Numbers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNumberOrderRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Order two numbers",
                  "value": {
                    "phone_numbers": [
                      "+19195551234",
                      "+19195555678"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Order created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/phone-number-orders \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"phone_numbers\":[\"+19195551234\",\"+19195555678\"],\"partial_allowed\":false}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-number-orders`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List phone number orders",
        "description": "Returns a paginated list of phone number orders for the account.\nIncludes both purchase and disconnect orders. Results are returned\nin reverse chronological order (newest first).\n",
        "operationId": "listNumberOrders",
        "tags": [
          "Phone Numbers"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/NumberOrderStatus"
          },
          {
            "$ref": "#/components/parameters/NumberOrderType"
          }
        ],
        "responses": {
          "200": {
            "description": "List of phone number orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NumberOrder"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/phone-number-orders?limit=10&status=SOME_STRING_VALUE&order_type=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-number-orders`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-number-orders/{order_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/OrderId"
        }
      ],
      "get": {
        "summary": "Get a phone number order",
        "description": "Retrieves a phone number order by ID. If the order is still pending,\nthe status is refreshed from the provider before returning.\n",
        "operationId": "getNumberOrder",
        "tags": [
          "Phone Numbers"
        ],
        "responses": {
          "200": {
            "description": "Order details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NumberOrderNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/phone-number-orders/nord_01h2xcejqtf2nbrexx3vqjhp47 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-number-orders/{order_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-numbers/{phone_number_id}/disconnect": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PhoneNumberId"
        }
      ],
      "post": {
        "summary": "Disconnect a phone number",
        "description": "Release a phone number back to the provider. Creates a disconnect order\nthat transitions the phone number to `released` status on completion.\n",
        "operationId": "disconnectPhoneNumber",
        "tags": [
          "Phone Numbers"
        ],
        "responses": {
          "201": {
            "description": "Disconnect order created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PhoneNumberNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/phone-numbers/did_01h2xcejqtf2nbrexx3vqjhp46/disconnect \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-numbers/{phone_number_id}/disconnect`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-numbers/{phone_number_id}/reassign": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PhoneNumberId"
        }
      ],
      "post": {
        "summary": "Reassign a phone number",
        "description": "Move a phone number to a different account.\n\nOn reassignment, the routing target is cleared and outbound calling is disabled.\nThe phone number must be in `active` or `inactive` status.\n",
        "operationId": "reassignPhoneNumber",
        "tags": [
          "Phone Numbers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "target_account_id": {
                    "type": "string",
                    "description": "ID of the account to reassign the phone number to"
                  }
                },
                "required": [
                  "target_account_id"
                ]
              },
              "examples": {
                "reassign": {
                  "summary": "Reassign to another account",
                  "value": {
                    "target_account_id": "acct_01h2xcejqtf2nbrexx3vqjhp47"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reassigned phone number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumber"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PhoneNumberNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/phone-numbers/did_01h2xcejqtf2nbrexx3vqjhp46/reassign \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"target_account_id\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-numbers/{phone_number_id}/reassign`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/phone-numbers/{phone_number_id}/route": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PhoneNumberId"
        }
      ],
      "post": {
        "summary": "Update routing target",
        "description": "Set or clear the [routing target](#section/Routing-Targets) for a phone number.\nThe routing target determines where inbound calls to this number are directed.\n\nSend a target ID to route calls to that target, or `null` to clear\nthe current routing. Omitting the `routing_target` key returns the\ncurrent phone number state unchanged.\n",
        "operationId": "updatePhoneNumberRouting",
        "tags": [
          "Phone Numbers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "routing_target": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ID of the target to route inbound calls to, or null to clear routing"
                  }
                }
              },
              "examples": {
                "set_target": {
                  "summary": "Route calls to a target",
                  "value": {
                    "routing_target": "user_01h2xcejqtf2nbrexx3vqjhp48"
                  }
                },
                "clear_target": {
                  "summary": "Clear routing",
                  "value": {
                    "routing_target": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated phone number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumber"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PhoneNumberNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/phone-numbers/did_01h2xcejqtf2nbrexx3vqjhp46/route \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"routing_target\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/phone-numbers/{phone_number_id}/route`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-in-eligibility": {
      "post": {
        "summary": "Check port-in eligibility",
        "description": "Check whether phone numbers are eligible for porting to DialStack. Returns\ncarrier information for portable numbers and rate center details for\nnon-portable numbers.\n\nThis is a pre-purchase check and does not require an account context.\n",
        "operationId": "checkPortInEligibility",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortInEligibilityRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Check two numbers",
                  "value": {
                    "phone_numbers": [
                      "+12025551234",
                      "+14155559876"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Eligibility check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortInEligibilityResult"
                },
                "examples": {
                  "success": {
                    "summary": "Mixed eligibility result",
                    "value": {
                      "portable_numbers": [
                        {
                          "phone_number": "+14155559876",
                          "losing_carrier_name": "T-Mobile US-SVR-10X/2",
                          "losing_carrier_spid": "6529",
                          "is_wireless": true,
                          "account_number_required": true
                        }
                      ],
                      "non_portable_numbers": [
                        {
                          "phone_number": "+12025551234",
                          "rate_center": "WASHINGT DC",
                          "city": "Washington",
                          "state": "DC"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-in-eligibility \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"phone_numbers\":[\"+12025551234\",\"+14155559876\"]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-in-eligibility`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a draft port order",
        "description": "Create a new port order in `draft` status. After creating the draft, approve\nthe order with an electronic signature, then submit it to begin the porting process.\n\nPhone numbers are validated and normalized to E.164 format. Toll-free numbers\nare not supported.\n",
        "operationId": "createPortOrder",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePortOrderRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Port a single number",
                  "value": {
                    "phone_numbers": [
                      "+12025551234"
                    ],
                    "subscriber": {
                      "btn": "+12025551234",
                      "business_name": "Doe Enterprises",
                      "approver_name": "John Doe",
                      "address": {
                        "house_number": "123",
                        "street_name": "Main St",
                        "city": "Anytown",
                        "state": "VA",
                        "zip": "22030"
                      }
                    },
                    "requested_foc_date": "2026-03-01"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draft port order created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"phone_numbers\":[\"+12025551234\"],\"subscriber\":{\"btn\":\"+12025551234\",\"business_name\":\"Doe Enterprises\",\"approver_name\":\"John Doe\",\"account_number\":\"123456789\",\"pin\":\"1234\",\"address\":{\"house_number\":\"123\",\"street_name\":\"Main St\",\"line2\":\"Suite 200\",\"city\":\"Anytown\",\"state\":\"VA\",\"zip\":\"22030\"}},\"requested_foc_date\":\"2026-03-01\",\"requested_foc_time\":\"10:00\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List port orders",
        "description": "Returns a paginated list of port orders for the account.\nResults are returned in reverse chronological order (newest first).\nOptionally filter by status.\n",
        "operationId": "listPortOrders",
        "tags": [
          "Number Porting"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/PortOrderStatus"
          }
        ],
        "responses": {
          "200": {
            "description": "List of port orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PortOrder"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/port-orders?limit=10&status=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "get": {
        "summary": "Get a port order",
        "description": "Retrieve a port order by ID. If the order is in a non-terminal status\n(`submitted`, `exception`, or `foc`), the status is automatically refreshed\nfrom the carrier before returning.\n",
        "operationId": "getPortOrder",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "Port order details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a port order",
        "description": "Update a port order that is in `approved` or `exception` status. Use this to correct\ninformation that caused a rejection, then resubmit. All fields are optional —\nonly provided fields are updated. Updating an approved order clears the approval\nand reverts the status to `draft`.\n",
        "operationId": "updatePortOrder",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePortOrderRequest"
              },
              "examples": {
                "fix_address": {
                  "summary": "Fix service address after rejection",
                  "value": {
                    "subscriber": {
                      "btn": "+12025551234",
                      "business_name": "Doe Enterprises",
                      "approver_name": "John Doe",
                      "address": {
                        "house_number": "456",
                        "street_name": "Oak Ave",
                        "city": "Anytown",
                        "state": "VA",
                        "zip": "22030"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Port order updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"phone_numbers\":[\"+12025551234\"],\"subscriber\":{\"btn\":\"+12025551234\",\"business_name\":\"Doe Enterprises\",\"approver_name\":\"John Doe\",\"account_number\":\"123456789\",\"pin\":\"1234\",\"address\":{\"house_number\":\"123\",\"street_name\":\"Main St\",\"line2\":\"Suite 200\",\"city\":\"Anytown\",\"state\":\"VA\",\"zip\":\"22030\"}},\"requested_foc_date\":\"2026-03-15\",\"requested_foc_time\":\"10:00\",\"resubmit\":false}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/submit": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "post": {
        "summary": "Submit a port order",
        "description": "Submit an approved port order for processing. The order must first be\n[approved](#tag/Number-Porting/operation/approvePortOrder) by the customer.\n\nOn success, the order status transitions from `approved` to `submitted`.\nThe necessary authorization documents are generated and forwarded to the\ncarrier automatically.\n",
        "operationId": "submitPortOrder",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "Port order submitted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "description": "Order is not in approved status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Approval required — the order must be approved before submission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/submit \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/submit`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "post": {
        "summary": "Cancel a port order",
        "description": "Cancel a port order. Draft and approved orders are cancelled locally.\nSubmitted orders are also cancelled with the carrier.\n\nCannot cancel orders in terminal status (`complete` or `cancelled`).\n",
        "operationId": "cancelPortOrder",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "Port order cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "description": "Order is in a terminal status and cannot be cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/cancel \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/cancel`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/approve": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "post": {
        "summary": "Approve a port order",
        "description": "Have the customer approve a port order by providing their electronic signature\nand IP address. This authorizes the number transfer and allows the order to be submitted.\n\nThe order must be in `draft` status and must have subscriber details.\n\nOn success, the order status transitions from `draft` to `approved`. If the order\ndetails are updated after approval, the approval is cleared and the status reverts\nto `draft` — the customer must approve again.\n",
        "operationId": "approvePortOrder",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApprovePortOrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Port order approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "description": "Order is not in draft status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Subscriber details are missing from the port order",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/approve \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"signature\":\"Jane Smith\",\"ip\":\"203.0.113.42\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/approve`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/csr": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "post": {
        "summary": "Upload CSR document",
        "description": "Upload an optional Customer Service Record (CSR) document for a port order.\nA CSR can help resolve porting issues by providing carrier account details.\n\nAccepted formats: PDF, PNG, JPG, TIFF. Maximum file size: 3 MB.\n",
        "operationId": "uploadPortOrderCSR",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSR document file"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CSR uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "csr uploaded successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/csr \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: multipart/form-data' \\\n  --form file=string"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/csr`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "Download CSR document",
        "description": "Download the Customer Service Record (CSR) document for a port order.\n",
        "operationId": "downloadPortOrderCSR",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "CSR document file",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/tiff": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/csr \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/csr`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/bill-copy": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "post": {
        "summary": "Upload bill copy document",
        "description": "Upload an optional bill copy document for a port order.\nA bill copy can help resolve porting issues by providing carrier account details.\n\nAccepted formats: PDF, PNG, JPG, TIFF. Maximum file size: 3 MB.\n",
        "operationId": "uploadPortOrderBillCopy",
        "tags": [
          "Number Porting"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Bill copy document file"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bill copy uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "bill_copy uploaded successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/bill-copy \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: multipart/form-data' \\\n  --form file=string"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/bill-copy`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "Download bill copy document",
        "description": "Download the bill copy document for a port order.\n",
        "operationId": "downloadPortOrderBillCopy",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "Bill copy document file",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/tiff": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/bill-copy \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/bill-copy`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/port-orders/{order_id}/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/PortOrderId"
        }
      ],
      "get": {
        "summary": "List port order events",
        "description": "Returns the audit trail of status changes for a port order,\nin reverse chronological order.\n",
        "operationId": "listPortOrderEvents",
        "tags": [
          "Number Porting"
        ],
        "responses": {
          "200": {
            "description": "List of port order events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PortOrderEvent"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/PortOrderNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/port-orders/por_01h2xcejqtf2nbrexx3vqjhp53/events \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/port-orders/{order_id}/events`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/ai-agents": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create an AI agent",
        "description": "Create a new AI agent within the account. This automatically provisions\na managed voice app and extension for call routing.\n",
        "operationId": "createAIAgent",
        "tags": [
          "AI Agents"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAIAgentRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Create a receptionist agent",
                  "value": {
                    "name": "Front Desk Receptionist",
                    "extension_number": "200",
                    "instructions": "You are the receptionist for Jones Family Dental.",
                    "faq_responses": [
                      {
                        "question": "What are your hours?",
                        "answer": "Monday through Friday, 9 AM to 5 PM."
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "AI agent created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AIAgent"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "Extension number already in use",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/ai-agents \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Front Desk Receptionist\",\"extension_number\":\"200\",\"persona_name\":\"Tony\",\"greeting_name\":\"Jones Family Dental\",\"instructions\":\"You are the receptionist for Jones Family Dental.\",\"faq_responses\":[{\"question\":\"What are your business hours?\",\"answer\":\"We are open Monday through Friday, 9 AM to 5 PM.\"}],\"scheduling\":{\"webhook_url\":\"http://example.com\"}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ai-agents`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List AI agents",
        "description": "List all AI agents for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listAIAgents",
        "tags": [
          "AI Agents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of AI agents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AIAgent"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/ai-agents?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ai-agents`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/ai-agents/{ai_agent_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/AIAgentId"
        }
      ],
      "get": {
        "summary": "Get AI agent details",
        "description": "Retrieve a specific AI agent by ID.\n",
        "operationId": "getAIAgent",
        "tags": [
          "AI Agents"
        ],
        "responses": {
          "200": {
            "description": "AI agent details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AIAgent"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AIAgentNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/ai-agents/aia_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ai-agents/{ai_agent_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update AI agent",
        "description": "Update AI agent details (name, instructions, or FAQ responses).\n",
        "operationId": "updateAIAgent",
        "tags": [
          "AI Agents"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAIAgentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "AI agent updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AIAgent"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AIAgentNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/ai-agents/aia_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Updated Receptionist\",\"persona_name\":\"Tony\",\"greeting_name\":\"Jones Family Dental\",\"instructions\":\"string\",\"faq_responses\":[{\"question\":\"What are your business hours?\",\"answer\":\"We are open Monday through Friday, 9 AM to 5 PM.\"}],\"scheduling\":{\"webhook_url\":\"http://example.com\"}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ai-agents/{ai_agent_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete AI agent",
        "description": "Delete an AI agent and its managed voice app and extension.\nThis operation is irreversible.\n",
        "operationId": "deleteAIAgent",
        "tags": [
          "AI Agents"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/AIAgentDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AIAgentNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/ai-agents/aia_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ai-agents/{ai_agent_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/voice-apps": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a voice app",
        "description": "Create a new voice app within the account. Voice apps handle calls via HTTP\nwebhook notification and optional WebSocket audio streaming.\n",
        "operationId": "createVoiceApp",
        "tags": [
          "Voice Apps"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVoiceAppRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Create AI receptionist",
                  "value": {
                    "name": "AI Receptionist",
                    "url": "https://ai.platform.example.com/calls"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Voice app created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceApp"
                },
                "examples": {
                  "success": {
                    "summary": "Successful voice app creation",
                    "value": {
                      "id": "va_01h2xcejqtf2nbrexx3vqjhp49",
                      "name": "AI Receptionist",
                      "url": "https://ai.platform.example.com/calls",
                      "status": "active",
                      "secret": "whsec_abc123def456...",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/voice-apps \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Spineline\",\"url\":\"https://ai.platform.example.com/calls\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.voiceApps.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List voice apps",
        "description": "List all voice apps for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listVoiceApps",
        "tags": [
          "Voice Apps"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of voice apps",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoiceApp"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Voice app list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/voice-apps",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "va_01h2xcejqtf2nbrexx3vqjhp49",
                          "name": "AI Receptionist",
                          "url": "https://ai.platform.example.com/calls",
                          "status": "active",
                          "secret": "whsec_abc123def456...",
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/voice-apps?limit=10&expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.voiceApps.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/voice-apps/{voice_app_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/VoiceAppId"
        }
      ],
      "get": {
        "summary": "Get voice app details",
        "description": "Retrieve a specific voice app by ID.\n",
        "operationId": "getVoiceApp",
        "tags": [
          "Voice Apps"
        ],
        "parameters": [
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Voice app details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceApp"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoiceAppNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/voice-apps/va_01h2xcejqtf2nbrexx3vqjhp49?expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.voiceApps.retrieve('voice_app_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update voice app",
        "description": "Update voice app details (name, URL, or status).\n",
        "operationId": "updateVoiceApp",
        "tags": [
          "Voice Apps"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateVoiceAppRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Voice app updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceApp"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoiceAppNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/voice-apps/va_01h2xcejqtf2nbrexx3vqjhp49 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Spineline\",\"url\":\"https://ai.platform.example.com/calls\",\"status\":\"active\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.voiceApps.update('voice_app_...', /* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "delete": {
        "summary": "Delete voice app",
        "description": "Delete a voice app. Active calls to this voice app will be terminated.\nThis operation is irreversible.\n",
        "operationId": "deleteVoiceApp",
        "tags": [
          "Voice Apps"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/VoiceAppDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoiceAppNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/voice-apps/va_01h2xcejqtf2nbrexx3vqjhp49 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.voiceApps.del('voice_app_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/voice-apps/{voice_app_id}/rotate_secret": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/VoiceAppId"
        }
      ],
      "post": {
        "summary": "Rotate webhook secret",
        "description": "Generate a new webhook signing secret for the voice app.\nThe old secret is immediately invalidated.\n",
        "operationId": "rotateVoiceAppSecret",
        "tags": [
          "Voice Apps"
        ],
        "responses": {
          "200": {
            "description": "Secret rotated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceApp"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/VoiceAppNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/voice-apps/va_01h2xcejqtf2nbrexx3vqjhp49/rotate_secret \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/voice-apps/{voice_app_id}/rotate_secret`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "get": {
        "summary": "Stream real-time events",
        "description": "Establish a Server-Sent Events (SSE) connection to receive real-time notifications\nabout account activity such as incoming calls.\n\n**Connection Behavior:**\n- On successful connection, a `connected` event is sent immediately\n- Events are streamed in real-time as they occur\n- The connection stays open indefinitely until the client disconnects\n- Clients should implement automatic reconnection with exponential backoff\n\n**Event Format:**\nEvents follow the SSE specification with `event:` and `data:` fields:\n```\nevent: call.incoming\ndata: {\"event\":\"call.incoming\",\"account_id\":\"acct_...\",\"from_number\":\"+14155551234\",\"to_number\":\"+14155559876\"}\n```\n\n**Available Event Types:**\n\n### connected\nSent immediately when the SSE connection is established.\n```json\n{\"message\": \"Connected to event stream\"}\n```\n\n### call.incoming\nSent when an incoming call arrives for the account.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.incoming\"` |\n| `account_id` | string | Account receiving the call |\n| `call_id` | string | Call detail record identifier |\n| `from_number` | string | Caller's phone number (E.164) |\n| `from_name` | string \\| null | Caller's name from caller ID |\n| `to_number` | string | Called phone number (E.164) |\n\n### call.initiated\nSent when an outbound call starts dialing.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.initiated\"` |\n| `account_id` | string | Account initiating the call |\n| `call_id` | string | Call detail record identifier |\n| `from_number` | string | Outbound caller number (E.164) |\n| `to_number` | string | Destination number (E.164) |\n| `user_id` | string | User who initiated the call |\n\n### call.ringing\nSent once per (call, user) when the platform is about to ring a user's phone(s). Fires\nregardless of how the call was routed to the user — direct extension, ring group, ring-all-users,\nFind-Me/Follow-Me (including forwarding to an external number), dial plan Dial User node, voice\napp transfer, or a parked-call ring-back. The event indicates logical \"we're ringing this user\",\nnot a SIP 180 Ringing signal.\n\nA user with multiple endpoints (desk phone + mobile app) produces one event, not one per device.\n\nNo stop event is emitted — consumers that dismiss UI on ring stop (e.g. screen pop) should rely on\n`call.answered` or `call.end`.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.ringing\"` |\n| `account_id` | string | Account owning the user being rung |\n| `call_id` | string | Call detail record identifier |\n| `user_id` | string | User whose phone(s) are being rung |\n| `from_number` | string | Caller's phone number (E.164) |\n| `from_name` | string \\| null | Caller's name from caller ID |\n| `to_number` | string | Called phone number (E.164) |\n| `ringing_at` | string | ISO 8601 timestamp |\n\n### call.answered\nSent when a call is answered.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.answered\"` |\n| `account_id` | string | Account where the call was answered |\n| `call_id` | string | Call detail record identifier |\n| `from_number` | string | Caller's phone number (E.164) |\n| `to_number` | string | Called phone number (E.164) |\n| `direction` | string | `\"inbound\"` or `\"outbound\"` |\n| `answered_at` | string | ISO 8601 timestamp |\n\n### call.end\nSent when a call ends.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.end\"` |\n| `account_id` | string | Account where the call ended |\n| `call_id` | string | Call detail record identifier |\n| `from_number` | string | Caller's phone number (E.164) |\n| `to_number` | string | Called phone number (E.164) |\n| `direction` | string | `\"inbound\"` or `\"outbound\"` |\n| `status` | string | `\"completed\"`, `\"no-answer\"`, `\"busy\"`, `\"failed\"`, or `\"voicemail\"` |\n| `duration_seconds` | integer | Call duration in seconds |\n| `ended_at` | string | ISO 8601 timestamp |\n\n### call.transfer\nSent when a call is transferred.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `event` | string | Always `\"call.transfer\"` |\n| `account_id` | string | Account where the transfer occurred |\n| `call_id` | string | Call detail record identifier |\n| `from_number` | string | Caller's phone number (E.164) |\n| `to_number` | string | Original called number (E.164) |\n| `transferred_to` | string | Transfer target (extension number) |\n",
        "operationId": "streamEvents",
        "tags": [
          "Events"
        ],
        "responses": {
          "200": {
            "description": "SSE event stream established",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string",
                  "example": "text/event-stream"
                }
              },
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "example": "no-cache"
                }
              },
              "Connection": {
                "schema": {
                  "type": "string",
                  "example": "keep-alive"
                }
              }
            },
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-Sent Events stream. Each event has an `event:` type and `data:` payload.\n"
                },
                "examples": {
                  "connected": {
                    "summary": "Connection established",
                    "value": "event: connected\ndata: {\"message\":\"Connected to event stream\"}\n"
                  },
                  "incoming_call": {
                    "summary": "Incoming call event",
                    "value": "event: call.incoming\ndata: {\"event\":\"call.incoming\",\"account_id\":\"acct_01h2xcejqtf2nbrexx3vqjhp41\",\"from_number\":\"+14155551234\",\"from_name\":\"John Smith\",\"to_number\":\"+14155559876\"}\n"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/events \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/events`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/schedules": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a schedule",
        "description": "Create a new business hours schedule within the account. Schedules define\nwhen the business is open based on weekly time ranges and holidays.\n",
        "operationId": "createSchedule",
        "tags": [
          "Schedules"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateScheduleRequest"
              },
              "examples": {
                "business_hours": {
                  "summary": "Standard business hours",
                  "value": {
                    "name": "Business Hours",
                    "timezone": "America/New_York",
                    "ranges": [
                      {
                        "day": 1,
                        "start": "09:00",
                        "end": "17:00"
                      },
                      {
                        "day": 2,
                        "start": "09:00",
                        "end": "17:00"
                      },
                      {
                        "day": 3,
                        "start": "09:00",
                        "end": "17:00"
                      },
                      {
                        "day": 4,
                        "start": "09:00",
                        "end": "17:00"
                      },
                      {
                        "day": 5,
                        "start": "09:00",
                        "end": "17:00"
                      }
                    ],
                    "holidays": [
                      {
                        "start": "2025-12-25",
                        "end": "2025-12-25"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Schedule created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                },
                "examples": {
                  "success": {
                    "summary": "Successful schedule creation",
                    "value": {
                      "id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                      "name": "Business Hours",
                      "timezone": "America/New_York",
                      "ranges": [
                        {
                          "day": 1,
                          "start": "09:00",
                          "end": "17:00"
                        }
                      ],
                      "holidays": [],
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/schedules \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Business Hours\",\"timezone\":\"America/New_York\",\"ranges\":[{\"day\":1,\"start\":\"09:00\",\"end\":\"17:00\"},{\"day\":2,\"start\":\"09:00\",\"end\":\"17:00\"}],\"holidays\":[{\"start\":\"2025-12-25\",\"end\":\"2025-12-25\"}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.schedules.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List schedules",
        "description": "List all schedules for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listSchedules",
        "tags": [
          "Schedules"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of schedules",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Schedule"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Schedule list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/schedules",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                          "name": "Business Hours",
                          "timezone": "America/New_York",
                          "ranges": [
                            {
                              "day": 1,
                              "start": "09:00",
                              "end": "17:00"
                            }
                          ],
                          "holidays": [],
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/schedules?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.schedules.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/schedules/{schedule_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "get": {
        "summary": "Get schedule details",
        "description": "Retrieve a specific schedule by ID.\n",
        "operationId": "getSchedule",
        "tags": [
          "Schedules"
        ],
        "responses": {
          "200": {
            "description": "Schedule details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ScheduleNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/schedules/sched_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.schedules.retrieve('schedule_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update schedule",
        "description": "Update schedule details (name, timezone, ranges, or holidays).\nOnly the fields provided will be updated.\n",
        "operationId": "updateSchedule",
        "tags": [
          "Schedules"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateScheduleRequest"
              },
              "examples": {
                "update_name": {
                  "summary": "Update schedule name",
                  "value": {
                    "name": "New Business Hours"
                  }
                },
                "update_ranges": {
                  "summary": "Update time ranges",
                  "value": {
                    "ranges": [
                      {
                        "day": 1,
                        "start": "08:00",
                        "end": "18:00"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Schedule updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ScheduleNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/schedules/sched_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Updated Business Hours\",\"timezone\":\"America/Los_Angeles\",\"ranges\":[{\"day\":1,\"start\":\"09:00\",\"end\":\"17:00\"}],\"holidays\":[{\"start\":\"2025-12-25\",\"end\":\"2025-12-25\"}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/schedules/{schedule_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete schedule",
        "description": "Delete a schedule. This operation is irreversible.\n",
        "operationId": "deleteSchedule",
        "tags": [
          "Schedules"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/ScheduleDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ScheduleNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/schedules/sched_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/schedules/{schedule_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/schedules/{schedule_id}/hold": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "post": {
        "summary": "Set schedule hold",
        "description": "Set a temporary hold on a schedule. The hold overrides the normal schedule\ncalculation until the specified time.\n\nUse `value: true` to force the schedule to be considered \"open\" regardless\nof the time ranges, or `value: false` to force it to be considered \"closed\".\n\nIf `until` is not provided, it defaults to midnight (00:00:00) the next day\nin the schedule's timezone.\n",
        "operationId": "setScheduleHold",
        "tags": [
          "Schedules"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HoldScheduleRequest"
              },
              "examples": {
                "close_until_specific_time": {
                  "summary": "Close until specific time",
                  "value": {
                    "value": false,
                    "until": "2025-12-20T17:00:00"
                  }
                },
                "close_until_tomorrow": {
                  "summary": "Close until midnight (default)",
                  "value": {
                    "value": false
                  }
                },
                "force_open": {
                  "summary": "Force open temporarily",
                  "value": {
                    "value": true,
                    "until": "2025-12-20T12:00:00"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hold set successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                },
                "examples": {
                  "with_hold": {
                    "summary": "Schedule with hold set",
                    "value": {
                      "id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                      "name": "Business Hours",
                      "timezone": "America/New_York",
                      "ranges": [
                        {
                          "day": 1,
                          "start": "09:00",
                          "end": "17:00"
                        }
                      ],
                      "holidays": [],
                      "hold": {
                        "value": false,
                        "until": "2025-12-20T17:00:00"
                      },
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T14:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ScheduleNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/schedules/sched_01h2xcejqtf2nbrexx3vqjhp50/hold \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"value\":false,\"until\":\"2025-12-20T17:00:00\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/schedules/{schedule_id}/hold`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Clear schedule hold",
        "description": "Clear the hold from a schedule, returning it to normal schedule-based calculation.\n",
        "operationId": "clearScheduleHold",
        "tags": [
          "Schedules"
        ],
        "responses": {
          "200": {
            "description": "Hold cleared successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                },
                "examples": {
                  "hold_cleared": {
                    "summary": "Schedule with hold cleared",
                    "value": {
                      "id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                      "name": "Business Hours",
                      "timezone": "America/New_York",
                      "ranges": [
                        {
                          "day": 1,
                          "start": "09:00",
                          "end": "17:00"
                        }
                      ],
                      "holidays": [],
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T14:35:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ScheduleNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/schedules/sched_01h2xcejqtf2nbrexx3vqjhp50/hold \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/schedules/{schedule_id}/hold`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dialplans": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a dial plan",
        "description": "Create a new visual call routing graph for the account.\nSee the `DialPlanNode` schema for the full list of node types and\ntheir configuration options.\n",
        "operationId": "createDialPlan",
        "tags": [
          "Dial Plans"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDialPlanRequest"
              },
              "examples": {
                "main_line": {
                  "summary": "Main line routing with schedule check",
                  "value": {
                    "name": "Main Line Routing",
                    "entry_node": "check_hours",
                    "nodes": [
                      {
                        "id": "check_hours",
                        "type": "schedule",
                        "config": {
                          "schedule_id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                          "open": "reception",
                          "closed": "voicemail"
                        }
                      },
                      {
                        "id": "reception",
                        "type": "internal_dial",
                        "config": {
                          "target_id": "user_01h2xcejqtf2nbrexx3vqjhp45",
                          "timeout": 30,
                          "next": "voicemail"
                        }
                      },
                      {
                        "id": "voicemail",
                        "type": "internal_dial",
                        "config": {
                          "target_id": "user_01h2xcejqtf2nbrexx3vqjhp46",
                          "timeout": 60
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dial plan created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DialPlan"
                },
                "examples": {
                  "success": {
                    "summary": "Successful dial plan creation",
                    "value": {
                      "id": "dp_01h2xcejqtf2nbrexx3vqjhp60",
                      "name": "Main Line Routing",
                      "entry_node": "check_hours",
                      "nodes": [
                        {
                          "id": "check_hours",
                          "type": "schedule",
                          "config": {
                            "schedule_id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                            "open": "reception",
                            "closed": "voicemail"
                          }
                        },
                        {
                          "id": "reception",
                          "type": "internal_dial",
                          "config": {
                            "target_id": "user_01h2xcejqtf2nbrexx3vqjhp45",
                            "timeout": 30,
                            "next": "voicemail"
                          }
                        },
                        {
                          "id": "voicemail",
                          "type": "internal_dial",
                          "config": {
                            "target_id": "user_01h2xcejqtf2nbrexx3vqjhp46",
                            "timeout": 60
                          }
                        }
                      ],
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/RoutingLoop"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dialplans \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Main Line Routing\",\"entry_node\":\"check_hours\",\"nodes\":[{\"id\":\"check_hours\",\"type\":\"schedule\",\"position\":{\"x\":200,\"y\":100},\"config\":{\"schedule_id\":\"sched_01h2xcejqtf2nbrexx3vqjhp50\",\"open\":\"reception\",\"closed\":\"voicemail\"}}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.dialPlans.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List dial plans",
        "description": "List all dial plans for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listDialPlans",
        "tags": [
          "Dial Plans"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of dial plans",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DialPlan"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/dialplans?limit=10&expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.dialPlans.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/dialplans/{dial_plan_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "dial_plan_id",
          "in": "path",
          "required": true,
          "description": "The dial plan identifier",
          "schema": {
            "type": "string"
          },
          "example": "dp_01h2xcejqtf2nbrexx3vqjhp60"
        }
      ],
      "get": {
        "summary": "Get a dial plan",
        "description": "Retrieve a dial plan by ID.\n",
        "operationId": "getDialPlan",
        "tags": [
          "Dial Plans"
        ],
        "parameters": [
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dial plan details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DialPlan"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/DialPlanNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/dialplans/dp_01h2xcejqtf2nbrexx3vqjhp60?expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.dialPlans.retrieve('dial_plan_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update a dial plan",
        "description": "Update an existing dial plan. All fields are optional;\nonly provided fields will be updated.\n\nWhen `nodes` is provided, it fully replaces all nodes (not a partial node update).\n",
        "operationId": "updateDialPlan",
        "tags": [
          "Dial Plans"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDialPlanRequest"
              },
              "examples": {
                "update_name": {
                  "summary": "Update dial plan name",
                  "value": {
                    "name": "Updated Main Line Routing"
                  }
                },
                "update_nodes": {
                  "summary": "Update nodes (full replacement)",
                  "value": {
                    "entry_node": "check_hours",
                    "nodes": [
                      {
                        "id": "check_hours",
                        "type": "schedule",
                        "config": {
                          "schedule_id": "sched_01h2xcejqtf2nbrexx3vqjhp50",
                          "open": "reception",
                          "closed": "after_hours"
                        }
                      },
                      {
                        "id": "reception",
                        "type": "internal_dial",
                        "config": {
                          "target_id": "user_01h2xcejqtf2nbrexx3vqjhp45",
                          "timeout": 30
                        }
                      },
                      {
                        "id": "after_hours",
                        "type": "internal_dial",
                        "config": {
                          "target_id": "user_01h2xcejqtf2nbrexx3vqjhp47",
                          "timeout": 45
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dial plan updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DialPlan"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/DialPlanNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dialplans/dp_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Updated Main Line Routing\",\"entry_node\":\"check_hours\",\"nodes\":[{\"id\":\"check_hours\",\"type\":\"schedule\",\"position\":{\"x\":200,\"y\":100},\"config\":{\"schedule_id\":\"sched_01h2xcejqtf2nbrexx3vqjhp50\",\"open\":\"reception\",\"closed\":\"voicemail\"}}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dialplans/{dial_plan_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a dial plan",
        "description": "Delete a dial plan by ID.\n\n**Note**: Deletion will fail if any extensions still reference this dial plan.\nYou must first update or delete those extensions.\n",
        "operationId": "deleteDialPlan",
        "tags": [
          "Dial Plans"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/DialPlanDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/DialPlanNotFound"
          },
          "409": {
            "$ref": "#/components/responses/DialPlanConflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/dialplans/dp_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dialplans/{dial_plan_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/ring_groups": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a ring group",
        "description": "Creates a new ring group for parallel dialing.\n\nWhen a call is routed to a ring group, all members ring simultaneously.\nThe first member to answer wins; other ringing channels are cancelled.\n",
        "operationId": "createRingGroup",
        "tags": [
          "Ring Groups"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRingGroupRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ring group created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RingGroup"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/ring_groups \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Sales Team\",\"timeout_seconds\":30,\"ignore_forwarding\":false,\"confirm_external\":false,\"timeout_action\":\"voicemail\",\"timeout_target\":\"user_01h2xcejqtf2nbrexx3vqjhp42\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.ringGroups.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List ring groups",
        "description": "Returns a paginated list of ring groups for the account.\n",
        "operationId": "listRingGroups",
        "tags": [
          "Ring Groups"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of ring groups",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RingGroup"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/ring_groups?limit=10&expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.ringGroups.list({ dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/ring_groups/{ring_group_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/RingGroupId"
        }
      ],
      "get": {
        "summary": "Get a ring group",
        "description": "Retrieves a ring group by ID, including its members.\n",
        "operationId": "getRingGroup",
        "tags": [
          "Ring Groups"
        ],
        "parameters": [
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ring group details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RingGroup"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/RingGroupNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/ring_groups/rg_01h2xcejqtf2nbrexx3vqjhp51?expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.ringGroups.retrieve('ring_group_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update a ring group",
        "description": "Updates ring group settings. All fields are optional.\n",
        "operationId": "updateRingGroup",
        "tags": [
          "Ring Groups"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRingGroupRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated ring group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RingGroup"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/RingGroupNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/ring_groups/rg_01h2xcejqtf2nbrexx3vqjhp51 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Support Team\",\"timeout_seconds\":45,\"ignore_forwarding\":true,\"confirm_external\":true,\"timeout_action\":\"voicemail\",\"timeout_target\":\"user_01h2xcejqtf2nbrexx3vqjhp42\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.ringGroups.update('ring_group_...', /* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "delete": {
        "summary": "Delete a ring group",
        "description": "Deletes a ring group. Cannot delete if used by an extension.\n",
        "operationId": "deleteRingGroup",
        "tags": [
          "Ring Groups"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/RingGroupDeleted"
          },
          "404": {
            "$ref": "#/components/responses/RingGroupNotFound"
          },
          "409": {
            "$ref": "#/components/responses/RingGroupConflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/ring_groups/rg_01h2xcejqtf2nbrexx3vqjhp51 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.ringGroups.del('ring_group_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      }
    },
    "/v1/ring_groups/{ring_group_id}/members": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/RingGroupId"
        }
      ],
      "post": {
        "summary": "Add a member",
        "description": "Adds a member to the ring group.\n\nExactly one of `extension` or `phone_number` must be provided:\n- `extension`: ID of a routing target\n- `phone_number`: Dial string (E.164, local number, extension, 911, etc.)\n",
        "operationId": "addRingGroupMember",
        "tags": [
          "Ring Groups"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddRingGroupMemberRequest"
              },
              "examples": {
                "extension": {
                  "summary": "Extension member",
                  "value": {
                    "extension": "user_01h2xcejqtf2nbrexx3vqjhp42"
                  }
                },
                "phone": {
                  "summary": "Phone number member",
                  "value": {
                    "phone_number": "+14155551234"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Member added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RingGroupMember"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/RingGroupNotFound"
          },
          "422": {
            "description": "Routing loop detected. Adding this member would create a circular reference\n(e.g., RG1 → DP1 → RG1), or nesting exceeds maximum depth of 20.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "routing loop detected: rg_01h2x... → dp_01h2x... → rg_01h2x..."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/ring_groups/rg_01h2xcejqtf2nbrexx3vqjhp51/members \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"extension\":\"user_01h2xcejqtf2nbrexx3vqjhp42\",\"phone_number\":\"+14155551234\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ring_groups/{ring_group_id}/members`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/ring_groups/{ring_group_id}/members/{member_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/RingGroupId"
        },
        {
          "$ref": "#/components/parameters/RingGroupMemberId"
        }
      ],
      "delete": {
        "summary": "Remove a member",
        "description": "Removes a member from the ring group.\n",
        "operationId": "removeRingGroupMember",
        "tags": [
          "Ring Groups"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/RingGroupMemberDeleted"
          },
          "404": {
            "$ref": "#/components/responses/RingGroupMemberNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/ring_groups/rg_01h2xcejqtf2nbrexx3vqjhp51/members/rgm_01h2xcejqtf2nbrexx3vqjhp52 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/ring_groups/{ring_group_id}/members/{member_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/shared_voicemail_boxes": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a shared voicemail box",
        "description": "Creates a new shared voicemail box for team or departmental voicemail.\n",
        "operationId": "createSharedVoicemailBox",
        "tags": [
          "Shared Voicemail Boxes"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSharedVoicemailBoxRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Shared voicemail box created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SharedVoicemailBox"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/shared_voicemail_boxes \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Sales Voicemail\",\"email\":\"sales@example.com\",\"pin\":\"1234\",\"email_attach_audio\":true,\"email_include_summary\":true,\"email_include_transcript\":true,\"delete_after_email\":true}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/shared_voicemail_boxes`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List shared voicemail boxes",
        "description": "Returns a paginated list of shared voicemail boxes for the account.\n",
        "operationId": "listSharedVoicemailBoxes",
        "tags": [
          "Shared Voicemail Boxes"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of shared voicemail boxes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SharedVoicemailBox"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/shared_voicemail_boxes?limit=10&expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/shared_voicemail_boxes`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/shared_voicemail_boxes/{shared_voicemail_box_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/SharedVoicemailBoxId"
        }
      ],
      "get": {
        "summary": "Get a shared voicemail box",
        "description": "Retrieves a shared voicemail box by ID.\n",
        "operationId": "getSharedVoicemailBox",
        "tags": [
          "Shared Voicemail Boxes"
        ],
        "parameters": [
          {
            "name": "expand[]",
            "in": "query",
            "description": "Related resources to include inline. Supported values: `extensions`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "extensions"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Shared voicemail box details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SharedVoicemailBox"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/SharedVoicemailBoxNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/shared_voicemail_boxes/svm_01h2xcejqtf2nbrexx3vqjhp60?expand%5B%5D=SOME_ARRAY_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/shared_voicemail_boxes/{shared_voicemail_box_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a shared voicemail box",
        "description": "Updates shared voicemail box settings. All fields are optional.\n",
        "operationId": "updateSharedVoicemailBox",
        "tags": [
          "Shared Voicemail Boxes"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSharedVoicemailBoxRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated shared voicemail box",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SharedVoicemailBox"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/SharedVoicemailBoxNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/shared_voicemail_boxes/svm_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Support Voicemail\",\"email\":\"support@example.com\",\"pin\":\"5678\",\"email_attach_audio\":false,\"email_include_summary\":false,\"email_include_transcript\":false,\"delete_after_email\":false}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/shared_voicemail_boxes/{shared_voicemail_box_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a shared voicemail box",
        "description": "Deletes a shared voicemail box. Cannot delete if used by an extension.\n",
        "operationId": "deleteSharedVoicemailBox",
        "tags": [
          "Shared Voicemail Boxes"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/SharedVoicemailBoxDeleted"
          },
          "404": {
            "$ref": "#/components/responses/SharedVoicemailBoxNotFound"
          },
          "409": {
            "$ref": "#/components/responses/SharedVoicemailBoxConflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/shared_voicemail_boxes/svm_01h2xcejqtf2nbrexx3vqjhp60 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/shared_voicemail_boxes/{shared_voicemail_box_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/audio_clips": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Upload an audio clip",
        "description": "Uploads a new audio clip for use as hold music, IVR prompts, or other audio playback.\n\nAccepts a multipart form with a `file` field (audio file) and a `name` field (display name).\nThe audio is validated and transcoded server-side. Maximum file size: 5 MB.\nSupported input formats: WAV, MP3, AAC, Ogg Vorbis, Opus.\n",
        "operationId": "createAudioClip",
        "tags": [
          "Audio Clips"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Display name for the audio clip (must be unique per account)",
                    "example": "Hold Music"
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Audio file to upload"
                  }
                },
                "required": [
                  "name",
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Audio clip created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioClip"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "An audio clip with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "File size exceeds the 5 MB limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/audio_clips \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: multipart/form-data' \\\n  --form 'name=Hold Music' \\\n  --form file=string"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audio_clips`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List audio clips",
        "description": "Returns a paginated list of audio clips for the account.\n",
        "operationId": "listAudioClips",
        "tags": [
          "Audio Clips"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of audio clips",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AudioClip"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/audio_clips?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audio_clips`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/audio_clips/{audio_clip_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/AudioClipId"
        }
      ],
      "get": {
        "summary": "Get an audio clip",
        "description": "Retrieves an audio clip by ID. The response includes a signed URL for downloading the audio file.\n",
        "operationId": "getAudioClip",
        "tags": [
          "Audio Clips"
        ],
        "responses": {
          "200": {
            "description": "Audio clip details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioClip"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/AudioClipNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/audio_clips/%7Baudio_clip_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audio_clips/{audio_clip_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update an audio clip",
        "description": "Updates an audio clip's display name.\n",
        "operationId": "updateAudioClip",
        "tags": [
          "Audio Clips"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAudioClipRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated audio clip",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioClip"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/AudioClipNotFound"
          },
          "409": {
            "description": "An audio clip with this name already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/audio_clips/%7Baudio_clip_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Updated Hold Music\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audio_clips/{audio_clip_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete an audio clip",
        "description": "Deletes an audio clip.\n",
        "operationId": "deleteAudioClip",
        "tags": [
          "Audio Clips"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/AudioClipDeleted"
          },
          "404": {
            "$ref": "#/components/responses/AudioClipNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/audio_clips/%7Baudio_clip_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/audio_clips/{audio_clip_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/extensions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create an extension",
        "description": "Creates a new extension mapping a dial code to a routing target.\n",
        "operationId": "createExtension",
        "tags": [
          "Extensions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExtensionRequest"
              },
              "examples": {
                "user_extension": {
                  "summary": "Create a user extension",
                  "value": {
                    "number": "105",
                    "target": "user_01h2xcejqtf2nbrexx3vqjhp42"
                  }
                },
                "dial_plan_extension": {
                  "summary": "Create a dial plan extension",
                  "value": {
                    "number": "200",
                    "target": "dp_01h2xcejqtf2nbrexx3vqjhp60"
                  }
                },
                "voice_app_extension": {
                  "summary": "Create a voice app extension",
                  "value": {
                    "number": "300",
                    "target": "va_01h2xcejqtf2nbrexx3vqjhp49"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Extension created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extension"
                },
                "examples": {
                  "success": {
                    "summary": "Successful extension creation",
                    "value": {
                      "number": "105",
                      "target": "user_01h2xcejqtf2nbrexx3vqjhp42",
                      "status": "active",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/ExtensionConflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/extensions \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"number\":\"105\",\"target\":\"user_01h2xcejqtf2nbrexx3vqjhp42\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.extensions.create(/* body params */, { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "get": {
        "summary": "List extensions",
        "description": "List all extensions for the account.\nOptionally filter by target to find extensions pointing to a specific routing target.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listExtensions",
        "tags": [
          "Extensions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ExtensionTargetFilter"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of extensions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Extension"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Extension list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/extensions",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "number": "105",
                          "target": "user_01h2xcejqtf2nbrexx3vqjhp42",
                          "status": "active",
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/extensions?target=user_01h2xcejqtf2nbrexx3vqjhp42&limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/extensions`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/extensions/{number}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/ExtensionNumber"
        }
      ],
      "get": {
        "summary": "Get an extension",
        "description": "Retrieve an extension by its number (dial code).\n",
        "operationId": "getExtension",
        "tags": [
          "Extensions"
        ],
        "responses": {
          "200": {
            "description": "Extension details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ExtensionNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/extensions/105 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "SDK",
            "source": "import { DialStack } from '@dialstack/sdk';\n\nconst ds = new DialStack(process.env.DIALSTACK_KEY);\n\nconst result = await ds.extensions.retrieve('number_...', { dialstackAccount: 'acct_...' });"
          }
        ]
      },
      "post": {
        "summary": "Update an extension",
        "description": "Update an existing extension. Only the target can be changed;\nto change the extension number, delete and recreate the extension.\n",
        "operationId": "updateExtension",
        "tags": [
          "Extensions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateExtensionRequest"
              },
              "examples": {
                "update_target": {
                  "summary": "Update extension target",
                  "value": {
                    "target": "user_01h2xcejqtf2nbrexx3vqjhp43"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extension updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Extension"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ExtensionNotFound"
          },
          "422": {
            "description": "Loop detected - updating to target a ring group would create a circular reference, or nesting exceeds maximum depth of 10",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "extension is a member of the target ring group"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/extensions/105 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"target\":\"user_01h2xcejqtf2nbrexx3vqjhp43\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/extensions/{number}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete an extension",
        "description": "Delete an extension by its number (dial code).\n",
        "operationId": "deleteExtension",
        "tags": [
          "Extensions"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/ExtensionDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ExtensionNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/extensions/105 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/extensions/{number}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/devices": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a device",
        "description": "**Recommended** way to create any device. Prefer this endpoint over\n`POST /v1/deskphones`, `POST /v1/dect-bases`, and\n`POST /v1/dect-bases/{id}/handsets`.\n\nSupported types:\n- `deskphone` requires `mac_address`\n- `dect_base` requires `mac_address`\n- `dect_handset` requires `base_id` and `ipei`\n",
        "operationId": "createDevice",
        "tags": [
          "Devices"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeviceRequest"
              },
              "examples": {
                "deskphone": {
                  "summary": "Create a deskphone",
                  "value": {
                    "type": "deskphone",
                    "mac_address": "00:04:13:aa:bb:cc",
                    "model": "D785"
                  }
                },
                "dect_base": {
                  "summary": "Create a DECT base",
                  "value": {
                    "type": "dect_base",
                    "mac_address": "00:04:13:11:22:33",
                    "model": "M500"
                  }
                },
                "dect_handset": {
                  "summary": "Create a DECT handset",
                  "value": {
                    "type": "dect_handset",
                    "base_id": "01h2xcejqtf2nbrexx3vqjhp50",
                    "ipei": "123456789012345",
                    "display_name": "Front Desk"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Device created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDeviceResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Parent DECT base not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Device creation conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/devices \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"type\":\"deskphone\",\"mac_address\":\"00:04:13:aa:bb:cc\",\"model\":\"D785\",\"overrides\":{\"abstractions\":{\"audio\":{\"codecs\":[\"PCMU\",\"PCMA\"],\"vad_enabled\":true,\"echo_cancellation\":true,\"jitter_buffer\":{\"mode\":\"adaptive\",\"min_ms\":40,\"max_ms\":200}},\"display\":{\"time_format\":\"12h\",\"date_format\":\"M/D/Y\",\"backlight_timeout\":30,\"backlight_level\":\"low\"},\"regional\":{\"timezone\":\"America/New_York\",\"language\":\"en-US\",\"tone_scheme\":\"us\"},\"network\":{\"vlan_id\":0,\"qos_dscp_sip\":26,\"qos_dscp_rtp\":46,\"ntp_server\":\"string\",\"rtcp_enabled\":true},\"features\":{\"dnd_enabled\":true,\"call_waiting_enabled\":true,\"call_forward_enabled\":true,\"auto_answer_enabled\":true,\"srtp_enabled\":true},\"provisioning\":{\"resync_time\":\"02:00\",\"resync_mode\":\"config_and_firmware\",\"bootup_check_enabled\":true},\"line_keys\":[{\"position\":1,\"type\":\"blf\",\"label\":\"Reception\",\"value\":\"100\"},{\"position\":2,\"type\":\"speed_dial\",\"label\":\"Support\",\"value\":\"+15551234567\"},{\"position\":3,\"type\":\"voicemail\",\"label\":\"Voicemail\",\"value\":\"*97\"}]},\"vendor_overrides\":{\"ntp_server\":\"time.nist.gov\"}},\"multicell_role\":\"single\",\"base_id\":\"01h2xcejqtf2nbrexx3vqjhp50\",\"ipei\":\"123456789012345\",\"display_name\":\"Front Desk\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List devices",
        "description": "**Recommended** way to list devices. Prefer this endpoint over\n`GET /v1/deskphones` and `GET /v1/dect-bases`.\n\nUnified view of all physical devices (deskphones and DECT base stations).\nUse the optional `type` filter to return only deskphones or only DECT base stations.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listDevices",
        "tags": [
          "Devices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/DeviceTypeFilter"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of devices",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Device"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/devices?type=SOME_STRING_VALUE&limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/devices/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Device identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get a device",
        "description": "**Recommended** way to fetch any device. Prefer this endpoint over\n`GET /v1/deskphones/{id}`, `GET /v1/dect-bases/{id}`, and\n`GET /v1/dect-bases/{id}/handsets/{handset_id}`.\n\nUnified view of a single device. Works for deskphones, DECT base stations, and DECT handsets.\n",
        "operationId": "getDevice",
        "tags": [
          "Devices"
        ],
        "responses": {
          "200": {
            "description": "Device details",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Device"
                    },
                    {
                      "$ref": "#/components/schemas/DECTHandset"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a device",
        "description": "**Recommended** way to delete any device. Prefer this endpoint over\n`DELETE /v1/deskphones/{id}`, `DELETE /v1/dect-bases/{id}`, and\n`DELETE /v1/dect-bases/{id}/handsets/{handset_id}`.\n\nDelete any device by its ID. Works for deskphones, DECT base stations, and DECT handsets.\n\nDeleting a deskphone removes all associated user assignments. Deleting a DECT base\nremoves all its handsets and their user assignments.\n",
        "operationId": "deleteDevice",
        "tags": [
          "Devices"
        ],
        "responses": {
          "204": {
            "description": "Device deleted"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/deskphones": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a deskphone",
        "deprecated": true,
        "description": "**Deprecated:** Use `POST /v1/devices` with `type: deskphone` instead.\n\nProvision a new deskphone. The vendor is auto-detected from the MAC address.\n",
        "operationId": "createDeskphone",
        "tags": [
          "Deskphones"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeskphoneRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Create a deskphone",
                  "value": {
                    "mac_address": "00:04:13:aa:bb:cc",
                    "model": "D785"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Deskphone created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionedDevice"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "A device with this MAC address already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/deskphones \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"mac_address\":\"00:04:13:aa:bb:cc\",\"model\":\"D785\",\"overrides\":{\"abstractions\":{\"audio\":{\"codecs\":[\"PCMU\",\"PCMA\"],\"vad_enabled\":true,\"echo_cancellation\":true,\"jitter_buffer\":{\"mode\":\"adaptive\",\"min_ms\":40,\"max_ms\":200}},\"display\":{\"time_format\":\"12h\",\"date_format\":\"M/D/Y\",\"backlight_timeout\":30,\"backlight_level\":\"low\"},\"regional\":{\"timezone\":\"America/New_York\",\"language\":\"en-US\",\"tone_scheme\":\"us\"},\"network\":{\"vlan_id\":0,\"qos_dscp_sip\":26,\"qos_dscp_rtp\":46,\"ntp_server\":\"string\",\"rtcp_enabled\":true},\"features\":{\"dnd_enabled\":true,\"call_waiting_enabled\":true,\"call_forward_enabled\":true,\"auto_answer_enabled\":true,\"srtp_enabled\":true},\"provisioning\":{\"resync_time\":\"02:00\",\"resync_mode\":\"config_and_firmware\",\"bootup_check_enabled\":true},\"line_keys\":[{\"position\":1,\"type\":\"blf\",\"label\":\"Reception\",\"value\":\"100\"},{\"position\":2,\"type\":\"speed_dial\",\"label\":\"Support\",\"value\":\"+15551234567\"},{\"position\":3,\"type\":\"voicemail\",\"label\":\"Voicemail\",\"value\":\"*97\"}]},\"vendor_overrides\":{\"ntp_server\":\"time.nist.gov\"}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List deskphones",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices?type=deskphone` instead.\n\nList all deskphones for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listDeskphones",
        "tags": [
          "Deskphones"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of deskphones",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProvisionedDevice"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/deskphones?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/deskphones/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Deskphone identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get a deskphone",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices/{id}` instead.\n\nRetrieve a deskphone by its ID.\n",
        "operationId": "getDeskphone",
        "tags": [
          "Deskphones"
        ],
        "responses": {
          "200": {
            "description": "Deskphone details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionedDevice"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a deskphone",
        "description": "Update a deskphone's properties. Only provided fields are changed.\n",
        "operationId": "updateDeskphone",
        "tags": [
          "Deskphones"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDeskphoneRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deskphone updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionedDevice"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"model\":\"string\",\"status\":\"pending-sync\",\"overrides\":{\"abstractions\":{\"audio\":{\"codecs\":[\"PCMU\",\"PCMA\"],\"vad_enabled\":true,\"echo_cancellation\":true,\"jitter_buffer\":{\"mode\":\"adaptive\",\"min_ms\":40,\"max_ms\":200}},\"display\":{\"time_format\":\"12h\",\"date_format\":\"M/D/Y\",\"backlight_timeout\":30,\"backlight_level\":\"low\"},\"regional\":{\"timezone\":\"America/New_York\",\"language\":\"en-US\",\"tone_scheme\":\"us\"},\"network\":{\"vlan_id\":0,\"qos_dscp_sip\":26,\"qos_dscp_rtp\":46,\"ntp_server\":\"string\",\"rtcp_enabled\":true},\"features\":{\"dnd_enabled\":true,\"call_waiting_enabled\":true,\"call_forward_enabled\":true,\"auto_answer_enabled\":true,\"srtp_enabled\":true},\"provisioning\":{\"resync_time\":\"02:00\",\"resync_mode\":\"config_and_firmware\",\"bootup_check_enabled\":true},\"line_keys\":[{\"position\":1,\"type\":\"blf\",\"label\":\"Reception\",\"value\":\"100\"},{\"position\":2,\"type\":\"speed_dial\",\"label\":\"Support\",\"value\":\"+15551234567\"},{\"position\":3,\"type\":\"voicemail\",\"label\":\"Voicemail\",\"value\":\"*97\"}]},\"vendor_overrides\":{\"ntp_server\":\"time.nist.gov\"}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a deskphone",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}` instead.\n\nDelete a deskphone and all its associated lines.\n",
        "operationId": "deleteDeskphone",
        "tags": [
          "Deskphones"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/DeviceDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/deskphones/{id}/provisioning-events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Deskphone identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "List provisioning events",
        "description": "List provisioning events for a deskphone. Returns a log of configuration\nfetches by the device.\n",
        "operationId": "listDeskphoneProvisioningEvents",
        "tags": [
          "Deskphones"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "List of provisioning events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProvisioningEvent"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/deskphones/%7Bid%7D/provisioning-events?limit=10' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}/provisioning-events`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/devices/{id}/status/check-sync": {
      "post": {
        "summary": "Trigger device configuration reload",
        "description": "Tells the device to fetch and apply its latest configuration.\nWorks for deskphones, DECT bases, and DECT handsets — on a DECT\nsystem, one request reloads configuration on every handset paired\nwith the base.\n\nWith the default `reboot: false`, the device applies configuration\nin place. Active calls continue and the device stays registered.\nWith `reboot: true`, the device reboots immediately — any active\ncall is dropped, and the device is offline for about 30–90 seconds.\n\nTrigger check-sync when you actually change configuration, not on\nevery admin-UI interaction. See the [Device provisioning\nguide](https://docs.dialstack.ai/guides/device-provisioning) for\nthe full list of side effects.\n",
        "operationId": "deviceCheckSync",
        "tags": [
          "Devices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Device identifier (deskphone, DECT base, or DECT handset)"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reboot": {
                    "type": "boolean",
                    "description": "If true, the device reboots immediately after applying\nconfig, interrupting any active call. Default `false`\nperforms a non-disruptive config reload.\n",
                    "default": false
                  }
                }
              },
              "examples": {
                "default": {
                  "summary": "Default (no reboot)",
                  "value": {}
                },
                "with_reboot": {
                  "summary": "With reboot — destructive, interrupts active calls",
                  "value": {
                    "reboot": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "At least one line accepted the request. Inspect `lines` for the\nper-line outcome — some lines may be `unreachable` or\n`not_registered` even when the overall request succeeds.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "lines_notified",
                    "lines"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "lines_notified": {
                      "type": "integer",
                      "description": "Number of lines that accepted the request.",
                      "example": 1
                    },
                    "lines": {
                      "type": "array",
                      "description": "Per-line outcome. `line_number` is a 1-indexed\nidentifier; for deskphones it matches the physical\nline, for DECT it is a stable sequence within the\nresponse.\n",
                      "items": {
                        "type": "object",
                        "required": [
                          "line_number",
                          "status"
                        ],
                        "properties": {
                          "line_number": {
                            "type": "integer",
                            "example": 1
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "delivered",
                              "not_registered",
                              "unreachable",
                              "error"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid device ID or device has no SIP lines configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_id": {
                    "value": {
                      "error": "Invalid device ID"
                    }
                  },
                  "no_lines": {
                    "value": {
                      "error": "Device has no SIP lines configured"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Device not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Device not found"
                }
              }
            }
          },
          "409": {
            "description": "The device could not be reached. The `reason` field tells you why:\n\n- `not_registered` — the device has no active registration. It\n  may be powered off, unable to reach the SIP server, or has\n  never registered.\n- `unreachable` — the device didn't respond in time. It is\n  likely offline or has lost its connection.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "reason"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "not_registered",
                        "unreachable"
                      ]
                    }
                  }
                },
                "examples": {
                  "not_registered": {
                    "value": {
                      "error": "Device is not registered - phone may be offline",
                      "reason": "not_registered"
                    }
                  },
                  "unreachable": {
                    "value": {
                      "error": "Device did not respond - it may be offline",
                      "reason": "unreachable"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Check-sync not available in this environment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Check-sync not available in this environment"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D/status/check-sync \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"reboot\":false}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}/status/check-sync`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/devices/{id}/users": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Device identifier (deskphone, DECT handset, or DECT base)",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Assign a user to a device",
        "description": "Assigns a user to a device. SIP credentials and line configuration are created automatically.\n\nSupported device types:\n- **Deskphones** — assigns the user to the next available line key (max 24)\n- **DECT handsets** — assigns the user to the handset (max 24)\n- **DECT bases** — not supported (returns 400); assign to individual handsets instead\n",
        "operationId": "assignUserToDevice",
        "tags": [
          "Devices"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignUserToDeviceRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Assign a user to a deskphone",
                  "value": {
                    "user_id": "user_01h2xcejqtf2nbrexx3vqjhp42"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User assigned to deskphone",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceUserAssignment"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          },
          "409": {
            "description": "Conflict (user already assigned or maximum lines reached)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "already_assigned": {
                    "value": {
                      "error": "user is already assigned to this device"
                    }
                  },
                  "max_lines": {
                    "value": {
                      "error": "device has reached the maximum of 24 lines"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D/users \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"user_id\":\"01h2xcejqtf2nbrexx3vqjhp42\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}/users`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List users assigned to a device",
        "description": "Returns all users currently assigned to the device.\nDevices support at most 24 users, so no pagination is needed.\n",
        "operationId": "listDeviceUsers",
        "tags": [
          "Devices"
        ],
        "responses": {
          "200": {
            "description": "List of assigned users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "enum": [
                        "list"
                      ]
                    },
                    "url": {
                      "type": "string"
                    },
                    "next_page_url": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "previous_page_url": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DeviceUserAssignment"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D/users \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}/users`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/devices/{id}/users/{user_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Device identifier (deskphone, DECT handset, or DECT base)",
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/UserId"
        }
      ],
      "delete": {
        "summary": "Remove a user from a device",
        "description": "Removes the user's assignment from the device.\nThe associated SIP credentials and line configuration are cleaned up automatically.\n",
        "operationId": "removeUserFromDevice",
        "tags": [
          "Devices"
        ],
        "responses": {
          "204": {
            "description": "User removed from deskphone"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Device not found or user is not assigned to this device",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/devices/%7Bid%7D/users/user_01h2xcejqtf2nbrexx3vqjhp42 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/devices/{id}/users/{user_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/deskphones/{id}/lines": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Deskphone identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Create a deskphone line",
        "deprecated": true,
        "description": "**Deprecated:** Use `POST /v1/devices/{id}/users` instead.\n\nAssigns a SIP endpoint to the next available line key on the deskphone.\nThe line number is automatically assigned as the lowest unused number (1-24).\nA deskphone supports a maximum of 24 lines. Each endpoint can only be assigned once per device.\n",
        "operationId": "createDeskphoneLine",
        "tags": [
          "Deskphones"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeviceLineRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Assign an endpoint to a line",
                  "value": {
                    "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Device line created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLine"
                },
                "examples": {
                  "success": {
                    "summary": "Successful line creation",
                    "value": {
                      "id": "dln_01h2xcejqtf2nbrexx3vqjhp55",
                      "device_id": "dev_01h2xcejqtf2nbrexx3vqjhp50",
                      "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43",
                      "line_number": 1,
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          },
          "409": {
            "description": "Conflict (endpoint already assigned or maximum lines reached)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "duplicate_endpoint": {
                    "value": {
                      "error": "Endpoint is already assigned to this device"
                    }
                  },
                  "max_lines": {
                    "value": {
                      "error": "Device has reached the maximum of 24 lines"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D/lines \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"endpoint_id\":\"ep_01h2xcejqtf2nbrexx3vqjhp43\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}/lines`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List deskphone lines",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices/{id}/users` instead.\n\nList all SIP line assignments for a deskphone.\nReturns lines ordered by line number.\n",
        "operationId": "listDeskphoneLines",
        "tags": [
          "Deskphones"
        ],
        "responses": {
          "200": {
            "description": "List of device lines",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DeviceLine"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D/lines \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}/lines`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/deskphones/{id}/lines/{line_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Deskphone identifier",
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/DeviceLineId"
        }
      ],
      "post": {
        "summary": "Update a deskphone line",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}/users/{user_id}` and `POST /v1/devices/{id}/users` instead.\n\nReassigns a deskphone line to a different SIP endpoint.\nThe line number remains unchanged; only the endpoint is updated.\n",
        "operationId": "updateDeskphoneLine",
        "tags": [
          "Deskphones"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDeviceLineRequest"
              },
              "examples": {
                "reassign": {
                  "summary": "Reassign to a different endpoint",
                  "value": {
                    "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp44"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Device line updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceLine"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceLineNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D/lines/dln_01h2xcejqtf2nbrexx3vqjhp55 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"endpoint_id\":\"ep_01h2xcejqtf2nbrexx3vqjhp44\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}/lines/{line_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a deskphone line",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}/users/{user_id}` instead.\n\nRemoves a SIP line assignment from the deskphone.\n",
        "operationId": "deleteDeskphoneLine",
        "tags": [
          "Deskphones"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/DeviceLineDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DeviceLineNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/deskphones/%7Bid%7D/lines/dln_01h2xcejqtf2nbrexx3vqjhp55 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/deskphones/{id}/lines/{line_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a DECT base station",
        "deprecated": true,
        "description": "**Deprecated:** Use `POST /v1/devices` with `type: dect_base` instead.\n\nRegister a new DECT base station for provisioning.\nThe vendor is automatically detected from the MAC address.\n",
        "operationId": "createDECTBase",
        "tags": [
          "DECT Bases"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDECTBaseRequest"
              },
              "examples": {
                "standalone": {
                  "summary": "Standalone base station",
                  "value": {
                    "mac_address": "00:04:13:bb:cc:dd"
                  }
                },
                "multicell_secondary": {
                  "summary": "Secondary base in multicell deployment",
                  "value": {
                    "mac_address": "00:04:13:bb:cc:ee",
                    "multicell_role": "secondary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "DECT base created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTBase"
                },
                "examples": {
                  "success": {
                    "summary": "Successful creation",
                    "value": {
                      "id": "dectb_01h2xcejqtf2nbrexx3vqjhp60",
                      "mac_address": "00:04:13:bb:cc:dd",
                      "vendor": "snom",
                      "model": null,
                      "status": "pending-sync",
                      "multicell_role": "single",
                      "max_handsets": 30,
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "A device with this MAC address already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "A device with this MAC address already exists"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dect-bases \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"mac_address\":\"00:04:13:bb:cc:dd\",\"model\":\"M500\",\"multicell_role\":\"single\",\"overrides\":{\"abstractions\":{\"audio\":{\"codecs\":[\"PCMU\",\"PCMA\"],\"vad_enabled\":true,\"echo_cancellation\":true,\"jitter_buffer\":{\"mode\":\"adaptive\",\"min_ms\":40,\"max_ms\":200}},\"display\":{\"time_format\":\"12h\",\"date_format\":\"M/D/Y\",\"backlight_timeout\":30,\"backlight_level\":\"low\"},\"regional\":{\"timezone\":\"America/New_York\",\"language\":\"en-US\",\"tone_scheme\":\"us\"},\"network\":{\"vlan_id\":0,\"qos_dscp_sip\":26,\"qos_dscp_rtp\":46,\"ntp_server\":\"string\",\"rtcp_enabled\":true},\"features\":{\"dnd_enabled\":true,\"call_waiting_enabled\":true,\"call_forward_enabled\":true,\"auto_answer_enabled\":true,\"srtp_enabled\":true},\"provisioning\":{\"resync_time\":\"02:00\",\"resync_mode\":\"config_and_firmware\",\"bootup_check_enabled\":true},\"line_keys\":[{\"position\":1,\"type\":\"blf\",\"label\":\"Reception\",\"value\":\"100\"},{\"position\":2,\"type\":\"speed_dial\",\"label\":\"Support\",\"value\":\"+15551234567\"},{\"position\":3,\"type\":\"voicemail\",\"label\":\"Voicemail\",\"value\":\"*97\"}]},\"vendor_overrides\":{\"ntp_server\":\"time.nist.gov\"}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List DECT base stations",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices?type=dect_base` instead.\n\nList all DECT base stations in the account.\n",
        "operationId": "listDECTBases",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "200": {
            "description": "List of DECT base stations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DECTBase"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/dect-bases \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "DECT base station identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get a DECT base station",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices/{id}` instead.\n\nRetrieve a DECT base station by ID.\n",
        "operationId": "getDECTBase",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "200": {
            "description": "DECT base station details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTBase"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "DECT base not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "DECT base not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a DECT base station",
        "description": "Update properties of a DECT base station.\n",
        "operationId": "updateDECTBase",
        "tags": [
          "DECT Bases"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDECTBaseRequest"
              },
              "examples": {
                "update_role": {
                  "summary": "Change multicell role",
                  "value": {
                    "multicell_role": "data_master"
                  }
                },
                "update_overrides": {
                  "summary": "Set device overrides",
                  "value": {
                    "overrides": {
                      "abstractions": {
                        "regional": {
                          "timezone": "America/Toronto",
                          "language": "fr-CA"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "DECT base updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTBase"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "DECT base not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "DECT base not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"model\":\"string\",\"status\":\"pending-sync\",\"multicell_role\":\"single\",\"overrides\":{\"abstractions\":{\"audio\":{\"codecs\":[\"PCMU\",\"PCMA\"],\"vad_enabled\":true,\"echo_cancellation\":true,\"jitter_buffer\":{\"mode\":\"adaptive\",\"min_ms\":40,\"max_ms\":200}},\"display\":{\"time_format\":\"12h\",\"date_format\":\"M/D/Y\",\"backlight_timeout\":30,\"backlight_level\":\"low\"},\"regional\":{\"timezone\":\"America/New_York\",\"language\":\"en-US\",\"tone_scheme\":\"us\"},\"network\":{\"vlan_id\":0,\"qos_dscp_sip\":26,\"qos_dscp_rtp\":46,\"ntp_server\":\"string\",\"rtcp_enabled\":true},\"features\":{\"dnd_enabled\":true,\"call_waiting_enabled\":true,\"call_forward_enabled\":true,\"auto_answer_enabled\":true,\"srtp_enabled\":true},\"provisioning\":{\"resync_time\":\"02:00\",\"resync_mode\":\"config_and_firmware\",\"bootup_check_enabled\":true},\"line_keys\":[{\"position\":1,\"type\":\"blf\",\"label\":\"Reception\",\"value\":\"100\"},{\"position\":2,\"type\":\"speed_dial\",\"label\":\"Support\",\"value\":\"+15551234567\"},{\"position\":3,\"type\":\"voicemail\",\"label\":\"Voicemail\",\"value\":\"*97\"}]},\"vendor_overrides\":{\"ntp_server\":\"time.nist.gov\"}}}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a DECT base station",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}` instead.\n\nDelete a DECT base station and all associated handsets and extensions.\n",
        "operationId": "deleteDECTBase",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "204": {
            "description": "DECT base deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "DECT base not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "DECT base not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases/{id}/handsets": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "DECT base station identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Add a handset to a DECT base",
        "deprecated": true,
        "description": "**Deprecated:** Use `POST /v1/devices` with `type: dect_handset` and\n`base_id` set to the DECT base identifier instead.\n\nPair a new wireless handset with a DECT base station.\nThe slot number is automatically assigned as the lowest available slot.\nIPEI (International Portable Equipment Identity) is a unique hardware identifier\nfor wireless handsets, formatted as a hexadecimal string up to 20 characters.\n",
        "operationId": "createDECTHandset",
        "tags": [
          "DECT Bases"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateHandsetRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Add a handset",
                  "value": {
                    "ipei": "0328A0000F",
                    "display_name": "Front Desk"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Handset created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTHandset"
                },
                "examples": {
                  "success": {
                    "summary": "Handset paired with base",
                    "value": {
                      "id": "decth_01h2xcejqtf2nbrexx3vqjhp70",
                      "base_id": "dectb_01h2xcejqtf2nbrexx3vqjhp60",
                      "ipei": "0328A0000F",
                      "status": "pending-sync",
                      "display_name": "Front Desk",
                      "slot_number": 1,
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "DECT base not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "DECT base not found"
                }
              }
            }
          },
          "409": {
            "description": "Handset limit reached or IPEI already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "max_handsets": {
                    "value": {
                      "error": "Base station has reached the maximum number of handsets"
                    }
                  },
                  "duplicate_ipei": {
                    "value": {
                      "error": "A handset with this IPEI already exists on this base"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"ipei\":\"0328A0000F\",\"display_name\":\"string\",\"model\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List handsets on a DECT base",
        "description": "List all wireless handsets paired with a DECT base station.\n",
        "operationId": "listDECTHandsets",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "200": {
            "description": "List of handsets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DECTHandset"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases/{id}/handsets/{handset_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "DECT base station identifier",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "handset_id",
          "in": "path",
          "required": true,
          "description": "Handset identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get a handset",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices/{id}` with the handset ID instead.\n\nRetrieve a specific handset.\n",
        "operationId": "getDECTHandset",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "200": {
            "description": "Handset details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTHandset"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Handset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Handset not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update a handset",
        "description": "Update handset properties such as IPEI or display name.\n",
        "operationId": "updateDECTHandset",
        "tags": [
          "DECT Bases"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateHandsetRequest"
              },
              "examples": {
                "update_name": {
                  "summary": "Update display name",
                  "value": {
                    "display_name": "Warehouse"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Handset updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DECTHandset"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Handset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Handset not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"ipei\":\"string\",\"display_name\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete a handset",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}` with the handset ID instead.\n\nRemove a handset from a DECT base station.\nAll extensions on the handset are also removed.\n",
        "operationId": "deleteDECTHandset",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "204": {
            "description": "Handset deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Handset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Handset not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases/{id}/handsets/{handset_id}/extensions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "DECT base station identifier",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "handset_id",
          "in": "path",
          "required": true,
          "description": "Handset identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Assign an extension to a handset",
        "deprecated": true,
        "description": "**Deprecated:** Use `POST /v1/devices/{id}/users` with the handset ID instead.\n\nAssign a SIP endpoint to a DECT handset as an extension (SIP line).\n",
        "operationId": "createDECTExtension",
        "tags": [
          "DECT Bases"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateHandsetLineRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Assign a SIP endpoint",
                  "value": {
                    "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Extension created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HandsetLine"
                },
                "examples": {
                  "success": {
                    "summary": "Extension assigned",
                    "value": {
                      "id": "decte_01h2xcejqtf2nbrexx3vqjhp80",
                      "handset_id": "decth_01h2xcejqtf2nbrexx3vqjhp70",
                      "endpoint_id": "ep_01h2xcejqtf2nbrexx3vqjhp43",
                      "display_name": null,
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Handset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Handset not found"
                }
              }
            }
          },
          "409": {
            "description": "Endpoint already assigned to this handset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Endpoint is already assigned to this handset"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D/extensions \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"endpoint_id\":\"string\",\"display_name\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}/extensions`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List extensions on a handset",
        "deprecated": true,
        "description": "**Deprecated:** Use `GET /v1/devices/{id}/users` with the handset ID instead.\n\nList all SIP line assignments on a DECT handset.\n",
        "operationId": "listDECTExtensions",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "200": {
            "description": "List of extensions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HandsetLine"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Handset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Handset not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D/extensions \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}/extensions`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/dect-bases/{id}/handsets/{handset_id}/extensions/{extension_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "DECT base station identifier",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "handset_id",
          "in": "path",
          "required": true,
          "description": "Handset identifier",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "extension_id",
          "in": "path",
          "required": true,
          "description": "Extension identifier",
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "summary": "Remove an extension from a handset",
        "deprecated": true,
        "description": "**Deprecated:** Use `DELETE /v1/devices/{id}/users/{user_id}` with the handset ID instead.\n\nRemove a SIP line assignment from a DECT handset.\n",
        "operationId": "deleteDECTExtension",
        "tags": [
          "DECT Bases"
        ],
        "responses": {
          "204": {
            "description": "Extension removed"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Extension not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Extension not found"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/dect-bases/%7Bid%7D/handsets/%7Bhandset_id%7D/extensions/%7Bextension_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/dect-bases/{id}/handsets/{handset_id}/extensions/{extension_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/locations": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        }
      ],
      "post": {
        "summary": "Create a location",
        "description": "Create a new business location with a validated address.\n",
        "operationId": "createLocation",
        "tags": [
          "Locations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationRequest"
              },
              "examples": {
                "basic": {
                  "summary": "Create main office",
                  "value": {
                    "name": "Main Office",
                    "address": {
                      "street": "123 Main St",
                      "city": "New York",
                      "state": "NY",
                      "postal_code": "10001",
                      "country": "US"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Location created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Location"
                },
                "examples": {
                  "success": {
                    "summary": "Successful location creation",
                    "value": {
                      "id": "loc_01h2xcejqtf2nbrexx3vqjhp50",
                      "name": "Main Office",
                      "address": {
                        "city": "New York",
                        "state": "NY",
                        "postal_code": "10001",
                        "country": "US",
                        "formatted_address": "123 Main St, New York, NY 10001, US"
                      },
                      "status": "active",
                      "e911_status": "none",
                      "created_at": "2025-10-18T10:00:00Z",
                      "updated_at": "2025-10-18T10:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/locations \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Main Office\",\"address\":{\"address_number\":\"1600\",\"street\":\"Pennsylvania Avenue NW\",\"unit\":\"Suite 200\",\"city\":\"New York\",\"state\":\"NY\",\"postal_code\":\"10001\",\"country\":\"US\"},\"primary_did_id\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List locations",
        "description": "List all locations for the account.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listLocations",
        "tags": [
          "Locations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/LocationStatus"
          }
        ],
        "responses": {
          "200": {
            "description": "List of locations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Location"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                },
                "examples": {
                  "list": {
                    "summary": "Location list response",
                    "value": {
                      "object": "list",
                      "url": "/v1/locations",
                      "next_page_url": null,
                      "previous_page_url": null,
                      "data": [
                        {
                          "id": "loc_01h2xcejqtf2nbrexx3vqjhp50",
                          "name": "Main Office",
                          "address": {
                            "city": "New York",
                            "state": "NY",
                            "postal_code": "10001",
                            "country": "US",
                            "formatted_address": "123 Main St, New York, NY 10001, US"
                          },
                          "status": "active",
                          "e911_status": "none",
                          "created_at": "2025-10-18T10:00:00Z",
                          "updated_at": "2025-10-18T10:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/locations?limit=10&status=active' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/locations/{location_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/LocationId"
        }
      ],
      "get": {
        "summary": "Get location details",
        "description": "Retrieve a specific location by ID.\n",
        "operationId": "getLocation",
        "tags": [
          "Locations"
        ],
        "responses": {
          "200": {
            "description": "Location details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Location"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/LocationNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/locations/loc_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations/{location_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update location",
        "description": "Update location details (name, address, primary phone number, or status).\n",
        "operationId": "updateLocation",
        "tags": [
          "Locations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Location updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Location"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/LocationNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/locations/loc_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Updated Office\",\"address\":{\"address_number\":\"1600\",\"street\":\"Pennsylvania Avenue NW\",\"unit\":\"Suite 200\",\"city\":\"New York\",\"state\":\"NY\",\"postal_code\":\"10001\",\"country\":\"US\"},\"primary_did_id\":\"string\",\"status\":\"active\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations/{location_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "delete": {
        "summary": "Delete location",
        "description": "Delete a location and its associated address.\nThis operation is irreversible.\n",
        "operationId": "deleteLocation",
        "tags": [
          "Locations"
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/LocationDeleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/LocationNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X DELETE \\\n  https://api.dialstack.ai/v1/locations/loc_01h2xcejqtf2nbrexx3vqjhp50 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations/{location_id}`, {\n  method: 'DELETE',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/locations/{location_id}/validate-e911": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/LocationId"
        }
      ],
      "post": {
        "summary": "Validate E911 address",
        "description": "Pre-check the location's address for E911 provisioning.\nReturns the address fields that will be used during provisioning. Full address validation\noccurs during the provision-e911 call.\n",
        "operationId": "validateLocationE911",
        "tags": [
          "Locations"
        ],
        "responses": {
          "200": {
            "description": "Address validation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/E911ValidationResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/LocationNotFound"
          },
          "502": {
            "description": "Upstream provider address validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/locations/loc_01h2xcejqtf2nbrexx3vqjhp50/validate-e911 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations/{location_id}/validate-e911`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/locations/{location_id}/provision-e911": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DialStackAccount"
        },
        {
          "$ref": "#/components/parameters/LocationId"
        }
      ],
      "post": {
        "summary": "Provision E911",
        "description": "Start E911 provisioning for a location.\nThe location must have a primary phone number assigned.\nProvisioning is asynchronous; the `e911_status` field tracks progress.\n",
        "operationId": "provisionLocationE911",
        "tags": [
          "Locations"
        ],
        "responses": {
          "200": {
            "description": "E911 provisioning started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Location"
                }
              }
            }
          },
          "400": {
            "description": "Location is missing a primary phone number",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/LocationNotFound"
          },
          "502": {
            "description": "Upstream provider order failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/locations/loc_01h2xcejqtf2nbrexx3vqjhp50/provision-e911 \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/locations/{location_id}/provision-e911`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/quality/summary": {
      "get": {
        "summary": "Get quality metrics summary",
        "description": "Returns aggregated call quality metrics for the account, including\nKPI averages (MOS, jitter, packet loss) and a time-bucketed series.\nMOS is computed using the ITU-T G.107 E-model.\n",
        "operationId": "getQualitySummary",
        "tags": [
          "Quality"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start of time range (RFC 3339)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End of time range (RFC 3339)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "granularity",
            "in": "query",
            "required": true,
            "description": "Time bucket granularity",
            "schema": {
              "type": "string",
              "enum": [
                "hourly",
                "daily"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quality summary with KPIs and time series",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "kpi": {
                      "type": "object",
                      "properties": {
                        "avg_mos": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Average MOS score (1.0–5.0)"
                        },
                        "avg_jitter_ms": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Average jitter in milliseconds"
                        },
                        "avg_packet_loss_pct": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Average packet loss percentage"
                        },
                        "total_calls": {
                          "type": "integer",
                          "description": "Total number of answered calls with quality data"
                        }
                      }
                    },
                    "time_series": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "bucket": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "avg_mos": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "call_count": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/quality/summary?from=SOME_STRING_VALUE&to=SOME_STRING_VALUE&granularity=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/quality/summary`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/quality/worst-calls": {
      "get": {
        "summary": "Get worst quality calls",
        "description": "Returns the calls with the lowest MOS scores in the given time range,\nsorted by MOS ascending (worst first). Limited to 90-day range.\n",
        "operationId": "getQualityWorstCalls",
        "tags": [
          "Quality"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start of time range (RFC 3339)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End of time range (RFC 3339)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of calls to return (default 10, max 50)",
            "schema": {
              "type": "integer",
              "default": 10,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of worst quality calls",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "calls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Call record ID"
                          },
                          "started_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "inbound",
                              "outbound",
                              "internal"
                            ]
                          },
                          "from_number": {
                            "type": "string"
                          },
                          "to_number": {
                            "type": "string"
                          },
                          "duration_seconds": {
                            "type": "integer"
                          },
                          "mos": {
                            "type": "number",
                            "description": "MOS score (1.0–5.0)"
                          },
                          "jitter_ms": {
                            "type": "number"
                          },
                          "packet_loss_pct": {
                            "type": "number"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/quality/worst-calls?from=SOME_STRING_VALUE&to=SOME_STRING_VALUE&limit=SOME_INTEGER_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/quality/worst-calls`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/quality/device-registrations": {
      "get": {
        "summary": "Get device registration status",
        "description": "Returns the registration status of all endpoints in the account,\nincluding whether each device is currently online or offline and\nits public IP address when available.\n",
        "operationId": "getDeviceRegistrations",
        "tags": [
          "Quality"
        ],
        "responses": {
          "200": {
            "description": "List of device registration statuses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devices": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Endpoint ID"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Endpoint display name"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "online",
                              "offline"
                            ],
                            "description": "Current registration status"
                          },
                          "public_ip": {
                            "type": "string",
                            "description": "Public IP address of the device (when online)"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/quality/device-registrations \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/quality/device-registrations`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/catalog": {
      "get": {
        "summary": "List hardware catalog",
        "description": "Returns the list of active hardware items available for selection during onboarding.\nThis endpoint does not require account context.\n",
        "operationId": "listCatalog",
        "tags": [
          "Catalog"
        ],
        "responses": {
          "200": {
            "description": "List of active hardware catalog items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "example": "list"
                    },
                    "url": {
                      "type": "string",
                      "example": "/v1/catalog"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HardwareCatalogItem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/catalog \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/catalog`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/hardware-orders": {
      "post": {
        "summary": "Create hardware order",
        "description": "Creates a new hardware order in draft status with the given items.\nEach item references a hardware catalog entry with a quantity.\n",
        "operationId": "createHardwareOrder",
        "tags": [
          "Hardware Orders"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HardwareOrderRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Hardware order created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HardwareOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Duplicate catalog item in order"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/hardware-orders \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"items\":[{\"hardware_catalog_id\":\"string\",\"quantity\":1}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/hardware-orders`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "get": {
        "summary": "List hardware orders",
        "description": "Returns all hardware orders for the account, including embedded items.\n",
        "operationId": "listHardwareOrders",
        "tags": [
          "Hardware Orders"
        ],
        "responses": {
          "200": {
            "description": "List of hardware orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "example": "list"
                    },
                    "url": {
                      "type": "string",
                      "example": "/v1/hardware-orders"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HardwareOrder"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/hardware-orders \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/hardware-orders`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/hardware-orders/{order_id}": {
      "get": {
        "summary": "Get hardware order",
        "description": "Returns a hardware order by ID, including embedded items.\n",
        "operationId": "getHardwareOrder",
        "tags": [
          "Hardware Orders"
        ],
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hardware order details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HardwareOrder"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/HardwareOrderNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/hardware-orders/%7Border_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/hardware-orders/{order_id}`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "post": {
        "summary": "Update hardware order items",
        "description": "Replaces all items on a draft order. The order must be in draft status.\nSends the complete desired state of items — existing items are replaced atomically.\n",
        "operationId": "updateHardwareOrder",
        "tags": [
          "Hardware Orders"
        ],
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HardwareOrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hardware order updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HardwareOrder"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/HardwareOrderNotFound"
          },
          "409": {
            "description": "Order not in draft status"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/hardware-orders/%7Border_id%7D \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"items\":[{\"hardware_catalog_id\":\"string\",\"quantity\":1}]}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/hardware-orders/{order_id}`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/auth/token": {
      "post": {
        "summary": "Create a user token",
        "description": "Exchanges your platform's JWT for a DialStack user token. User tokens grant\naccess to the WebRTC signalling channel and user-scoped REST endpoints (`/v1/me/*`).\n\nYour platform must be configured for token exchange during onboarding.\nDialStack verifies your JWT using the JWKS URL and issuer configured for\nyour platform, then maps the subject claim to a DialStack user.\n\nRequires a platform API key. User tokens cannot be used to create new tokens.\n",
        "operationId": "createUserToken",
        "tags": [
          "User Authentication"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthTokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User token created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokenResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/UserNotFound"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/auth/token \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"grant_type\":\"token_exchange\",\"account_id\":\"acct_01h2xcejqtf2nbrexx3vqjhp41\",\"subject_token\":\"string\",\"subject_token_type\":\"urn:ietf:params:oauth:token-type:jwt\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/auth/token`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/auth/refresh": {
      "post": {
        "summary": "Refresh a user token",
        "description": "Extends the lifetime of an existing user token. Returns a new token with\na fresh expiry. The original token remains valid until its own expiry.\n\nRefresh proactively (e.g., 5 minutes before expiry) to avoid interrupting\nactive WebRTC sessions.\n",
        "operationId": "refreshUserToken",
        "tags": [
          "User Authentication"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthRefreshRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token refreshed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokenResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/auth/refresh \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"token\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/auth/refresh`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/auth/revoke": {
      "post": {
        "summary": "Revoke a user token",
        "description": "Immediately invalidates a user token. Any active WebRTC session using\nthis token is disconnected.\n\nCall this when the user logs out of your application.\n",
        "operationId": "revokeUserToken",
        "tags": [
          "User Authentication"
        ],
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthRevokeRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Token revoked"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X POST \\\n  https://api.dialstack.ai/v1/auth/revoke \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"token\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/auth/revoke`, {\n  method: 'POST',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/webrtc/ice-servers": {
      "get": {
        "summary": "Get ICE server credentials",
        "description": "Returns STUN and TURN server configurations for establishing WebRTC peer\nconnections. TURN credentials are time-limited — fetch fresh credentials\nbefore the `expires_at` timestamp.\n\nCall this before initiating or answering a call. The returned configuration\ncan be passed directly to `RTCPeerConnection` as `iceServers`.\n",
        "operationId": "getIceServers",
        "tags": [
          "WebRTC"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "ICE server configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IceServersResponse"
                },
                "example": {
                  "ice_servers": [
                    {
                      "urls": "stun:stun.dialstack.ai:3478"
                    },
                    {
                      "urls": [
                        "turn:turn.dialstack.ai:443?transport=tcp",
                        "turn:turn.dialstack.ai:443?transport=udp"
                      ],
                      "username": "1712793600:user_01h2xcejqtf2nbrexx3vqjhp42",
                      "credential": "aGVsbG8gd29ybGQ="
                    }
                  ],
                  "expires_at": "2026-04-10T22:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/webrtc/ice-servers \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/webrtc/ice-servers`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Get current user profile",
        "description": "Returns the authenticated user's profile, including their assigned extensions\nand registered devices.\n",
        "operationId": "getCurrentUser",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "User profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserProfile"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/me \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/me/calls": {
      "get": {
        "summary": "List own call history",
        "description": "Returns call records where the authenticated user was a participant.\nResults are returned in reverse chronological order (newest first).\n",
        "operationId": "listOwnCalls",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "direction",
            "in": "query",
            "description": "Filter by call direction",
            "schema": {
              "type": "string",
              "enum": [
                "inbound",
                "outbound"
              ]
            }
          },
          {
            "name": "from_date",
            "in": "query",
            "description": "Return calls on or after this date (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "description": "Return calls before this date (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of call records",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "$ref": "#/components/schemas/ListObject"
                    },
                    "url": {
                      "$ref": "#/components/schemas/ListUrl"
                    },
                    "next_page_url": {
                      "$ref": "#/components/schemas/NextPageUrl"
                    },
                    "previous_page_url": {
                      "$ref": "#/components/schemas/PreviousPageUrl"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CallLog"
                      }
                    }
                  },
                  "required": [
                    "object",
                    "url",
                    "next_page_url",
                    "previous_page_url",
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  'https://api.dialstack.ai/v1/me/calls?limit=10&direction=SOME_STRING_VALUE&from_date=SOME_STRING_VALUE&to_date=SOME_STRING_VALUE' \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me/calls`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/me/presence": {
      "get": {
        "summary": "Get own presence status",
        "description": "Returns the authenticated user's current presence status.\n",
        "operationId": "getOwnPresence",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Presence status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresenceStatus"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/me/presence \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me/presence`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "put": {
        "summary": "Update own presence status",
        "description": "Updates the authenticated user's presence status. Only `available`, `dnd`,\nand `away` can be set manually. The `on_call` and `offline` statuses are\nmanaged automatically by the system.\n",
        "operationId": "updateOwnPresence",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresenceUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presence updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresenceStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X PUT \\\n  https://api.dialstack.ai/v1/me/presence \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"status\":\"available\",\"status_text\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me/presence`, {\n  method: 'PUT',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    },
    "/v1/me/emergency-address": {
      "get": {
        "summary": "Get emergency address",
        "description": "Returns the authenticated user's registered emergency address for E911.\nReturns 404 if no address has been registered.\n",
        "operationId": "getEmergencyAddress",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Emergency address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmergencyAddress"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No emergency address registered"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X GET \\\n  https://api.dialstack.ai/v1/me/emergency-address \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me/emergency-address`, {\n  method: 'GET',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n  },\n});\n\nconst data = await res.json();"
          }
        ]
      },
      "put": {
        "summary": "Set emergency address",
        "description": "Registers or updates the user's emergency address for E911. The address\nis validated against the MSAG (Master Street Address Guide) before saving.\nIf validation fails, the response includes suggestions.\n\nAn emergency address is required before the user can place calls. Attempting\nto dial without a validated address returns an error on the signalling channel.\n",
        "operationId": "setEmergencyAddress",
        "tags": [
          "User Profile"
        ],
        "security": [
          {
            "UserAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmergencyAddressRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Emergency address validated and saved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmergencyAddress"
                }
              }
            }
          },
          "400": {
            "description": "Address validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message",
                      "examples": [
                        "Address could not be validated"
                      ]
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "address_validation_failed"
                      ]
                    },
                    "suggestions": {
                      "type": "array",
                      "description": "Suggested corrected addresses (if available)",
                      "items": {
                        "$ref": "#/components/schemas/EmergencyAddressRequest"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "curl",
            "source": "curl -X PUT \\\n  https://api.dialstack.ai/v1/me/emergency-address \\\n  -H 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n  -H 'content-type: application/json' \\\n  -d '{\"street\":\"string\",\"street2\":\"string\",\"city\":\"string\",\"state\":\"string\",\"zip\":\"string\",\"country\":\"string\"}'"
          },
          {
            "lang": "TypeScript",
            "label": "fetch",
            "source": "const res = await fetch(`https://api.dialstack.ai/v1/me/emergency-address`, {\n  method: 'PUT',\n  headers: {\n    'Authorization': \\`Bearer \\${process.env.DIALSTACK_KEY}\\`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({ /* request body */ }),\n});\n\nconst data = await res.json();"
          }
        ]
      }
    }
  },
  "tags": [
    {
      "name": "Audit Logs",
      "description": "Read-only access to audit trail entries"
    },
    {
      "name": "Accounts",
      "description": "Account (customer organization) management.\nThese endpoints operate at the platform level and don't require the `DialStack-Account` header.\n"
    },
    {
      "name": "Sessions",
      "description": "Account session management for embedded components.\nSessions provide scoped authentication for frontend components.\nRequires a platform API key — session tokens cannot be used to create new sessions.\n"
    },
    {
      "name": "Users",
      "description": "User (people) management.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Voicemails",
      "description": "Voicemail message management.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Calls",
      "description": "Call initiation, history, and real-time monitoring.\nUse POST /v1/calls to initiate click-to-call, GET /v1/calls to retrieve call history,\nand POST /v1/calls/{call_id}/listeners to stream real-time audio from active calls.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Phone Numbers",
      "description": "Phone number (DID) management including search, ordering, and disconnect.\nRequires account context via `DialStack-Account` header or session token.\nFor porting existing numbers from another carrier, see Number Porting.\n"
    },
    {
      "name": "Number Porting",
      "description": "Number porting (port-in) management. Transfer existing phone numbers from another\ncarrier to DialStack. The eligibility check endpoint does not require the\n`DialStack-Account` header.\n"
    },
    {
      "name": "AI Agents",
      "description": "AI-powered voice agent management.\nAI agents provide automated call handling with customizable instructions and FAQ responses.\nEach agent automatically manages a voice app and extension for call routing.\nRequires account context via `DialStack-Account` header.\n"
    },
    {
      "name": "Voice Apps",
      "description": "Voice app management for programmable voice applications.\nVoice apps handle calls via HTTP webhook notification and optional WebSocket audio streaming.\nRequires account context via `DialStack-Account` header.\n"
    },
    {
      "name": "Events",
      "description": "Real-time event streaming via Server-Sent Events (SSE).\nUse this endpoint to receive live notifications about calls, voicemails, and other account activity.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Schedules",
      "description": "Business hours schedule management.\nSchedules define when the business is open based on weekly time ranges and holidays.\nA temporary hold can override the schedule calculation.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Dial Plans",
      "description": "Visual call routing graph management.\nDial plans define how calls are routed through nodes (schedules, extensions).\nMultiple extensions can share the same dial plan.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Ring Groups",
      "description": "Ring group management for parallel dialing (call forking).\nRing groups dial multiple members simultaneously; the first to answer wins.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Shared Voicemail Boxes",
      "description": "Shared voicemail box management for team or departmental voicemail.\nShared voicemail boxes can receive messages and forward them via email.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Audio Clips",
      "description": "Audio clip management for hold music, IVR prompts, and other audio playback.\nUpload audio files which are validated and transcoded server-side.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Extensions",
      "description": "Extension (dial code) management.\nExtensions map short dial codes to routing targets.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Locations",
      "description": "Business location management.\nLocations represent physical offices or business premises with validated addresses.\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Devices",
      "description": "Unified device API for deskphones, DECT bases, and DECT handsets.\n**This is the recommended way to manage devices.** Use `/v1/devices` to\ncreate, list, get, and delete any device type, and `/v1/devices/{id}/users`\nto assign and manage users on any device type.\n\nThe type-specific `/v1/deskphones` and `/v1/dect-bases` endpoints are\nretained only for operations that have no unified equivalent yet\n(updates, provisioning-events, listing handsets under a specific base).\nPrefer `/v1/devices` everywhere else.\n\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Deskphones",
      "description": "Deskphone-specific operations retained for the cases `/v1/devices` does\nnot cover yet (updates and provisioning events). For create, list, get,\nand delete, use the unified [Devices](#tag/Devices) API — it is the\nrecommended approach for all new integrations.\n\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "DECT Bases",
      "description": "DECT-specific operations retained for the cases `/v1/devices` does not\ncover yet (updates and listing handsets under a specific base). For\ncreate, list, get, and delete of bases and handsets, use the unified\n[Devices](#tag/Devices) API — it is the recommended approach for all\nnew integrations.\n\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "Catalog",
      "description": "Hardware catalog listing.\nReturns available hardware items for selection during onboarding.\nDoes not require account context.\n"
    },
    {
      "name": "Hardware Orders",
      "description": "Hardware order management.\nOrders contain line items representing hardware selections (model + quantity).\nRequires account context via `DialStack-Account` header or session token.\n"
    },
    {
      "name": "User Authentication",
      "description": "User-level authentication for softphones and user-facing applications.\nAuthenticate end users to obtain tokens for WebRTC signalling and user-scoped\nREST endpoints. Supports token exchange, managed credentials, and SSO.\nRequires a platform API key to create tokens.\n"
    },
    {
      "name": "WebRTC",
      "description": "WebRTC configuration for softphone applications.\nProvides ICE server credentials for establishing peer connections.\nThe signalling protocol is documented in the [WebRTC Signalling Protocol](/webrtc/protocol).\nRequires a user token.\n"
    },
    {
      "name": "User Profile",
      "description": "User-scoped REST endpoints for softphone and user-facing applications.\nReturns data scoped to the authenticated user (own call history, voicemails,\npresence, device registration). Requires a user token.\n"
    },
    {
      "name": "Quality",
      "description": "Call quality metrics and device registration health.\nAggregate MOS/packet-loss summaries, worst-call lookups, and live device\nregistration state for monitoring and troubleshooting.\nRequires account context via `DialStack-Account` header or session token.\n"
    }
  ],
  "x-tagGroups": [
    {
      "name": "Accounts & Users",
      "tags": [
        "Accounts",
        "Sessions",
        "Users",
        "User Profile",
        "User Authentication",
        "Extensions"
      ]
    },
    {
      "name": "Calls",
      "tags": [
        "Calls",
        "Voicemails",
        "Events",
        "WebRTC"
      ]
    },
    {
      "name": "Routing",
      "tags": [
        "Dial Plans",
        "Ring Groups",
        "Schedules",
        "Shared Voicemail Boxes",
        "Audio Clips",
        "Phone Numbers",
        "Number Porting",
        "Locations"
      ]
    },
    {
      "name": "AI & Voice Apps",
      "tags": [
        "AI Agents",
        "Voice Apps"
      ]
    },
    {
      "name": "Devices & Hardware",
      "tags": [
        "Devices",
        "Deskphones",
        "DECT Bases",
        "Hardware Orders",
        "Catalog"
      ]
    },
    {
      "name": "Platform",
      "tags": [
        "Audit Logs",
        "Quality"
      ]
    }
  ]
}