{
  "openapi": "3.0.3",
  "info": {
    "title": "Multitel v3 API",
    "description": "Multitel DID number management, messaging, fax, calls, and telephony API.\n\n## Authentication\n\nEndpoints use the authentication rules documented for each API family. The Calls API accepts one of:\n- **HTTP Basic Auth** — `Authorization: Basic base64(username:password)` using the customer `users.username` / `users.password` pair or a dedicated API account\n- **Bearer Token** — `Authorization: Bearer <api_token>` from an enabled, IP-restricted API account\n\nDedicated API accounts must have a current explicit `calls:write` approval in my.multi.tel. Customer user credentials do not require that separate API-account approval. Legacy subaccount credentials are not accepted by the Calls API.",
    "version": "3.0.0",
    "contact": {
      "name": "Multitel Support",
      "url": "https://www.multitel.net",
      "email": "support@multitel.net"
    }
  },
  "servers": [
    {
      "url": "https://api.multitel.net/v3",
      "description": "Production"
    }
  ],
  "security": [
    { "basicAuth": [] },
    { "bearerAuth": [] }
  ],
  "tags": [
    { "name": "Countries & Geography", "description": "Country, state, area, and prefix lookups" },
    { "name": "Number Search & Ordering", "description": "Search, reserve, and purchase phone numbers" },
    { "name": "Number Management", "description": "Inventory, configuration, release, and restore" },
    { "name": "Caller ID / CNAM / LIDB", "description": "CNAM lookups, LIDB updates, directory listings" },
    { "name": "Number Lookup", "description": "Number validation, LRN dips, carrier lookups" },
    { "name": "CDRs & Billing", "description": "Call detail records, balance, pricing" },
    { "name": "Messaging", "description": "SMS sending and utilities" },
    { "name": "Fax", "description": "Fax sending, inbox, outbox, and file management" },
    { "name": "Calls", "description": "Customer-authorized click-to-call and outbound call status" },
    { "name": "E911", "description": "911 address provisioning and management" },
    { "name": "10DLC Brand & Campaign", "description": "10DLC brand registration and campaign management" },
    { "name": "SIP", "description": "SIP account provisioning and management" },
    { "name": "eSIM", "description": "eSIM provisioning and management" },
    { "name": "Regulatory Documents", "description": "Identity documents and regulatory compliance" },
    { "name": "WhatsApp", "description": "WhatsApp messaging and sender management" }
  ],
  "paths": {
    "/countries": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "List countries with numbers in stock",
        "description": "Returns a list of countries where DID numbers are available. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "List of countries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "integer", "example": 200 },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "countrycode": { "type": "string", "example": "1", "description": "Dial prefix / country calling code" },
                          "name": { "type": "string", "example": "United States", "description": "Country display name" },
                          "description": { "type": "string", "example": "US Local DIDs", "description": "Additional description" },
                          "isocode": { "type": "string", "example": "US", "description": "ISO 3166-1 alpha-2 country code" },
                          "latitude": { "type": "string", "example": "37.0902", "description": "Country centroid latitude" },
                          "longitude": { "type": "string", "example": "-95.7129", "description": "Country centroid longitude" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/getstates/{iso}": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "List states/provinces with stock",
        "description": "Returns states or provinces for US or CA that have available number inventory.",
        "parameters": [
          {
            "name": "iso",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "US" },
            "description": "Country ISO code (US or CA)"
          }
        ],
        "responses": {
          "200": { "description": "List of states with available numbers" }
        }
      }
    },
    "/getareas/{iso}": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "List DID coverage areas",
        "description": "Returns DID coverage areas (cities/regions) for a given country ISO code. Optionally filterable by state.",
        "parameters": [
          {
            "name": "iso",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "US" },
            "description": "Country ISO code"
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "example": "NY" },
            "description": "State/province code to filter by"
          }
        ],
        "responses": {
          "200": { "description": "List of areas with available numbers" }
        }
      }
    },
    "/getprefixes/{area_id}": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "List prefixes for an area",
        "description": "Returns available DID prefixes (NPA/NXX or equivalent) for a given area UUID.",
        "parameters": [
          {
            "name": "area_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Area UUID"
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "example": "CA" },
            "description": "2-letter state code to filter prefixes"
          }
        ],
        "responses": {
          "200": { "description": "List of prefixes with pricing" }
        }
      }
    },
    "/get-prefix/{prefix_uuid}": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "Get prefix details",
        "description": "Returns detailed prefix info including pricing and available number counts.",
        "parameters": [
          {
            "name": "prefix_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          },
          {
            "name": "channels",
            "in": "query",
            "required": false,
            "schema": { "type": "integer" },
            "description": "Requested channel count"
          },
          {
            "name": "price_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Specific price UUID (also accepted as priceid)"
          }
        ],
        "responses": {
          "200": { "description": "Prefix details with pricing" }
        }
      }
    },
    "/getregistration/{area_id}/{iso}": {
      "get": {
        "tags": ["Countries & Geography"],
        "summary": "Get regulatory registration requirements",
        "description": "Returns the regulatory registration requirement message for a given area and country.",
        "parameters": [
          {
            "name": "area_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Area UUID"
          },
          {
            "name": "iso",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Country ISO code"
          }
        ],
        "responses": {
          "200": { "description": "Registration requirements" }
        }
      }
    },

    "/getnumbers/{prefix_id}/{quantity}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Search available numbers",
        "description": "Fetches available telephone numbers for a given prefix UUID and requested quantity.",
        "parameters": [
          {
            "name": "prefix_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          },
          {
            "name": "quantity",
            "in": "path",
            "required": true,
            "schema": { "type": "integer", "default": 1 },
            "description": "Number of results to return"
          }
        ],
        "responses": {
          "200": { "description": "List of available numbers with pricing" }
        }
      }
    },
    "/getmobiles/{prefix_id}/{quantity}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Search available mobile numbers",
        "description": "Same as getnumbers but restricted to wireless/mobile number types (US only).",
        "parameters": [
          {
            "name": "prefix_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          },
          {
            "name": "quantity",
            "in": "path",
            "required": true,
            "schema": { "type": "integer", "default": 1 },
            "description": "Number of results to return"
          }
        ],
        "responses": {
          "200": { "description": "List of available mobile numbers" }
        }
      }
    },
    "/getmobilecount/{prefix_id}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Count available mobile numbers",
        "description": "Returns inventory count of available mobile numbers for a prefix.",
        "parameters": [
          {
            "name": "prefix_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          }
        ],
        "responses": {
          "200": { "description": "Mobile number count" }
        }
      }
    },
    "/reservednumbers": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "List numbers in cart",
        "description": "Lists numbers currently in the authenticated user's cart (reserved but not yet purchased).",
        "responses": {
          "200": { "description": "List of reserved numbers" }
        }
      }
    },
    "/reservenumber/{uuid}/{price_uuid}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Add number to cart",
        "description": "Reserves a number and adds it to the user's cart with a chosen price plan.",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Number or number UUID"
          },
          {
            "name": "price_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Price plan UUID"
          }
        ],
        "responses": {
          "200": { "description": "Number reserved" }
        }
      }
    },
    "/unreservenumber/{uuid}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Remove number from cart",
        "description": "Removes a number from the user's cart/reservation.",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Number or number UUID"
          }
        ],
        "responses": {
          "200": { "description": "Number unreserved" }
        }
      }
    },
    "/rentnumber/{uuid}/{price_uuid}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Purchase a number",
        "description": "Purchases (activates) a single number, charging the user's balance. The number does not need to be in the cart first.",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Number or number UUID"
          },
          {
            "name": "price_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Price plan UUID"
          }
        ],
        "responses": {
          "200": { "description": "Number purchased successfully" }
        }
      }
    },
    "/rentnumbers": {
      "post": {
        "tags": ["Number Search & Ordering"],
        "summary": "Bulk purchase numbers",
        "description": "Purchases multiple numbers at once from a JSON array.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tnlist"],
                "properties": {
                  "tnlist": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "tn": { "type": "string", "description": "Phone number or UUID" },
                        "price_uuid": { "type": "string", "description": "Price plan UUID" }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Bulk purchase results" }
        }
      }
    },
    "/order/{prefix_uuid}": {
      "post": {
        "tags": ["Number Search & Ordering"],
        "summary": "Search and purchase in one call",
        "description": "Searches for available numbers by prefix, selects one, and purchases it. Supports quantity, channels, price selection, and webhook notification for async results.",
        "parameters": [
          {
            "name": "prefix_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "quantity": { "type": "integer", "default": 1, "maximum": 100, "description": "Number of DIDs to order (max 100)" },
                  "channels": { "type": "string", "description": "Number of channels to assign" },
                  "price_id": { "type": "string", "description": "Specific price UUID to use" },
                  "webhook_url": { "type": "string", "description": "URL to POST async order result to" },
                  "reference": { "type": "string", "maxLength": 255, "description": "Client reference string attached to webhook payload" }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "quantity": { "type": "integer", "default": 1, "maximum": 100, "description": "Number of DIDs to order (max 100)" },
                  "channels": { "type": "string", "description": "Number of channels to assign" },
                  "price_id": { "type": "string", "description": "Specific price UUID to use" },
                  "webhook_url": { "type": "string", "description": "URL to POST async order result to" },
                  "reference": { "type": "string", "maxLength": 255, "description": "Client reference string attached to webhook payload" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Order result with purchased number(s)" }
        }
      }
    },
    "/backorder/{prefix_uuid}/{price_uuid}": {
      "get": {
        "tags": ["Number Search & Ordering"],
        "summary": "Backorder a number",
        "description": "Places a backorder request for a number in a prefix area that has no immediate stock.",
        "parameters": [
          {
            "name": "prefix_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Prefix UUID"
          },
          {
            "name": "price_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Price plan UUID"
          }
        ],
        "responses": {
          "200": { "description": "Backorder placed" }
        }
      }
    },

    "/inventory": {
      "get": {
        "tags": ["Number Management"],
        "summary": "List purchased numbers",
        "description": "Returns the user's full purchased number inventory with configuration, features, billing, pricing, and trunk details.",
        "responses": {
          "200": {
            "description": "Number inventory",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "integer", "example": 200 },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/NumberDetail" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inventory/{number}": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Get single number from inventory",
        "description": "Returns full details for a specific purchased number.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "12125551234" },
            "description": "Phone number (E.164 without +)"
          }
        ],
        "responses": {
          "200": {
            "description": "Number details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "integer", "example": 200 },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/NumberDetail" }
                    }
                  }
                }
              }
            }
          },
          "404": { "description": "Number not found in your account" }
        }
      }
    },
    "/numberinfo/{number}": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Get detailed number info",
        "description": "Returns detailed information for a single purchased number including trunk, features, capacity, registration status, and pricing.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "12125551234" },
            "description": "Phone number (E.164 without +)"
          }
        ],
        "responses": {
          "200": {
            "description": "Number info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "integer", "example": 200 },
                    "data": { "$ref": "#/components/schemas/NumberDetail" }
                  }
                }
              }
            }
          },
          "404": { "description": "Number not found" }
        }
      }
    },
    "/modifynumber/{number}": {
      "post": {
        "tags": ["Number Management"],
        "summary": "Update number configuration",
        "description": "Updates the configuration for a purchased number. All fields are optional — only provided fields will be updated.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "12125551234" },
            "description": "Phone number (E.164 without +)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "uri": { "type": "string", "description": "Primary SIP URI or phone number to forward calls to", "example": "user@sip.example.com" },
                  "uri2": { "type": "string", "description": "Secondary failover SIP URI" },
                  "uri3": { "type": "string", "description": "Tertiary failover SIP URI" },
                  "ringtype": { "type": "string", "description": "Ring type: 1=SIP URI, 2=PSTN, 3=SIP Registration", "enum": ["1", "2", "3"] },
                  "cnam": { "type": "string", "description": "Caller ID name (CNAM)", "example": "My Company" },
                  "description": { "type": "string", "description": "Description/label for this number" },
                  "smsuri": { "type": "string", "description": "SMS forwarding URI or webhook URL" },
                  "smsringtype": { "type": "string", "description": "SMS forwarding type" },
                  "autorenew": { "type": "string", "description": "Auto-renew: 1=enabled, 0=disabled", "enum": ["0", "1"] },
                  "overflow": { "type": "string", "description": "Allow overflow channels: 1=yes, 0=no", "enum": ["0", "1"] },
                  "forcecodec": { "type": "string", "description": "Force audio codec (e.g. g729, ulaw, alaw)" },
                  "forcedtmf": { "type": "string", "description": "Force DTMF mode (e.g. rfc2833, inband, info)" },
                  "leg_timeout": { "type": "string", "description": "Ring timeout in seconds before failover" },
                  "origintrunk": { "type": "string", "description": "Origination trunk ID or name" },
                  "type": { "type": "string", "description": "Forward destination type" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Number updated successfully" },
          "400": { "description": "Number is required" },
          "403": { "description": "POST method required" },
          "404": { "description": "Number not in your account" },
          "500": { "description": "Could not update" }
        }
      }
    },
    "/release/{number}": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Release a number",
        "description": "Cancels/releases a purchased number. An early-release fee may apply within the minimum commitment period.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number to release"
          }
        ],
        "responses": {
          "200": { "description": "Number released" },
          "404": { "description": "Number not found" }
        }
      }
    },
    "/restore/{number}": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Re-activate a released number",
        "description": "Re-activates a single previously released number, charging the appropriate setup and monthly fees.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number to restore"
          }
        ],
        "responses": {
          "200": { "description": "Number restored" }
        }
      }
    },
    "/bulk_restore": {
      "post": {
        "tags": ["Number Management"],
        "summary": "Bulk restore released numbers",
        "description": "Re-activates multiple released numbers at once. For batches over 10, supports async mode with webhook callback. webhook_url is conditionally required for large batches and must be an HTTPS URL.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numbers": {
                    "type": "array",
                    "items": { "type": "string" },
                    "description": "List of phone numbers to restore"
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "HTTPS webhook URL for async notification (conditionally required for batches over 10 numbers)",
                    "example": "https://example.com/webhook/bulk-restore"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Restore results or job UUID for async" }
        }
      }
    },
    "/bulk_restore_status": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Poll bulk restore status",
        "description": "Polls the status of an async bulk restore job.",
        "parameters": [
          {
            "name": "job_uuid",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Job UUID returned from bulk_restore"
          },
          {
            "name": "number",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Filter status by specific number"
          }
        ],
        "responses": {
          "200": { "description": "Job status" }
        }
      }
    },
    "/getdidlogs/{number}": {
      "get": {
        "tags": ["Number Management"],
        "summary": "Get DID query log",
        "description": "Returns the most recent DID query log entry for a specific number.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          }
        ],
        "responses": {
          "200": { "description": "DID log entry" }
        }
      }
    },
    "/get_dids": {
      "post": {
        "tags": ["Number Management"],
        "summary": "List DIDs",
        "description": "Lists DIDs for the authenticated user with filtering, pagination, and date range options. Optionally scoped to a sub-account.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sub_user": { "type": "string", "description": "Sub-account UUID to scope results to" },
                  "page_size": { "type": "integer", "default": 50, "description": "Number of results per page" },
                  "page_num": { "type": "integer", "default": 1, "description": "Page number (1-based)" },
                  "number": { "type": "string", "description": "Search/filter by phone number" },
                  "start_date": { "type": "string", "description": "Filter purchase date from (YYYY-MM-DD)", "example": "2025-01-01" },
                  "end_date": { "type": "string", "description": "Filter purchase date to (YYYY-MM-DD)", "example": "2025-12-31" },
                  "status": { "type": "string", "description": "Filter by status: 'active' returns non-voided numbers; any other value returns voided numbers", "example": "active" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "List of DIDs" }
        }
      }
    },
    "/check_numbers": {
      "post": {
        "tags": ["Number Management"],
        "summary": "Check number availability (internal)",
        "description": "Internal/admin endpoint. Checks the availability or status of one or more phone numbers. Not intended for general API use.",
        "responses": {
          "200": { "description": "Number status results" }
        }
      }
    },

    "/cnam/{number}": {
      "get": {
        "tags": ["Caller ID / CNAM / LIDB"],
        "summary": "CNAM lookup or update",
        "description": "Performs a CNAM (outbound caller ID name) lookup or update for a number.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          }
        ],
        "responses": {
          "200": { "description": "CNAM result" }
        }
      }
    },
    "/lidb/{number}": {
      "post": {
        "tags": ["Caller ID / CNAM / LIDB"],
        "summary": "LIDB update",
        "description": "Submits a LIDB (Line Information Database) update to set the calling name. Charges $5 per update.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["typeofservice", "callingname"],
                "properties": {
                  "typeofservice": { "type": "string", "description": "Type of service code (e.g. 'R' for residential)", "example": "R" },
                  "callingname": { "type": "string", "description": "Caller ID name to provision (must contain at least one letter)", "example": "John Smith" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "LIDB order submitted" }
        }
      }
    },
    "/directory/{number}": {
      "post": {
        "tags": ["Caller ID / CNAM / LIDB"],
        "summary": "411 directory listing",
        "description": "Submits a 411 directory listing order for a number with name and address info. Charges $10.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["lastname", "city", "postalcode", "state", "streetname", "streetnum"],
                "properties": {
                  "lastname": { "type": "string", "description": "Last name" },
                  "city": { "type": "string", "description": "City" },
                  "postalcode": { "type": "string", "description": "ZIP/postal code" },
                  "state": { "type": "string", "description": "State abbreviation", "example": "NY" },
                  "streetname": { "type": "string", "description": "Street name" },
                  "streetnum": { "type": "string", "description": "Street number" },
                  "firstname": { "type": "string", "description": "First name (optional)" },
                  "streetpredir": { "type": "string", "description": "Pre-directional, e.g. 'N'", "example": "N" },
                  "streettype": { "type": "string", "description": "Street type, e.g. 'Ave'", "example": "Ave" },
                  "streetpostdir": { "type": "string", "description": "Post-directional" },
                  "location": { "type": "string", "description": "Suite/apartment number" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Directory listing submitted" }
        }
      }
    },
    "/callerregistry": {
      "post": {
        "tags": ["Caller ID / CNAM / LIDB"],
        "summary": "Register caller identity",
        "description": "Registers a caller identity (business or individual) with the caller registry to improve call answer rates.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type", "claim", "phoneNumber", "displayName", "category", "companyName", "companyAddressLine1", "city", "state", "zip", "companyUrl", "contactEmail", "contactPhone", "contactName"],
                "properties": {
                  "type": { "type": "string", "description": "Registration type" },
                  "claim": { "type": "string", "description": "Claim identifier" },
                  "phoneNumber": {
                    "oneOf": [
                      { "type": "string", "description": "Single phone number" },
                      { "type": "array", "items": { "type": "string" }, "description": "Array of phone numbers" }
                    ],
                    "description": "Phone number(s) to register"
                  },
                  "displayName": { "type": "string", "description": "Display name shown to call recipients" },
                  "category": { "type": "string", "description": "Call category" },
                  "companyName": { "type": "string", "description": "Company or organization name" },
                  "companyAddressLine1": { "type": "string", "description": "Company street address" },
                  "city": { "type": "string", "description": "City" },
                  "state": { "type": "string", "description": "State abbreviation" },
                  "zip": { "type": "string", "description": "ZIP/postal code" },
                  "companyUrl": { "type": "string", "description": "Company website URL" },
                  "contactEmail": { "type": "string", "description": "Contact email address" },
                  "contactPhone": { "type": "string", "description": "Contact phone number" },
                  "contactName": { "type": "string", "description": "Contact person name" },
                  "explanation": { "type": "string", "description": "Optional explanation or notes" },
                  "companyAddressLine2": { "type": "string", "description": "Company address line 2 (suite, floor, etc.)" },
                  "serviceProvider": { "type": "string", "description": "Service provider name" },
                  "callCount": { "type": "integer", "description": "Estimated daily call volume" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Caller registry registration submitted" }
        }
      }
    },

    "/nanpacheck/{number}": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "NANPA number validation",
        "description": "Validates a North American phone number against NANPA allocation tables, returning city, state, and country.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "example": "2125551234" },
            "description": "Phone number to validate"
          }
        ],
        "responses": {
          "200": { "description": "NANPA validation result" }
        }
      }
    },
    "/lrninfo/{number}": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "LRN and carrier routing info",
        "description": "Returns Local Routing Number and carrier routing information for a number.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          }
        ],
        "responses": {
          "200": { "description": "LRN info" }
        }
      }
    },
    "/lrn/{number}/{ani}": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "Live LRN dip",
        "description": "Performs a live LRN dip, returning ported status, OCN, carrier name, and SPID.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number to look up"
          },
          {
            "name": "ani",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "ANI (calling number)"
          }
        ],
        "responses": {
          "200": { "description": "LRN dip result" }
        }
      }
    },
    "/validate_number/{phone}": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "Full number validation",
        "description": "Validates a phone number's format and region. For US/CA numbers, also checks NANPA tables and LRN ported status.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number to validate"
          }
        ],
        "responses": {
          "200": { "description": "Validation result" }
        }
      }
    },
    "/gettermcost": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "Get termination cost",
        "description": "Returns the outbound per-minute termination rate for a destination number based on the user's rate deck.",
        "parameters": [
          {
            "name": "number",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Destination phone number"
          }
        ],
        "responses": {
          "200": { "description": "Termination rate" }
        }
      }
    },
    "/getnumberofchannels": {
      "get": {
        "tags": ["Number Lookup"],
        "summary": "Get channel capacity",
        "description": "Returns purchased, available, and per-channel pricing for a given DID number.",
        "parameters": [
          {
            "name": "Number",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number to query (case-sensitive parameter name)"
          }
        ],
        "responses": {
          "200": { "description": "Channel info" }
        }
      }
    },

    "/cdrs/{number}/{direction}": {
      "post": {
        "tags": ["CDRs & Billing"],
        "summary": "Get call detail records",
        "description": "Returns call detail records for inbound or outbound calls within a date range. Defaults to last 30 days.",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Phone number"
          },
          {
            "name": "direction",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "enum": ["inbound", "outbound"], "default": "inbound" },
            "description": "Call direction"
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "date_from": { "type": "string", "description": "Start date (YYYY-MM-DD), defaults to 30 days ago", "example": "2025-01-01" },
                  "date_to": { "type": "string", "description": "End date (YYYY-MM-DD), defaults to today", "example": "2025-01-31" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "CDR list" }
        }
      }
    },
    "/getpriceinfo/{price_uuid}": {
      "get": {
        "tags": ["CDRs & Billing"],
        "summary": "Get pricing details",
        "description": "Returns setup, monthly, per-minute, and channel pricing for a specific price plan UUID.",
        "parameters": [
          {
            "name": "price_uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Price plan UUID"
          }
        ],
        "responses": {
          "200": { "description": "Price details" }
        }
      }
    },
    "/getbalance": {
      "get": {
        "tags": ["CDRs & Billing"],
        "summary": "Get account balance",
        "description": "Returns the user's current account balance, currency, and payment terms.",
        "responses": {
          "200": {
            "description": "Balance info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "integer", "example": 200 },
                    "data": {
                      "type": "object",
                      "properties": {
                        "balance": { "type": "string", "example": "125.50" },
                        "currency": { "type": "string", "example": "USD" },
                        "terms": { "type": "string", "example": "prepaid" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/add_balance": {
      "post": {
        "tags": ["CDRs & Billing"],
        "summary": "Top up balance",
        "description": "Charges a saved card to top up the user's account balance. Minimum $5, maximum $500.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["amount"],
                "properties": {
                  "amount": { "type": "number", "description": "Amount in USD ($5-$500)", "example": 50 },
                  "card_id": { "type": "string", "description": "Saved card ID (uses default if not specified)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Balance topped up" }
        }
      }
    },

    "/sendsms": {
      "post": {
        "tags": ["Messaging"],
        "summary": "Send SMS",
        "description": "Sends an SMS or MMS message. Supports multiple recipients (comma-separated or array).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["from", "to"],
                "properties": {
                  "from": { "type": "string", "description": "Sender number (must be a purchased DID)", "example": "12125551234" },
                  "to": {
                    "oneOf": [
                      { "type": "string", "description": "Recipient number or comma-separated list", "example": "14155559876" },
                      { "type": "array", "items": { "type": "string" }, "description": "Array of recipient numbers" }
                    ]
                  },
                  "text": { "type": "string", "description": "Message body (required if no media)", "example": "Hello from Multitel!" },
                  "media": { "type": "string", "description": "Media URL for MMS (required if no text)" }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["from", "to", "text"],
                "properties": {
                  "from": { "type": "string", "description": "Sender number" },
                  "to": { "type": "string", "description": "Recipient number(s), comma-separated" },
                  "text": { "type": "string", "description": "Message body" },
                  "media": { "type": "string", "description": "Media URL for MMS" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "SMS sent" },
          "403": { "description": "SMS not enabled or missing parameters" }
        }
      }
    },
    "/smslength": {
      "get": {
        "tags": ["Messaging"],
        "summary": "Calculate SMS segments",
        "description": "Calculates the SMS segment count and character info for a given message body.",
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Message text to analyze"
          }
        ],
        "responses": {
          "200": { "description": "Segment count and character info" }
        }
      },
      "post": {
        "tags": ["Messaging"],
        "summary": "Calculate SMS segments",
        "description": "Calculates the SMS segment count and character info for a message body supplied as JSON or form-encoded data.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["text"],
                "properties": {
                  "text": { "type": "string", "description": "Message text to analyze" }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["text"],
                "properties": {
                  "text": { "type": "string", "description": "Message text to analyze" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Segment count and character info" },
          "403": { "description": "Missing, invalid, or non-string text parameter" }
        }
      }
    },
    "/offnet/sms": {
      "post": {
        "tags": ["Messaging"],
        "summary": "Off-network SMS test",
        "description": "Sends an off-network outbound SMS test to a purchased number. A test code is sent to the number and the result is posted to the notify_url webhook.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["number", "notify_url"],
                "properties": {
                  "number": { "type": "string", "description": "Purchased DID number to test (digits only)", "example": "12125551234" },
                  "notify_url": { "type": "string", "description": "Webhook URL to receive test result notification (10-255 chars)", "example": "https://example.com/webhook/sms-test" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Test SMS sent successfully" },
          "500": { "description": "Failed — number not found or unable to send" }
        }
      }
    },
    "/offnet/fax": {
      "post": {
        "tags": ["Messaging"],
        "summary": "Off-network fax test",
        "description": "Sends an off-network outbound fax test to a purchased number. A test fax is sent and the result is posted to the notify_url webhook.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["number", "notify_url"],
                "properties": {
                  "number": { "type": "string", "description": "Purchased DID number to test (digits only)", "example": "12125551234" },
                  "notify_url": { "type": "string", "description": "Webhook URL to receive test result notification (10-255 chars)", "example": "https://example.com/webhook/fax-test" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Test fax sent successfully" },
          "500": { "description": "Failed — number not found or unable to send" }
        }
      }
    },

    "/send_fax": {
      "post": {
        "tags": ["Fax"],
        "summary": "Send fax",
        "description": "Queues an outbound fax for a number owned by the authenticated customer. Supports multipart file upload or base64-encoded file via JSON. Accepted formats are PDF, TIFF, JPG, PNG, DOC, DOCX, and TXT, up to 15 MB.",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["from_number", "to_number", "fax_file"],
                "properties": {
                  "from_number": { "type": "string", "description": "Sender fax number" },
                  "to_number": { "type": "string", "description": "Recipient fax number" },
                  "fax_file": { "type": "string", "format": "binary", "description": "Fax document file" },
                  "webhook_url": { "type": "string", "format": "uri", "description": "Optional HTTP(S) webhook URL for queued, completed, or failed delivery notifications" }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["from_number", "to_number", "file_name", "file_b64"],
                "properties": {
                  "from_number": { "type": "string", "description": "Sender fax number" },
                  "to_number": { "type": "string", "description": "Recipient fax number" },
                  "file_name": { "type": "string", "description": "File name with extension (required when using file_b64)" },
                  "file_b64": { "type": "string", "description": "Base64-encoded file content (required with file_name)" },
                  "webhook_url": { "type": "string", "format": "uri", "description": "Optional HTTP(S) webhook URL for queued, completed, or failed delivery notifications" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Fax queued" },
          "400": { "description": "Invalid number, file, or request" },
          "401": { "description": "Authentication required" },
          "402": { "description": "Insufficient balance" },
          "429": { "description": "Fax rate limit reached" }
        }
      }
    },
    "/fax_status": {
      "get": {
        "tags": ["Fax"],
        "summary": "Get fax status",
        "description": "Returns safe delivery metadata for an outbound fax job owned by the authenticated customer.",
        "parameters": [
          {
            "name": "job_id",
            "in": "query",
            "required": true,
            "description": "The job_id returned by send_fax",
            "schema": { "type": "string", "pattern": "^[a-fA-F0-9]{32}$" }
          }
        ],
        "responses": {
          "200": { "description": "Fax status" },
          "400": { "description": "Missing or invalid job_id" },
          "401": { "description": "Authentication required" },
          "404": { "description": "Fax job not found for this customer" }
        }
      }
    },
    "/fax_download": {
      "get": {
        "tags": ["Fax"],
        "summary": "Download fax file",
        "description": "Downloads the file associated with an outbound fax job owned by the authenticated customer.",
        "parameters": [
          {
            "name": "job_id",
            "in": "query",
            "required": true,
            "description": "The job_id returned by send_fax",
            "schema": { "type": "string", "pattern": "^[a-fA-F0-9]{32}$" }
          }
        ],
        "responses": {
          "200": { "description": "Fax file" },
          "400": { "description": "Missing or invalid job_id" },
          "401": { "description": "Authentication required" },
          "404": { "description": "Fax job or file not found for this customer" }
        }
      }
    },
    "/fax_inbox": {
      "get": {
        "tags": ["Fax"],
        "summary": "List received faxes",
        "description": "Lists received inbound faxes with pagination, search, and date-range filtering.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 1 },
            "description": "Page number"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 25, "maximum": 100 },
            "description": "Results per page (max 100)"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Search filter — searches caller and fax numbers"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "example": "2025-01-01" },
            "description": "Filter from date (YYYY-MM-DD)"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "example": "2025-12-31" },
            "description": "Filter to date (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": { "description": "Fax inbox listing" }
        }
      }
    },
    "/fax_outbox": {
      "get": {
        "tags": ["Fax"],
        "summary": "List sent faxes",
        "description": "Lists sent outbound faxes with pagination and search.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 1 },
            "description": "Page number"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "default": 25, "maximum": 100 },
            "description": "Results per page (max 100)"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Search filter — searches from/to numbers and UUID"
          }
        ],
        "responses": {
          "200": { "description": "Fax outbox listing" }
        }
      }
    },
    "/fax_send": {
      "post": {
        "tags": ["Fax"],
        "summary": "Queue outbound fax",
        "description": "Queues an outbound fax by accepting from/to numbers and a file upload. Allowed file types: pdf, tif, tiff, jpg, jpeg, png, doc, docx, txt.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["from_number", "to_number", "file"],
                "properties": {
                  "from_number": { "type": "string", "description": "Sender fax number" },
                  "to_number": { "type": "string", "description": "Recipient fax number" },
                  "file": { "type": "string", "format": "binary", "description": "Fax document file (pdf, tif, tiff, jpg, jpeg, png, doc, docx, txt)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Fax queued" }
        }
      }
    },
    "/fax_file/{type}/{id}": {
      "get": {
        "tags": ["Fax"],
        "summary": "Download fax file",
        "description": "Downloads an inbound or outbound fax file as PDF or TIFF.",
        "parameters": [
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "enum": ["inbound", "outbound"] },
            "description": "Fax direction"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Fax ID (md5 hash for inbound, UUID for outbound)"
          }
        ],
        "responses": {
          "200": { "description": "Fax file download" }
        }
      }
    },
    "/fax_resend/{uuid}": {
      "post": {
        "tags": ["Fax"],
        "summary": "Re-send a fax",
        "description": "Re-queues a previously failed or completed outbound fax for resend.",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Fax job UUID"
          }
        ],
        "responses": {
          "200": { "description": "Fax re-queued" }
        }
      }
    },
    "/fax_numbers": {
      "get": {
        "tags": ["Fax"],
        "summary": "List fax-capable numbers",
        "description": "Lists purchased numbers available for fax sending.",
        "responses": {
          "200": { "description": "List of numbers" }
        }
      }
    },

    "/tn911validate": {
      "post": {
        "tags": ["E911"],
        "summary": "Validate 911 address",
        "description": "Validates a 911 address before provisioning.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["tn", "name", "streetNum", "streetInfo", "city", "state", "postalCode"],
                "properties": {
                  "tn": { "type": "string", "description": "10-digit phone number" },
                  "name": { "type": "string", "description": "Caller/resident name for 911 record" },
                  "streetNum": { "type": "string", "description": "Street number" },
                  "streetInfo": { "type": "string", "description": "Street name and type" },
                  "city": { "type": "string", "description": "City" },
                  "state": { "type": "string", "description": "State abbreviation", "example": "NY" },
                  "postalCode": { "type": "string", "description": "ZIP/postal code" },
                  "location": { "type": "string", "description": "Apartment or suite number (optional)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Address validation result" }
        }
      }
    },
    "/tn911inventory": {
      "get": {
        "tags": ["E911"],
        "summary": "List provisioned 911 records",
        "description": "Lists all actively provisioned E911 records for the authenticated user.",
        "responses": {
          "200": { "description": "911 records" }
        }
      }
    },
    "/tn911remove": {
      "post": {
        "tags": ["E911"],
        "summary": "Remove 911 provisioning",
        "description": "Removes (deprovisions) a 911 record for a phone number.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["tn"],
                "properties": {
                  "tn": { "type": "string", "description": "10 or 11-digit phone number to deprovision" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "911 record removed" }
        }
      }
    },
    "/tn911": {
      "post": {
        "tags": ["E911"],
        "summary": "Provision 911 address",
        "description": "Provisions or updates a 911 address for a phone number.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["tn", "name", "streetNum", "streetInfo", "city", "state", "postalCode"],
                "properties": {
                  "tn": { "type": "string", "description": "10 or 11-digit phone number" },
                  "name": { "type": "string", "description": "Caller/resident name for 911 record" },
                  "streetNum": { "type": "string", "description": "Street number" },
                  "streetInfo": { "type": "string", "description": "Street name and type" },
                  "city": { "type": "string", "description": "City" },
                  "state": { "type": "string", "description": "State abbreviation", "example": "NY" },
                  "postalCode": { "type": "string", "description": "ZIP/postal code" },
                  "location": { "type": "string", "description": "Apartment or suite number (optional)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "911 provisioned" }
        }
      }
    },

    "/brand_nonBlocking": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Register 10DLC brand",
        "description": "Registers a new 10DLC brand via Campaign Registry. Charges $4.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["entityType"],
                "properties": {
                  "entityType": { "type": "string", "description": "Entity type", "enum": ["PRIVATE_PROFIT", "PUBLIC_PROFIT", "NON_PROFIT", "GOVERNMENT", "SOLE_PROPRIETOR"] },
                  "firstName": { "type": "string", "description": "First name (for sole proprietor)" },
                  "lastName": { "type": "string", "description": "Last name (for sole proprietor)" },
                  "displayName": { "type": "string", "description": "Brand display name" },
                  "companyName": { "type": "string", "description": "Legal company name" },
                  "ein": { "type": "string", "description": "Tax ID / EIN" },
                  "einIssuingCountry": { "type": "string", "description": "Country that issued the EIN" },
                  "phone": { "type": "string", "description": "Business phone number" },
                  "street": { "type": "string", "description": "Street address" },
                  "city": { "type": "string", "description": "City" },
                  "state": { "type": "string", "description": "State abbreviation" },
                  "postalCode": { "type": "string", "description": "ZIP/postal code" },
                  "country": { "type": "string", "description": "Country code", "example": "US" },
                  "email": { "type": "string", "description": "Business email address" },
                  "stockSymbol": { "type": "string", "description": "Stock ticker symbol (for public companies)" },
                  "stockExchange": { "type": "string", "description": "Stock exchange (for public companies)" },
                  "website": { "type": "string", "description": "Business website URL" },
                  "vertical": { "type": "string", "description": "Industry vertical" },
                  "brandRelationship": { "type": "string", "description": "Brand relationship type" },
                  "altBusinessId": { "type": "string", "description": "Alternate business identifier" },
                  "altBusinessIdType": { "type": "string", "description": "Type of alternate business identifier" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Brand registered" } }
      }
    },
    "/brand_get/{brandId}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Get brand details",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Brand details" } }
      }
    },
    "/brand_update/{brandId}": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Update brand",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Brand updated" } }
      }
    },
    "/brand_delete/{brandId}": {
      "delete": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Delete brand",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Brand deleted" } }
      }
    },
    "/brand_externalVetting_get/{brandId}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Get vetting status",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Vetting status" } }
      }
    },
    "/brand_externalVetting_insert/{brandId}": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Submit for external vetting",
        "description": "Submits a brand for external vetting. Pricing: POLITICAL=$65, STANDARD=$40, ENHANCED=$95.",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Vetting submitted" } }
      }
    },
    "/brand_externalVetting_update/{brandId}": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Update external vetting",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Vetting updated" } }
      }
    },
    "/campaignBuilder_insert": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Create campaign",
        "description": "Creates a new 10DLC campaign. Charges based on use-case pricing.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["usecase"],
                "properties": {
                  "usecase": { "type": "string", "description": "Campaign use-case (e.g. MARKETING, 2FA, CUSTOMER_CARE)", "example": "MARKETING" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Campaign created" } }
      }
    },
    "/campaignBuilder_get/{brandId}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "List campaigns for brand",
        "parameters": [{ "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Campaign list" } }
      }
    },
    "/campaignBuilder_usecase/{brandId}/{usecase}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Get use-case details",
        "parameters": [
          { "name": "brandId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "usecase", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Use-case details" } }
      }
    },
    "/campaignBuilder_delete/{campaignId}": {
      "delete": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Delete campaign builder",
        "parameters": [{ "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Campaign deleted" } }
      }
    },
    "/campaign_update/{campaignId}": {
      "post": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Update campaign",
        "parameters": [{ "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Campaign updated" } }
      }
    },
    "/campaign_delete/{campaignId}": {
      "delete": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Delete campaign",
        "parameters": [{ "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Campaign deleted" } }
      }
    },
    "/campaign_get/{campaignId}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Get campaign",
        "parameters": [{ "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Campaign details" } }
      }
    },
    "/campaign": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "List campaigns",
        "description": "General campaign listing endpoint.",
        "responses": { "200": { "description": "Campaign list" } }
      }
    },
    "/campaignregistry_enum/{type}": {
      "get": {
        "tags": ["10DLC Brand & Campaign"],
        "summary": "Get CR enum values",
        "description": "Returns Campaign Registry enumeration values (e.g., valid use cases, entity types).",
        "parameters": [{ "name": "type", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Enum type to retrieve" }],
        "responses": { "200": { "description": "Enum values" } }
      }
    },

    "/createsipaccount": {
      "post": {
        "tags": ["SIP"],
        "summary": "Create SIP account",
        "description": "Creates a new SIP account for registering SIP devices or softphones.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "CallerId": { "type": "string", "description": "Caller ID to present on outbound calls" },
                  "RecordCall": { "type": "string", "description": "Enable call recording (yes/no)" },
                  "Alias": { "type": "string", "description": "Friendly alias for this SIP account" },
                  "CountryCode": { "type": "string", "description": "Country calling code" },
                  "CountryID": { "type": "string", "description": "Country ID" },
                  "VideoSupport": { "type": "string", "description": "Enable video support (yes/no)" },
                  "DisAllow": { "type": "string", "description": "Codecs to disallow" },
                  "Allow": { "type": "string", "description": "Codecs to allow" },
                  "Type": { "type": "string", "description": "Peer type" },
                  "Context": { "type": "string", "description": "Dialplan context" },
                  "Call_Limit": { "type": "string", "description": "Maximum simultaneous calls" },
                  "CanReinvite": { "type": "string", "description": "Allow re-INVITE (yes/no/nonat)" },
                  "DtmfMode": { "type": "string", "description": "DTMF mode (rfc2833, inband, info)" },
                  "Host": { "type": "string", "description": "Host/IP for static peers" },
                  "Insecure": { "type": "string", "description": "Insecure mode flags" },
                  "Nat": { "type": "string", "description": "NAT traversal setting" },
                  "Qualify": { "type": "string", "description": "Enable SIP OPTIONS keep-alive (yes/no)" },
                  "RestrictcId": { "type": "string", "description": "Restrict caller ID presentation" },
                  "TranSport": { "type": "string", "description": "SIP transport (udp, tcp, tls)" },
                  "Language": { "type": "string", "description": "Language/locale setting" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "SIP account created" }
        }
      }
    },

    "/get_esim_packages": {
      "get": {
        "tags": ["eSIM"],
        "summary": "List eSIM packages",
        "description": "Lists available eSIM data packages.",
        "responses": { "200": { "description": "Package list" } }
      }
    },
    "/get_sim_regions": {
      "get": {
        "tags": ["eSIM"],
        "summary": "List eSIM regions",
        "description": "Lists available eSIM regional coverage areas.",
        "responses": { "200": { "description": "Region list" } }
      }
    },
    "/create_esim/{package_uuid}": {
      "post": {
        "tags": ["eSIM"],
        "summary": "Purchase eSIM",
        "description": "Purchases and activates a new eSIM for a given package UUID.",
        "parameters": [{ "name": "package_uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "eSIM created" } }
      }
    },
    "/update_esim/{uuid}": {
      "post": {
        "tags": ["eSIM"],
        "summary": "Update eSIM",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "eSIM updated" } }
      }
    },
    "/get_esim/{uuid}": {
      "get": {
        "tags": ["eSIM"],
        "summary": "Get eSIM details",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "eSIM details" } }
      }
    },
    "/get_esim_plans/{uuid}": {
      "get": {
        "tags": ["eSIM"],
        "summary": "List eSIM data plans",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Plan list" } }
      }
    },
    "/get_esim_regions/{uuid}": {
      "get": {
        "tags": ["eSIM"],
        "summary": "Get eSIM coverage regions",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Region list" } }
      }
    },
    "/delete_esim/{uuid}": {
      "delete": {
        "tags": ["eSIM"],
        "summary": "Cancel eSIM",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "eSIM cancelled" } }
      }
    },
    "/create_plan/{uuid}/{package_uuid}": {
      "post": {
        "tags": ["eSIM"],
        "summary": "Add data plan to eSIM",
        "parameters": [
          { "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" }, "description": "eSIM UUID" },
          { "name": "package_uuid", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Package UUID" }
        ],
        "responses": { "200": { "description": "Plan added" } }
      }
    },
    "/delete_plan/{uuid}/{plan_id}": {
      "delete": {
        "tags": ["eSIM"],
        "summary": "Remove data plan",
        "parameters": [
          { "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" }, "description": "eSIM UUID" },
          { "name": "plan_id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Plan ID" }
        ],
        "responses": { "200": { "description": "Plan removed" } }
      }
    },
    "/get_esim_topups/{uuid}": {
      "get": {
        "tags": ["eSIM"],
        "summary": "Get top-up history",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Top-up history" } }
      }
    },

    "/get_proof_types": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "List proof document types",
        "description": "Returns supported identity document types.",
        "responses": { "200": { "description": "Proof types" } }
      }
    },
    "/get_supporting_document_templates/{iso}": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "Get document templates for country",
        "parameters": [{ "name": "iso", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Country ISO code" }],
        "responses": { "200": { "description": "Document templates" } }
      }
    },
    "/create_encrypt_files": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Upload encrypted identity docs",
        "responses": { "200": { "description": "Files uploaded" } }
      }
    },
    "/get_encrypted_files": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "List uploaded documents",
        "responses": { "200": { "description": "File list" } }
      }
    },
    "/delete_encrypted_file/{uuid}": {
      "delete": {
        "tags": ["Regulatory Documents"],
        "summary": "Delete uploaded document",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "File deleted" } }
      }
    },
    "/get_requirements": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "Get regulatory requirements",
        "description": "Returns the full regulatory requirements for purchasing numbers in a given country.",
        "responses": { "200": { "description": "Requirements" } }
      }
    },
    "/registration_status/{number}": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "Get registration status",
        "description": "Returns the carrier registration/verification status for a purchased number.",
        "parameters": [{ "name": "number", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Registration status" } }
      }
    },
    "/number_identity/{number}": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Associate identity with number",
        "description": "Associates an identity/address bundle with a number for regulatory registration.",
        "parameters": [{ "name": "number", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Identity associated" } }
      }
    },
    "/set_carrier_webhook": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Set registration webhook",
        "description": "Sets a webhook URL to receive carrier-side registration/verification status updates.",
        "responses": { "200": { "description": "Webhook set" } }
      }
    },
    "/documents": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "List all documents",
        "responses": { "200": { "description": "Document list" } }
      }
    },
    "/get_document/{uuid}": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "Get document",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Document details" } }
      }
    },
    "/create_document": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Create document",
        "responses": { "200": { "description": "Document created" } }
      }
    },
    "/update_document/{uuid}": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Update document",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Document updated" } }
      }
    },
    "/delete_document/{uuid}": {
      "delete": {
        "tags": ["Regulatory Documents"],
        "summary": "Delete document",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Document deleted" } }
      }
    },
    "/create_supporting_document": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Create supporting document",
        "responses": { "200": { "description": "Supporting document created" } }
      }
    },
    "/supporting_document/{uuid}": {
      "get": {
        "tags": ["Regulatory Documents"],
        "summary": "Get supporting document",
        "parameters": [{ "name": "uuid", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Supporting document" } }
      }
    },
    "/create_proof": {
      "post": {
        "tags": ["Regulatory Documents"],
        "summary": "Create proof document",
        "responses": { "200": { "description": "Proof created" } }
      }
    },

    "/wa_senders": {
      "get": {
        "tags": ["WhatsApp"],
        "summary": "List sender profiles",
        "description": "Lists WhatsApp sender profiles for the user.",
        "responses": { "200": { "description": "Sender list" } }
      }
    },
    "/wa_sender/{id}": {
      "get": {
        "tags": ["WhatsApp"],
        "summary": "Get sender profile",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Sender profile" } }
      }
    },
    "/wa_delete_sender/{id}": {
      "delete": {
        "tags": ["WhatsApp"],
        "summary": "Delete sender",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Sender deleted" } }
      }
    },
    "/wa_templates": {
      "get": {
        "tags": ["WhatsApp"],
        "summary": "List message templates",
        "responses": { "200": { "description": "Template list" } }
      }
    },
    "/wa_template/{id}": {
      "get": {
        "tags": ["WhatsApp"],
        "summary": "Get template",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Template details" } }
      }
    },
    "/wa_template_types": {
      "get": {
        "tags": ["WhatsApp"],
        "summary": "List template types",
        "description": "Returns available WhatsApp template category types.",
        "responses": { "200": { "description": "Template types" } }
      }
    },
    "/wa_delete_template/{id}": {
      "delete": {
        "tags": ["WhatsApp"],
        "summary": "Delete template",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Template deleted" } }
      }
    },
    "/wa_send_message": {
      "post": {
        "tags": ["WhatsApp"],
        "summary": "Send WhatsApp message",
        "responses": { "200": { "description": "Message sent" } }
      }
    },
    "/wa_send_code": {
      "post": {
        "tags": ["WhatsApp"],
        "summary": "Send verification code",
        "description": "Sends a WhatsApp verification code.",
        "responses": { "200": { "description": "Code sent" } }
      }
    },
    "/call-devices": {
      "get": {
        "tags": ["Calls"],
        "summary": "List available answering devices",
        "description": "Returns only active devices owned by the authenticated customer, authorized SIP URI target IPs, and available origination trunks. Each trunk includes its numeric ID, MD5 reference, database name, hostname, and every source IP customers must whitelist.",
        "responses": {
          "200": { "description": "Available answering devices" },
          "401": { "description": "Invalid API credentials" }
        }
      }
    },
    "/calls": {
      "post": {
        "tags": ["Calls"],
        "summary": "Create a click-to-call call",
        "description": "Dedicated API credentials require a current explicit calls:write approval; customer users.username/users.password Basic credentials do not. Rings the selected answering device first and connects the destination second. Every PSTN leg passes through MultiTEL authorization, rating, fraud controls, channel limits, and normal CDR billing. A callback-phone device creates two billable PSTN legs; SIP and Hosted PBX devices create one billable destination leg. SIP-account calls are dispatched only by the account's own registration-SBC pool. SIP-URI calls require an enabled account Authorized IP and a supported origination trunk.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["from", "to", "answering_device"],
                "properties": {
                  "from": { "type": "string", "description": "Active owned number or verified caller ID in E.164 format", "example": "+12125550100" },
                  "to": { "type": "string", "description": "Destination in E.164 format", "example": "+12125550101" },
                  "timeout_seconds": { "type": "integer", "minimum": 10, "maximum": 60, "default": 30 },
                  "answering_device": {
                    "type": "object",
                    "required": ["type"],
                    "properties": {
                      "type": { "type": "string", "enum": ["hpbx_extension", "sip_account", "sip_uri", "phone"] },
                      "id": { "description": "Device ID returned by GET /call-devices", "oneOf": [{ "type": "integer" }, { "type": "string" }] },
                      "billing_code": { "type": "string", "description": "Required only for hpbx_extension; returned by GET /call-devices" },
                      "uri": { "type": "string", "description": "Required for sip_uri. Must use sip:user@public-ip[:port], where the IP is an enabled Authorized IP on the account." },
                      "origination_trunk": {
                        "description": "Required for sip_uri and optional as a consistency check for sip_account. Accepts the trunk's numeric integer ID, MD5-of-ID reference, exact database name, or exact trunk hostname returned by GET /call-devices.",
                        "oneOf": [{ "type": "integer" }, { "type": "string" }]
                      },
                      "origination_trunk_id": {
                        "description": "Backward-compatible alias for origination_trunk.",
                        "oneOf": [{ "type": "integer" }, { "type": "string" }]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": { "description": "Call accepted" },
          "400": { "description": "Invalid number or answering device" },
          "401": { "description": "Invalid API credentials" },
          "402": { "description": "Insufficient balance" },
          "403": { "description": "Caller ID is not owned or verified" },
          "429": { "description": "Call rate limit exceeded" }
        }
      }
    },
    "/calls/{call_id}": {
      "get": {
        "tags": ["Calls"],
        "summary": "Get call status",
        "parameters": [
          { "name": "call_id", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[a-f0-9]{32}$" } }
        ],
        "responses": {
          "200": { "description": "Customer-scoped call status and durations" },
          "401": { "description": "Invalid API credentials" },
          "404": { "description": "Call not found for this customer" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "HTTP Basic Auth using either the customer users.username/users.password pair or dedicated API-account credentials. Legacy subaccount credentials are not accepted by the Calls API."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Enabled api_accounts token credential with a matching IP restriction."
      }
    },
    "schemas": {
      "NumberDetail": {
        "type": "object",
        "properties": {
          "number": { "type": "string", "example": "12125551234" },
          "uuid": { "type": "string" },
          "description": { "type": "string" },
          "isocode": { "type": "string", "example": "US" },
          "config": {
            "type": "object",
            "properties": {
              "uri": { "type": "string", "description": "Primary SIP URI", "example": "user@sip.example.com" },
              "uri2": { "type": "string", "description": "Secondary failover URI" },
              "uri3": { "type": "string", "description": "Tertiary failover URI" },
              "forward_destination": { "type": "string" },
              "sms_uri": { "type": "string" },
              "sms_forward_destination": { "type": "string" }
            }
          },
          "features": {
            "type": "object",
            "properties": {
              "voice": { "type": "string" },
              "sms": { "type": "string" },
              "mms": { "type": "string" }
            }
          },
          "status": {
            "type": "object",
            "properties": {
              "capacity": {
                "type": "object",
                "properties": {
                  "assigned_channels": { "type": "string" },
                  "used_channels": { "type": "string" },
                  "overflow": { "type": "string" },
                  "overage_charge": { "type": "string" }
                }
              },
              "origination": {
                "type": "object",
                "properties": {
                  "origination_trunk_id": { "type": "string" },
                  "origination_trunk_name": { "type": "string" },
                  "origination_country_iso": { "type": "string" },
                  "origination_continent_iso": { "type": "string" },
                  "origination_continent_name": { "type": "string" }
                }
              },
              "service_active": { "type": "string" },
              "force_codec": { "type": "string" },
              "force_dtmf": { "type": "string" }
            }
          },
          "billing": {
            "type": "object",
            "properties": {
              "cnam": { "type": "string" },
              "overflow": { "type": "string" },
              "autorenew": { "type": "string" },
              "persistent": { "type": "string" },
              "date_created": { "type": "string" }
            }
          },
          "price": {
            "type": "object",
            "properties": {
              "setup_price": { "type": "string" },
              "monthly_price": { "type": "string" },
              "per_minute": { "type": "string" },
              "free_minutes": { "type": "string" },
              "remaining_minutes": { "type": "string" }
            }
          }
        }
      }
    }
  }
}
