{
  "openapi": "3.1.0",
  "info": {
    "title": "VoicePro Plus API",
    "version": "3.0.0",
    "summary": "The VoicePro Plus public API for Enterprise accounts.",
    "description": "The VoicePro Plus API v3. Within v3 only additive changes are made; clients must ignore unknown fields and unknown enum values. A breaking change ships only as a new major version, and the previous version keeps working for at least 12 months after it is announced, with a Sunset header on its responses. Uptime target: 99.9% a calendar month, reported on the public status page at https://voicepro.plus/status."
  },
  "servers": [
    {
      "url": "https://api.voicepro.plus/v3"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "SIMs"
    },
    {
      "name": "IoT SIMs"
    },
    {
      "name": "IoT connectors",
      "description": "Deliver your IoT devices' traffic to your own cloud, with TLS added in the network: an HTTPS endpoint, a TLS server or an Azure IoT Hub. Only your own connectors and SIMs."
    },
    {
      "name": "Numbers"
    },
    {
      "name": "Voice trunk"
    },
    {
      "name": "Activity"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Dips"
    },
    {
      "name": "Webhooks",
      "description": "Signed HTTPS callbacks when something changes on your account: create, pause, test and see every delivery."
    }
  ],
  "paths": {
    "/account": {
      "get": {
        "operationId": "getAccount",
        "tags": [
          "Account"
        ],
        "summary": "The workspace this key belongs to, the services on it and the key's own scopes.",
        "x-scope": "read",
        "responses": {
          "200": {
            "description": "The account.",
            "headers": {
              "$ref": "#/components/headers/StandardSet"
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "example": {
                  "object": "account",
                  "id": "acct_AB12CD",
                  "name": "Acme Logistics",
                  "legal_name": "Acme Logistics Ltd",
                  "status": "active",
                  "country": "GB",
                  "timezone": "Europe/London",
                  "currency": "GBP",
                  "parent_account_id": null,
                  "created_at": "2026-10-01T09:00:00Z",
                  "services": {
                    "mobile_sims": {
                      "enabled": true,
                      "count": 12,
                      "active_count": 11
                    },
                    "numbers": {
                      "enabled": true,
                      "count": 3
                    },
                    "voice_trunk": {
                      "enabled": true
                    },
                    "sms_route": {
                      "enabled": false
                    },
                    "iot": {
                      "enabled": true
                    }
                  },
                  "spending_limit": {
                    "limit": {
                      "amount": 250000,
                      "currency": "GBP"
                    },
                    "alert_percentages": [
                      80,
                      100
                    ]
                  },
                  "sso": {
                    "domain": "example.com",
                    "providers": [
                      "microsoft"
                    ],
                    "required": false
                  },
                  "open_invoice_count": 1,
                  "authenticated_as": {
                    "type": "api_key",
                    "key_id": "key_1A2B3C4D",
                    "mode": "live",
                    "scopes": [
                      "read",
                      "billing:read"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sub_accounts": {
      "get": {
        "operationId": "listSubAccounts",
        "tags": [
          "Account"
        ],
        "summary": "Sub-accounts, each with its counts of SIMs, numbers and active members, and whether it has a voice trunk.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SubAccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "sub_account",
                      "id": "acct_EF34GH",
                      "name": "Acme Logistics North",
                      "status": "active",
                      "sim_count": 4,
                      "number_count": 1,
                      "voice_trunk": false,
                      "member_count": 5
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/incidents": {
      "get": {
        "operationId": "listIncidents",
        "tags": [
          "Account"
        ],
        "summary": "Open incidents and planned maintenance (next 3 days) affecting this account's services.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Incident"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "incident",
                      "id": "inc_20261021a",
                      "title": "Delayed usage figures",
                      "kind": "incident",
                      "impact": "minor",
                      "components": [
                        "usage"
                      ],
                      "started_at": "2026-10-21T07:40:00Z",
                      "resolved_at": "2026-10-21T08:25:00Z",
                      "status_page_url": "https://status.voicepro.plus"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sims": {
      "get": {
        "operationId": "listSims",
        "tags": [
          "SIMs"
        ],
        "summary": "Mobile SIMs with this month's usage.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "suspended"
              ]
            }
          },
          {
            "name": "holder",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Holder name contains."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Sim"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "sim",
                      "id": "sim_K7M2Q9",
                      "label": "Warehouse van 3",
                      "plan_name": "Business+ Essentials",
                      "add_ons": [
                        "EU Roaming"
                      ],
                      "iccid": "8944500102345678901",
                      "phone_number": "+447700900123",
                      "country": "GB",
                      "status": "active",
                      "holder_name": "Sam Taylor",
                      "data_cap_gb": 30,
                      "created_at": "2026-10-02T09:14:00Z",
                      "activated_at": "2026-10-02T11:40:00Z",
                      "month_to_date": {
                        "data_bytes": 4831838208,
                        "roaming_bytes": 214748364,
                        "calls": 42,
                        "sms": 17,
                        "countries": [
                          "GB",
                          "FR"
                        ]
                      },
                      "data_as_of": "2026-10-28T08:55:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createSim",
        "tags": [
          "SIMs"
        ],
        "summary": "Add a business mobile SIM line.",
        "description": "Needs an Idempotency-Key. Adds a line exactly as Add a SIM line in the portal: it counts towards your monthly plan total on your normal invoice from today (no prepaid balance is used). We send the SIM and attach it to the line; iccid and phone_number are null until then. 409 account_not_active until the account is active. A locked account gets 423 account_locked.",
        "x-scope": "sims:write",
        "x-charged": false,
        "x-events": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimCreate"
              },
              "example": {
                "label": "Field ops, Berlin lead",
                "plan": "elite",
                "add_ons": [
                  "travel_data"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new SIM line.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sim"
                },
                "example": {
                  "object": "sim",
                  "id": "sim_N4P8R2",
                  "label": "Field ops, Berlin lead",
                  "plan_name": "Business+ Elite",
                  "add_ons": [
                    "Travel data add-on"
                  ],
                  "iccid": null,
                  "phone_number": null,
                  "country": "GB",
                  "status": "active",
                  "holder_name": null,
                  "data_cap_gb": null,
                  "created_at": "2026-10-29T11:00:00Z",
                  "activated_at": "2026-10-29T11:00:00Z",
                  "month_to_date": {
                    "data_bytes": 0,
                    "roaming_bytes": 0,
                    "calls": 0,
                    "sms": 0,
                    "countries": []
                  },
                  "data_as_of": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sims/{id}": {
      "get": {
        "operationId": "getSim",
        "tags": [
          "SIMs"
        ],
        "summary": "One mobile SIM.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sim"
                },
                "example": {
                  "object": "sim",
                  "id": "sim_K7M2Q9",
                  "label": "Warehouse van 3",
                  "plan_name": "Business+ Essentials",
                  "add_ons": [
                    "EU Roaming"
                  ],
                  "iccid": "8944500102345678901",
                  "phone_number": "+447700900123",
                  "country": "GB",
                  "status": "active",
                  "holder_name": "Sam Taylor",
                  "data_cap_gb": 30,
                  "created_at": "2026-10-02T09:14:00Z",
                  "activated_at": "2026-10-02T11:40:00Z",
                  "month_to_date": {
                    "data_bytes": 4831838208,
                    "roaming_bytes": 214748364,
                    "calls": 42,
                    "sms": 17,
                    "countries": [
                      "GB",
                      "FR"
                    ]
                  },
                  "data_as_of": "2026-10-28T08:55:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sims/{id}/usage": {
      "get": {
        "operationId": "getSimUsage",
        "tags": [
          "SIMs"
        ],
        "summary": "Usage for a time range (at most 400 days).",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Step"
          },
          {
            "$ref": "#/components/parameters/CompareFrom"
          },
          {
            "$ref": "#/components/parameters/CompareTo"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimUsage"
                },
                "example": {
                  "object": "sim_usage",
                  "sim_id": "sim_K7M2Q9",
                  "range": {
                    "from": "2026-10-01T00:00:00Z",
                    "to": "2026-10-28T00:00:00Z",
                    "step": "1d",
                    "timezone": "Europe/London"
                  },
                  "totals": {
                    "data_bytes": 4831838208,
                    "roaming_bytes": 214748364,
                    "calls": 42,
                    "call_seconds": 5210,
                    "sms": 17
                  },
                  "previous": {
                    "data_bytes": 3951369912,
                    "roaming_bytes": 0,
                    "calls": 38,
                    "call_seconds": 4480,
                    "sms": 21
                  },
                  "series": [
                    {
                      "t": "2026-10-26T00:00:00Z",
                      "data_bytes": 187695104,
                      "calls": 3,
                      "sms": 1
                    },
                    {
                      "t": "2026-10-27T00:00:00Z",
                      "data_bytes": 201326592,
                      "calls": 2,
                      "sms": 0
                    }
                  ],
                  "by_country": [
                    {
                      "country": "GB",
                      "data_bytes": 4617089843
                    },
                    {
                      "country": "FR",
                      "data_bytes": 214748365
                    }
                  ],
                  "data_as_of": "2026-10-28T08:55:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims": {
      "get": {
        "operationId": "listIotSims",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "IoT SIMs. 404 service_not_enabled without IoT.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotSim"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_sim",
                      "id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                      "iccid": "8944501234567890123",
                      "label": "Trailer tracker 12",
                      "activated": true,
                      "online": true,
                      "network": {
                        "name": "Network GB",
                        "country": "GB",
                        "mcc": "234",
                        "mnc": "10"
                      },
                      "network_type": "4G",
                      "last_seen_at": "2026-10-28T08:52:11Z",
                      "imei_lock": null,
                      "data_limit": {
                        "total_bytes": 524288000,
                        "period": "monthly",
                        "alert_bytes": 419430400
                      },
                      "month_bytes": 73400320,
                      "data_as_of": "2026-10-28T08:55:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}": {
      "get": {
        "operationId": "getIotSim",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "One IoT SIM with this month's data.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotSim"
                },
                "example": {
                  "object": "iot_sim",
                  "id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "iccid": "8944501234567890123",
                  "label": "Trailer tracker 12",
                  "activated": true,
                  "online": true,
                  "network": {
                    "name": "Network GB",
                    "country": "GB",
                    "mcc": "234",
                    "mnc": "10"
                  },
                  "network_type": "4G",
                  "last_seen_at": "2026-10-28T08:52:11Z",
                  "imei_lock": null,
                  "data_limit": {
                    "total_bytes": 524288000,
                    "period": "monthly",
                    "alert_bytes": 419430400
                  },
                  "month_bytes": 73400320,
                  "data_as_of": "2026-10-28T08:55:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateIotSim",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "Change one SIM: its name, on or off, IMEI lock, data limit or radio technologies. Checked in full before anything is sent; the answer is the SIM afterwards.",
        "x-scope": "sims:write",
        "description": "Needs the sims:write scope and an Idempotency-Key. A locked account gets 423 account_locked. Turning a SIM off or on also sends the sim.suspended webhook.",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotSimUpdate"
              },
              "example": {
                "label": "Trailer tracker 12 (depot)"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotSim"
                },
                "example": {
                  "object": "iot_sim",
                  "id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "iccid": "8944501234567890123",
                  "label": "Trailer tracker 12 (depot)",
                  "activated": true,
                  "online": true,
                  "network": {
                    "name": "Network GB",
                    "country": "GB",
                    "mcc": "234",
                    "mnc": "10"
                  },
                  "network_type": "4G",
                  "last_seen_at": "2026-10-28T08:52:11Z",
                  "imei_lock": null,
                  "data_limit": {
                    "total_bytes": 524288000,
                    "period": "monthly",
                    "alert_bytes": 419430400
                  },
                  "data_as_of": "2026-10-28T09:01:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}/events": {
      "get": {
        "operationId": "listIotSimEvents",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "The network log of one IoT SIM over a time range, newest first: authentication results (allowed or refused, with the network's reason), attaches, data sessions starting, detaches with the session's bytes, and location updates. Default range: the last 7 days; at most 31 days. truncated is true when the range held more than 5,000 network rows (narrow the range). Reads are limited to 10 a minute per account.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of the range. Default: 7 days before to."
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of the range. Default: now. At most 31 days after from."
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Comma-separated event types to include: authentication, attach, data_session_start, detach, location. Default: all.",
              "examples": [
                "authentication,detach"
              ]
            }
          },
          {
            "name": "refused",
            "in": "query",
            "schema": {
              "type": "boolean",
              "description": "true: only authentication attempts the network refused."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotEvent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_event",
                      "time": "2026-10-28T08:52:11Z",
                      "type": "data_session_start",
                      "outcome": "allowed",
                      "reason": null,
                      "message": null,
                      "network": {
                        "name": "Network GB",
                        "country": "GB",
                        "mcc": "234",
                        "mnc": "10"
                      },
                      "network_type": "4G",
                      "imei": "356938035643809",
                      "ip": "198.51.100.24",
                      "session_id": "sess_9f2k7m",
                      "upload_bytes": null,
                      "download_bytes": null,
                      "bytes": null,
                      "location": {
                        "cell_id": 52011,
                        "area_code": 1203,
                        "accuracy_m": 350,
                        "lat": 51.5072,
                        "lng": -0.1276
                      }
                    }
                  ],
                  "has_more": true,
                  "next_cursor": "eyJrIjoiMjAyNi0xMC0yOFQwODo1MjoxMVoifQ"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}/connector": {
      "patch": {
        "operationId": "setIotSimConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "Send one IoT SIM's traffic through one of your connectors, or through none (connector null).",
        "x-scope": "iot:write",
        "description": "Only your own SIMs and your own connectors. Needs the iot:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotSimConnectorUpdate"
              },
              "example": {
                "connector": "acme-ingest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotSimConnector"
                },
                "example": {
                  "object": "iot_sim_connector",
                  "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "connector": "acme-ingest"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/connectors": {
      "get": {
        "operationId": "listIotConnectors",
        "tags": [
          "IoT connectors"
        ],
        "summary": "The account's IoT cloud connectors, and the connector types on offer (types).",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotConnector"
                          }
                        },
                        "types": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotConnectorType"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_connector",
                      "name": "acme-ingest",
                      "type": "https",
                      "settings": {
                        "url": "https://ingest.example.com/iot"
                      },
                      "secrets": {},
                      "passthrough": [
                        {
                          "protocol": "tcp",
                          "ip": "203.0.113.10",
                          "port": 8883
                        }
                      ],
                      "sim_count": 12
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "types": [
                    "https",
                    "tls",
                    "azure_iot_hub",
                    "aws_iot_core"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createIotConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "Create a cloud connector: device traffic delivered to your HTTPS endpoint, TLS server or Azure IoT Hub, with TLS added in the network.",
        "x-scope": "iot:write",
        "description": "Secrets (private key, certificates, connection string) are sent to the IoT network only: never stored by us and never returned; each shows set or not set. Needs the iot:write scope and an Idempotency-Key. A locked account gets 423 account_locked. A name already in use is 409 state_conflict.",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotConnectorCreate"
              },
              "example": {
                "name": "acme-ingest",
                "type": "https",
                "settings": {
                  "url": "https://ingest.example.com/iot"
                },
                "passthrough": [
                  {
                    "protocol": "tcp",
                    "ip": "203.0.113.10",
                    "port": 8883
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotConnector"
                },
                "example": {
                  "object": "iot_connector",
                  "name": "acme-ingest",
                  "type": "https",
                  "settings": {
                    "url": "https://ingest.example.com/iot"
                  },
                  "secrets": {},
                  "passthrough": [
                    {
                      "protocol": "tcp",
                      "ip": "203.0.113.10",
                      "port": 8883
                    }
                  ],
                  "sim_count": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/connectors/{name}": {
      "get": {
        "operationId": "getIotConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "One cloud connector.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The connector's name, as you gave it.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{3,60}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotConnector"
                },
                "example": {
                  "object": "iot_connector",
                  "name": "acme-ingest",
                  "type": "https",
                  "settings": {
                    "url": "https://ingest.example.com/iot"
                  },
                  "secrets": {},
                  "passthrough": [
                    {
                      "protocol": "tcp",
                      "ip": "203.0.113.10",
                      "port": 8883
                    }
                  ],
                  "sim_count": 12
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateIotConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "Change a connector's settings, replace a secret or set its passthrough rules. A secret left out is kept. The type and name cannot change.",
        "x-scope": "iot:write",
        "description": "Needs the iot:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The connector's name, as you gave it.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{3,60}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotConnectorUpdate"
              },
              "example": {
                "settings": {
                  "url": "https://ingest2.example.com/iot"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotConnector"
                },
                "example": {
                  "object": "iot_connector",
                  "name": "acme-ingest",
                  "type": "https",
                  "settings": {
                    "url": "https://ingest2.example.com/iot"
                  },
                  "secrets": {},
                  "passthrough": [
                    {
                      "protocol": "tcp",
                      "ip": "203.0.113.10",
                      "port": 8883
                    }
                  ],
                  "sim_count": 12
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "operationId": "deleteIotConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "Delete a connector. Refused (409 state_conflict) while any SIM still uses it.",
        "x-scope": "iot:write",
        "description": "Needs the iot:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The connector's name, as you gave it.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{3,60}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotConnectorDeleted"
                },
                "example": {
                  "object": "iot_connector",
                  "name": "acme-ingest",
                  "deleted": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/connectors/{name}/test": {
      "post": {
        "operationId": "testIotConnector",
        "tags": [
          "IoT connectors"
        ],
        "summary": "Test a connector: an HTTPS connector gets a labelled test POST from our platform; every type shows its recent delivery errors from the network.",
        "x-scope": "iot:write",
        "description": "Needs the iot:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The connector's name, as you gave it.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{3,60}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotConnectorTest"
                },
                "example": {
                  "object": "iot_connector_test",
                  "name": "acme-ingest",
                  "delivered": true,
                  "status": 200,
                  "detail": "Test message delivered.",
                  "recent_errors": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/numbers": {
      "get": {
        "operationId": "listNumbers",
        "tags": [
          "Numbers"
        ],
        "summary": "Phone numbers and their routing.",
        "x-scope": "numbers:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Number"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "number",
                      "id": "num_q4zr7mxkp2wd6hnc3tbvfy5a",
                      "phone_number": "+442079460123",
                      "holder_name": "Acme Logistics Ltd",
                      "status": "active",
                      "provisioned_at": "2026-10-05T10:00:00Z",
                      "routing": {
                        "mode": "forward",
                        "forward_to": "+447700900456"
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/numbers/{id}": {
      "get": {
        "operationId": "getNumber",
        "tags": [
          "Numbers"
        ],
        "summary": "One number.",
        "x-scope": "numbers:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Number"
                },
                "example": {
                  "object": "number",
                  "id": "num_q4zr7mxkp2wd6hnc3tbvfy5a",
                  "phone_number": "+442079460123",
                  "holder_name": "Acme Logistics Ltd",
                  "status": "active",
                  "provisioned_at": "2026-10-05T10:00:00Z",
                  "routing": {
                    "mode": "forward",
                    "forward_to": "+447700900456"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateNumberRouting",
        "tags": [
          "Numbers"
        ],
        "summary": "Change a number's routing: ring the app, or forward to another number.",
        "description": "Needs an Idempotency-Key: a retry with the same key and body replays the first answer; the same key with another body is 409 idempotency_key_reused. A forward is saved and answered with state pending until it is in effect; it is never reported live before then. Premium-rate numbers are never listed and never a forward target. A locked account gets 423 account_locked.",
        "x-scope": "numbers:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NumberRoutingUpdate"
              },
              "example": {
                "routing": {
                  "mode": "forward",
                  "forward_to": "+447700900456"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberRouting"
                },
                "example": {
                  "object": "number_routing",
                  "number_id": "num_q4zr7mxkp2wd6hnc3tbvfy5a",
                  "mode": "forward",
                  "forward_to": "+447700900456",
                  "state": "active",
                  "note": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/numbers/{id}/usage": {
      "get": {
        "operationId": "getNumberUsage",
        "tags": [
          "Numbers"
        ],
        "summary": "Calls and SMS for a time range.",
        "x-scope": "numbers:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Step"
          },
          {
            "$ref": "#/components/parameters/CompareFrom"
          },
          {
            "$ref": "#/components/parameters/CompareTo"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberUsage"
                },
                "example": {
                  "object": "number_usage",
                  "number_id": "num_q4zr7mxkp2wd6hnc3tbvfy5a",
                  "range": {
                    "from": "2026-10-01T00:00:00Z",
                    "to": "2026-10-28T00:00:00Z",
                    "step": "1d",
                    "timezone": "Europe/London"
                  },
                  "totals": {
                    "inbound_calls": 96,
                    "outbound_calls": 41,
                    "answered_calls": 118,
                    "minutes": 402.5,
                    "sms": 0
                  },
                  "previous": {
                    "inbound_calls": 88,
                    "outbound_calls": 37,
                    "answered_calls": 109,
                    "minutes": 371,
                    "sms": 0
                  },
                  "series": [
                    {
                      "t": "2026-10-26T00:00:00Z",
                      "calls": 6,
                      "sms": 0
                    },
                    {
                      "t": "2026-10-27T00:00:00Z",
                      "calls": 9,
                      "sms": 0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/number_offers": {
      "get": {
        "operationId": "listNumberOffers",
        "tags": [
          "Numbers"
        ],
        "summary": "Numbers you can order in a country, with their prepaid price in the currency you choose.",
        "description": "Prices are clean figures in the currency asked for (currency, else your account's own), converted at today's rate: first_payment (first month plus any one-off setup fee) is taken from your prepaid balance in that currency when you order. Premium rate and shared cost numbers are never offered.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "description": "ISO 3166 alpha-2, for example GB."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "mobile",
                "landline",
                "tollfree",
                "national"
              ]
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{3}$"
            },
            "description": "Show prices in this currency (one we charge in); default your account's own currency."
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/NumberOffer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "number_offer",
                      "id": "nof_m3xk7q2zrw4pdn6hc5tbvfya",
                      "country": "GB",
                      "prefix": "4420",
                      "area_name": "London",
                      "category": "landline",
                      "channels_included": 2,
                      "monthly_price": {
                        "amount": 150,
                        "currency": "USD"
                      },
                      "setup_price": {
                        "amount": 0,
                        "currency": "USD"
                      },
                      "first_payment": {
                        "amount": 150,
                        "currency": "USD"
                      },
                      "data_as_of": "2026-10-28T06:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/number_orders": {
      "post": {
        "operationId": "createNumberOrder",
        "tags": [
          "Numbers"
        ],
        "summary": "Order a number. Prepaid from your account balance.",
        "description": "The first payment is taken from your account balance before the number is ordered. A balance that does not cover it is 402 insufficient_balance and nothing is ordered. If the order cannot be placed, the payment is returned to your balance exactly once and the answer is 503. One Idempotency-Key never charges or orders twice. No refund when a number is later released or cancelled.",
        "x-scope": "orders:write",
        "x-charged": true,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "offer_id"
                ],
                "properties": {
                  "offer_id": {
                    "type": "string",
                    "pattern": "^nof_[a-z2-7]{24}$"
                  },
                  "currency": {
                    "type": "string",
                    "pattern": "^[A-Za-z]{3}$",
                    "description": "The currency the first payment is paid in, from your prepaid balance in that currency; left out, your account's own currency. Each price is the catalogue figure converted at today's rate and rounded up to a clean price (.49 or .99, or 50 whole units for JPY and KRW)."
                  }
                }
              },
              "example": {
                "offer_id": "nof_m3xk7q2zrw4pdn6hc5tbvfya"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ordered and paid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberOrder"
                },
                "example": {
                  "object": "number_order",
                  "id": "nord_p6wz2kq7mx4rd3nh5cbtvfya",
                  "status": "completed",
                  "offer_id": "nof_m3xk7q2zrw4pdn6hc5tbvfya",
                  "phone_number": "+442079460188",
                  "number_id": "num_r5kx2wq7mz4pd3nh6cbtvfya",
                  "charged": {
                    "amount": 150,
                    "currency": "USD"
                  },
                  "balance_after": {
                    "amount": 4850,
                    "currency": "USD"
                  },
                  "created_at": "2026-10-28T09:30:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/port_requests": {
      "get": {
        "operationId": "listPortRequests",
        "tags": [
          "Numbers"
        ],
        "summary": "Requests to transfer numbers in.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PortRequest"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "port_request",
                      "id": "port_4F9K2A",
                      "numbers": [
                        "+442079460188"
                      ],
                      "current_provider": "Previous provider plc",
                      "account_reference": "ACC-558120",
                      "authorised_name": "Jordan Lee",
                      "status": "accepted",
                      "transfer_date": "2026-10-30",
                      "action_needed": null,
                      "history": [
                        {
                          "at": "2026-10-20T09:00:00Z",
                          "status": "submitted",
                          "note": null
                        },
                        {
                          "at": "2026-10-23T14:12:00Z",
                          "status": "accepted",
                          "note": "Transfer date confirmed."
                        }
                      ],
                      "created_at": "2026-10-20T09:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createPortRequest",
        "tags": [
          "Numbers"
        ],
        "summary": "Ask to transfer numbers to VoicePro from another provider.",
        "description": "Our provisioning team takes it from here; follow it with GET /port_requests/{id} or the porting.updated webhook. Up to 20 requests a day per account. Needs an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-scope": "porting:write",
        "x-charged": false,
        "x-events": [
          "porting.updated"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortRequestCreate"
              },
              "example": {
                "numbers": [
                  "+442079460188"
                ],
                "current_provider": "Previous provider plc",
                "account_reference": "ACC-558120",
                "authorised_name": "Jordan Lee"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortRequest"
                },
                "example": {
                  "object": "port_request",
                  "id": "port_4F9K2A",
                  "numbers": [
                    "+442079460188"
                  ],
                  "current_provider": "Previous provider plc",
                  "account_reference": "ACC-558120",
                  "authorised_name": "Jordan Lee",
                  "status": "submitted",
                  "transfer_date": null,
                  "action_needed": null,
                  "history": [
                    {
                      "at": "2026-10-20T09:00:00Z",
                      "status": "submitted",
                      "note": null
                    }
                  ],
                  "created_at": "2026-10-20T09:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/port_requests/{id}": {
      "get": {
        "operationId": "getPortRequest",
        "tags": [
          "Numbers"
        ],
        "summary": "One transfer request with its history.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortRequest"
                },
                "example": {
                  "object": "port_request",
                  "id": "port_4F9K2A",
                  "numbers": [
                    "+442079460188"
                  ],
                  "current_provider": "Previous provider plc",
                  "account_reference": "ACC-558120",
                  "authorised_name": "Jordan Lee",
                  "status": "accepted",
                  "transfer_date": "2026-10-30",
                  "action_needed": null,
                  "history": [
                    {
                      "at": "2026-10-20T09:00:00Z",
                      "status": "submitted",
                      "note": null
                    },
                    {
                      "at": "2026-10-23T14:12:00Z",
                      "status": "accepted",
                      "note": "Transfer date confirmed."
                    }
                  ],
                  "created_at": "2026-10-20T09:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/trunks": {
      "get": {
        "operationId": "listTrunks",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Trunk settings. 404 service_not_enabled without a voice trunk.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Trunk"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "trunk",
                      "name": "acme-main",
                      "active": true,
                      "call_limit": 30,
                      "cps_limit": 5,
                      "max_call_seconds": 7200,
                      "allowed_ips": [
                        "203.0.113.20"
                      ],
                      "data_as_of": "2026-10-28T08:55:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/rates": {
      "get": {
        "operationId": "listRates",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Current and scheduled rates.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "destination",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Destination name contains."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Rate"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "rate",
                      "destination": "France - Fixed",
                      "rate": {
                        "amount": "0.0060",
                        "currency": "USD"
                      },
                      "billing_increment": "60/60",
                      "effective_from": "2026-10-01T00:00:00Z",
                      "effective_until": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/calls": {
      "get": {
        "operationId": "listCalls",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Call records, newest first, for a range of at most 92 days (default: the last 24 hours).",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "name": "number",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Digits matched in from or to."
            }
          },
          {
            "name": "result",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "ok",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Call"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "call",
                      "id": "call_mfrgg5dbgaztemrqgu",
                      "started_at": "2026-10-27T14:03:22Z",
                      "from": "+442079460123",
                      "to": "+33155550123",
                      "country": "FR",
                      "seconds": 184,
                      "result": "answered",
                      "charge": {
                        "amount": "0.0184",
                        "currency": "USD"
                      },
                      "data_as_of": "2026-10-28T08:55:00Z",
                      "sip_call_id": "a1b2c3d4e5@203.0.113.20"
                    }
                  ],
                  "has_more": true,
                  "next_cursor": "eyJrIjoiMjAyNi0xMC0yN1QxNDowMzoyMloifQ"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/calls/{id}": {
      "get": {
        "operationId": "getCall",
        "tags": [
          "Voice trunk"
        ],
        "summary": "One call record by id, within the last 92 days.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Call"
                },
                "example": {
                  "object": "call",
                  "id": "call_mfrgg5dbgaztemrqgu",
                  "started_at": "2026-10-27T14:03:22Z",
                  "from": "+442079460123",
                  "to": "+33155550123",
                  "country": "FR",
                  "seconds": 184,
                  "result": "answered",
                  "charge": {
                    "amount": "0.0184",
                    "currency": "USD"
                  },
                  "data_as_of": "2026-10-28T08:55:00Z",
                  "sip_call_id": "a1b2c3d4e5@203.0.113.20"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/traffic": {
      "get": {
        "operationId": "getTraffic",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Totals and series for a time range.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Step"
          },
          {
            "$ref": "#/components/parameters/CompareFrom"
          },
          {
            "$ref": "#/components/parameters/CompareTo"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Traffic"
                },
                "example": {
                  "object": "traffic",
                  "range": {
                    "from": "2026-10-01T00:00:00Z",
                    "to": "2026-10-28T00:00:00Z",
                    "step": "1d",
                    "timezone": "Europe/London"
                  },
                  "totals": {
                    "calls": 1240,
                    "answered": 868,
                    "asr": 0.7,
                    "acd_seconds": 142.5,
                    "minutes": 2061.5,
                    "spend": {
                      "amount": "103.08",
                      "currency": "USD"
                    },
                    "pdd_seconds": 2.1,
                    "sdr": 0.012
                  },
                  "previous": {
                    "calls": 1105,
                    "answered": 762,
                    "asr": 0.69,
                    "acd_seconds": 142.5,
                    "minutes": 1810,
                    "spend": {
                      "amount": "90.50",
                      "currency": "USD"
                    },
                    "pdd_seconds": 2.1,
                    "sdr": 0.012
                  },
                  "series": [
                    {
                      "t": "2026-10-27T00:00:00Z",
                      "calls": 52,
                      "answered": 37,
                      "minutes": 88.5,
                      "spend": {
                        "amount": "4.43",
                        "currency": "USD"
                      }
                    }
                  ],
                  "data_as_of": "2026-10-28T08:55:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/traffic/destinations": {
      "get": {
        "operationId": "listTrafficDestinations",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Traffic by destination country for a time range.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/TrafficDestination"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "traffic_destination",
                      "country": "FR",
                      "calls": 410,
                      "answered": 295,
                      "asr": 0.72,
                      "minutes": 701.2,
                      "spend": {
                        "amount": "35.06",
                        "currency": "USD"
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/activity": {
      "get": {
        "operationId": "listActivity",
        "tags": [
          "Activity"
        ],
        "summary": "Calls, SMS and data across SIMs, numbers and the voice trunk, newest first. Each source gives at most 5000 records per window; has_more then pages into older records. Voice trunk records cover at most the last 92 days.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "call",
                "sms",
                "data"
              ]
            }
          },
          {
            "name": "via",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "sim",
                "number",
                "trunk"
              ]
            }
          },
          {
            "name": "number",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Digits matched in from or to."
            }
          },
          {
            "name": "result",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "ok",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Activity"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "activity",
                      "id": "act_5mq2k7xw",
                      "at": "2026-10-27T14:03:22Z",
                      "kind": "call",
                      "direction": "out",
                      "via": {
                        "type": "sim",
                        "id": "sim_K7M2Q9",
                        "label": "Warehouse van 3"
                      },
                      "from": "+447700900123",
                      "to": "+442079460555",
                      "country": "GB",
                      "roaming_country": null,
                      "seconds": 95,
                      "bytes": null,
                      "result": "answered",
                      "ok": true,
                      "charge": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/invoices": {
      "get": {
        "operationId": "listInvoices",
        "tags": [
          "Billing"
        ],
        "summary": "VoicePro invoices, newest first.",
        "x-scope": "billing:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "paid",
                "overdue",
                "void"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Invoice"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "invoice",
                      "id": "inv_2610AB12",
                      "period": "2026-09",
                      "status": "paid",
                      "subtotal": {
                        "amount": 42000,
                        "currency": "GBP"
                      },
                      "vat": {
                        "amount": 8400,
                        "currency": "GBP"
                      },
                      "total": {
                        "amount": 50400,
                        "currency": "GBP"
                      },
                      "issued_at": "2026-10-01T06:00:00Z",
                      "due_at": "2026-10-15T23:59:59Z",
                      "paid_at": "2026-10-08T10:21:00Z",
                      "line_count": 2
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/invoices/{id}": {
      "get": {
        "operationId": "getInvoice",
        "tags": [
          "Billing"
        ],
        "summary": "One invoice with its lines.",
        "x-scope": "billing:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDetail"
                },
                "example": {
                  "object": "invoice",
                  "id": "inv_2610AB12",
                  "period": "2026-09",
                  "status": "paid",
                  "subtotal": {
                    "amount": 42000,
                    "currency": "GBP"
                  },
                  "vat": {
                    "amount": 8400,
                    "currency": "GBP"
                  },
                  "total": {
                    "amount": 50400,
                    "currency": "GBP"
                  },
                  "issued_at": "2026-10-01T06:00:00Z",
                  "due_at": "2026-10-15T23:59:59Z",
                  "paid_at": "2026-10-08T10:21:00Z",
                  "line_count": 2,
                  "lines": [
                    {
                      "description": "Business+ Essentials, 12 SIMs",
                      "quantity": 12,
                      "unit_price": {
                        "amount": 3000,
                        "currency": "GBP"
                      },
                      "total": {
                        "amount": 36000,
                        "currency": "GBP"
                      },
                      "kind": "plan"
                    },
                    {
                      "description": "EU Roaming add-on",
                      "quantity": 12,
                      "unit_price": {
                        "amount": 500,
                        "currency": "GBP"
                      },
                      "total": {
                        "amount": 6000,
                        "currency": "GBP"
                      },
                      "kind": "add_on"
                    }
                  ],
                  "notes": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/invoices/{id}/pdf": {
      "get": {
        "operationId": "getInvoicePdf",
        "tags": [
          "Billing"
        ],
        "summary": "The invoice as a VAT invoice PDF.",
        "x-scope": "billing:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        },
        "description": "Available for standard-rated UK invoices: every line charged UK VAT at 20%, on a UK account. Any other invoice answers 409 state_conflict; email help@voicepro.plus for a copy."
      }
    },
    "/wholesale/invoices": {
      "get": {
        "operationId": "listWholesaleInvoices",
        "tags": [
          "Billing"
        ],
        "summary": "Wholesale voice invoices.",
        "x-scope": "billing:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WholesaleInvoice"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "wholesale_invoice",
                      "number": "W-2026-0931",
                      "period_start": "2026-09-01",
                      "period_end": "2026-09-30",
                      "issued_at": "2026-10-01T06:00:00Z",
                      "due_at": "2026-10-15T23:59:59Z",
                      "total": {
                        "amount": 9050,
                        "currency": "USD"
                      },
                      "status": "paid"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/wholesale/payments": {
      "get": {
        "operationId": "listWholesalePayments",
        "tags": [
          "Billing"
        ],
        "summary": "Payments received for wholesale voice.",
        "x-scope": "billing:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WholesalePayment"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "wholesale_payment",
                      "date": "2026-10-08",
                      "amount": {
                        "amount": 9050,
                        "currency": "USD"
                      },
                      "reference": "ACME-OCT-01"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "getBalance",
        "tags": [
          "Billing"
        ],
        "summary": "Wholesale balance and prepaid dip balance.",
        "x-scope": "billing:read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                },
                "example": {
                  "object": "balance",
                  "wholesale": [
                    {
                      "amount": 4850,
                      "currency": "USD"
                    }
                  ],
                  "prepaid": [
                    {
                      "amount": 2500,
                      "currency": "GBP"
                    },
                    {
                      "amount": 12000,
                      "currency": "USD"
                    }
                  ],
                  "default_currency": "GBP",
                  "data_as_of": "2026-10-28T09:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/spend": {
      "get": {
        "operationId": "getSpend",
        "tags": [
          "Billing"
        ],
        "summary": "This month's spend by service, the projection and the spending limit.",
        "x-scope": "billing:read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Spend"
                },
                "example": {
                  "object": "spend",
                  "period": "2026-10",
                  "days_elapsed": 27.4,
                  "days_in_month": 31,
                  "lines": [
                    {
                      "service": "Mobile SIMs",
                      "kind": "fixed",
                      "month_to_date": {
                        "amount": 42000,
                        "currency": "GBP"
                      },
                      "today": null,
                      "projected": {
                        "amount": 42000,
                        "currency": "GBP"
                      },
                      "note": null
                    },
                    {
                      "service": "Voice trunk",
                      "kind": "usage",
                      "month_to_date": {
                        "amount": 10308,
                        "currency": "USD"
                      },
                      "today": {
                        "amount": 443,
                        "currency": "USD"
                      },
                      "projected": {
                        "amount": 11660,
                        "currency": "USD"
                      },
                      "note": null
                    }
                  ],
                  "totals": [
                    {
                      "month_to_date": {
                        "amount": 42000,
                        "currency": "GBP"
                      },
                      "projected": {
                        "amount": 42000,
                        "currency": "GBP"
                      }
                    },
                    {
                      "month_to_date": {
                        "amount": 10308,
                        "currency": "USD"
                      },
                      "projected": {
                        "amount": 11660,
                        "currency": "USD"
                      }
                    }
                  ],
                  "limit": {
                    "limit": {
                      "amount": 250000,
                      "currency": "GBP"
                    },
                    "used": {
                      "amount": 42000,
                      "currency": "GBP"
                    },
                    "projected": {
                      "amount": 42000,
                      "currency": "GBP"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dips/products": {
      "get": {
        "operationId": "listDipProducts",
        "tags": [
          "Dips"
        ],
        "summary": "Dip products you can buy, with live prices.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/DipProduct"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "dip_product",
                      "code": "nrv",
                      "name": "VPX-NRV",
                      "price": {
                        "amount": "0.0050",
                        "currency": "USD"
                      }
                    },
                    {
                      "object": "dip_product",
                      "code": "last_port",
                      "name": "Last Port",
                      "price": {
                        "amount": "0.0030",
                        "currency": "USD"
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dips": {
      "get": {
        "operationId": "listDips",
        "tags": [
          "Dips"
        ],
        "summary": "Past single dips, newest first: the most recent 200, each kept for 90 days.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Dip"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "dip",
                      "id": "dip_x7k2m9qwp4zr",
                      "number": "447700900123",
                      "country": "GB",
                      "products": [
                        "nrv",
                        "last_port"
                      ],
                      "risk": "low",
                      "score": 12,
                      "validity": "valid",
                      "network": "Mobile network GB",
                      "status": "active",
                      "created_at": "2026-10-27T16:45:10Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createDip",
        "tags": [
          "Dips"
        ],
        "summary": "Dip one number: the chosen products, answered now.",
        "x-scope": "dips:write",
        "x-charged": true,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "description": "Charged from your prepaid balance in the currency the request names (else your account's own currency), at the portal's prices converted at today's rate. The full price of the requested products is taken before the dip runs; if the balance does not cover it the answer is 402 insufficient_balance and no dip runs. Products that do not answer are refunded, and a dip the service cannot answer is refunded in full (503). The Idempotency-Key is recorded with the payment itself, so one key is never charged twice. 423 account_locked when the account is locked pending a Trust & Safety review. Dips run at up to 10 per second per key and up to 10 per second across all of an account's keys; a burst waits once, then 429.",
        "x-events": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DipCreate"
              },
              "example": {
                "number": "+447700900123",
                "products": [
                  "nrv",
                  "last_port"
                ],
                "currency": "GBP"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DipCreated"
                },
                "example": {
                  "object": "dip",
                  "id": "dip_x7k2m9qwp4zr",
                  "number": "447700900123",
                  "country": "GB",
                  "products": [
                    "nrv",
                    "last_port"
                  ],
                  "results": {
                    "nrv": {
                      "tn": "447700900123",
                      "cc": "GB",
                      "valid": true,
                      "source": "local",
                      "line_type": "mobile",
                      "range_holder": "Example Mobile Ltd",
                      "ms": 12
                    },
                    "last_port": {
                      "tn": "447700900123",
                      "valid": "Y",
                      "lastPorted": "00/00/0000"
                    }
                  },
                  "charge": {
                    "amount": "0.0080",
                    "currency": "USD"
                  },
                  "created_at": "2026-10-27T16:45:10Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          },
          "504": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-billable": true
      }
    },
    "/dips/{id}": {
      "get": {
        "operationId": "getDip",
        "tags": [
          "Dips"
        ],
        "summary": "One past dip.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Dip"
                },
                "example": {
                  "object": "dip",
                  "id": "dip_x7k2m9qwp4zr",
                  "number": "447700900123",
                  "country": "GB",
                  "products": [
                    "nrv",
                    "last_port"
                  ],
                  "risk": "low",
                  "score": 12,
                  "validity": "valid",
                  "network": "Mobile network GB",
                  "status": "active",
                  "created_at": "2026-10-27T16:45:10Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dips/usage": {
      "get": {
        "operationId": "getDipUsage",
        "tags": [
          "Dips"
        ],
        "summary": "Dips this month by product.",
        "x-scope": "read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DipUsage"
                },
                "example": {
                  "object": "dip_usage",
                  "month": "2026-10",
                  "total": 1840,
                  "by_product": {
                    "nrv": 1500,
                    "last_port": 340
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dip_batches": {
      "get": {
        "operationId": "listDipBatches",
        "tags": [
          "Dips"
        ],
        "summary": "Dip batches, newest first.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/DipBatch"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "dip_batch",
                      "id": "dipb_8KQ2M7",
                      "name": "October lead list",
                      "total": 500,
                      "done": 500,
                      "products": [
                        "nrv"
                      ],
                      "state": "done",
                      "created_at": "2026-10-26T09:00:00Z",
                      "finished_at": "2026-10-26T09:04:31Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createDipBatch",
        "tags": [
          "Dips"
        ],
        "summary": "Check a file of up to 20,000 numbers in the background.",
        "description": "The whole file is charged before it starts from your prepaid balance in the currency the request names (else your account's own), at the GET /dips/products prices converted at today's rate: 402 insufficient_balance when it does not cover it. A batch that does not start is refunded in full, and any numbers the service did not accept are refunded. Needs an Idempotency-Key; one key can never pay twice. Follow it with GET /dip_batches/{id}, and read the answers with GET /dip_batches/{id}/results. A locked account gets 423 account_locked.",
        "x-scope": "dips:write",
        "x-charged": true,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DipBatchCreate"
              },
              "example": {
                "numbers": [
                  "+447700900001",
                  "+447700900002"
                ],
                "products": [
                  "nrv"
                ],
                "name": "October list"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DipBatchStarted"
                },
                "example": {
                  "object": "dip_batch",
                  "id": "dipb_8KQ2M7",
                  "name": "October list",
                  "total": 2,
                  "done": 0,
                  "products": [
                    "nrv"
                  ],
                  "state": "running",
                  "created_at": "2026-10-26T09:00:00Z",
                  "finished_at": null,
                  "charge": {
                    "amount": "0.0004",
                    "currency": "USD"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dip_batches/{id}": {
      "get": {
        "operationId": "getDipBatch",
        "tags": [
          "Dips"
        ],
        "summary": "One batch with its progress.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DipBatch"
                },
                "example": {
                  "object": "dip_batch",
                  "id": "dipb_8KQ2M7",
                  "name": "October lead list",
                  "total": 500,
                  "done": 500,
                  "products": [
                    "nrv"
                  ],
                  "state": "done",
                  "created_at": "2026-10-26T09:00:00Z",
                  "finished_at": "2026-10-26T09:04:31Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/dip_batches/{id}/results": {
      "get": {
        "operationId": "listDipBatchResults",
        "tags": [
          "Dips"
        ],
        "summary": "Batch results; 409 state_conflict while running unless partial=true. CSV with Accept: text/csv.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "partial",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/DipResult"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "dip_result",
                      "number": "447700900123",
                      "product": "nrv",
                      "result_code": "ok",
                      "result": {
                        "tn": "447700900123",
                        "cc": "GB",
                        "valid": true,
                        "source": "local",
                        "line_type": "mobile",
                        "range_holder": "Example Mobile Ltd",
                        "ms": 12
                      }
                    }
                  ],
                  "has_more": true,
                  "next_cursor": "eyJrIjoiNDQ3NzAwOTAwMTIzIn0"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/bulk_jobs": {
      "post": {
        "operationId": "createIotBulkJob",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "One change for up to 5,000 of the account's IoT SIMs, run in the background.",
        "description": "Name the SIMs by sim_ids (from GET /iot/sims) and/or iccids, 1 to 5,000 in all. Every SIM is checked to be on this account before anything runs: one that is not, a repeat, or more than 5,000 is 400 invalid_parameter and nothing is changed. The answer is 202 with the job; follow it with GET /iot/bulk_jobs/{id}. Each SIM is changed at most once, also if the job is interrupted and resumed; a SIM whose change was interrupted before it was confirmed is reported failed, never sent again. Up to 5,000 SIMs take about 2 minutes. Needs an Idempotency-Key: a retry with the same key and body returns the same job (200); the same key with another body is 409 idempotency_key_reused. A locked account gets 423 account_locked. The iot.bulk_job_done webhook fires when the job finishes.",
        "x-scope": "sims:write",
        "x-charged": false,
        "x-events": [
          "iot.bulk_job_done"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotBulkJobCreate"
              },
              "example": {
                "sim_ids": [
                  "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "sim_b4nq7zx2kw5rm3dh6ctvfypa"
                ],
                "change": {
                  "data_limit": {
                    "total_bytes": 1073741824,
                    "period": "monthly",
                    "alert_bytes": 858993459
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The job this Idempotency-Key already started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotBulkJob"
                },
                "example": {
                  "object": "iot_bulk_job",
                  "id": "bulk_3f9a1c7e5b2d4a6c8e0f1a2b",
                  "status": "done",
                  "change": {
                    "data_limit": {
                      "total_bytes": 1073741824,
                      "period": "monthly",
                      "alert_bytes": 858993459
                    }
                  },
                  "total": 2,
                  "processed": 2,
                  "succeeded": 2,
                  "failed": 0,
                  "created_at": "2026-10-28T09:10:00Z",
                  "finished_at": "2026-10-28T09:10:04Z"
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the job runs in the background",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotBulkJob"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/bulk_jobs/{id}": {
      "get": {
        "operationId": "getIotBulkJob",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "One bulk job with its progress.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotBulkJob"
                },
                "example": {
                  "object": "iot_bulk_job",
                  "id": "bulk_3f9a1c7e5b2d4a6c8e0f1a2b",
                  "status": "done",
                  "change": {
                    "data_limit": {
                      "total_bytes": 1073741824,
                      "period": "monthly",
                      "alert_bytes": 858993459
                    }
                  },
                  "total": 2,
                  "processed": 2,
                  "succeeded": 2,
                  "failed": 0,
                  "created_at": "2026-10-28T09:10:00Z",
                  "finished_at": "2026-10-28T09:10:04Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/bulk_jobs/{id}/results": {
      "get": {
        "operationId": "listIotBulkJobResults",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "Each SIM's result, in the order asked: ok, failed with a reason, or pending. CSV with Accept: text/csv.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotBulkResult"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_bulk_result",
                      "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                      "iccid": "8944501234567890123",
                      "status": "ok",
                      "reason": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/trunks/channels": {
      "get": {
        "operationId": "getTrunkChannels",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Channels in use per trunk, now and at peak, against each trunk's limit, with a series.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "24h",
                "7d",
                "30d"
              ],
              "default": "24h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrunkChannels"
                },
                "example": {
                  "object": "trunk_channels",
                  "range": "24h",
                  "bucket_seconds": 900,
                  "history_through": "2026-10-28T21:45:00Z",
                  "unavailable": [],
                  "trunks": [
                    {
                      "name": "ACME_SIP_GW1",
                      "limit": 120,
                      "now": 38,
                      "now_at": "2026-10-28T21:59:30Z",
                      "peak": 96,
                      "peak_at": "2026-10-28T18:15:00Z",
                      "series": [
                        {
                          "at": "2026-10-28T21:15:00Z",
                          "channels": 41
                        },
                        {
                          "at": "2026-10-28T21:30:00Z",
                          "channels": 36
                        }
                      ]
                    }
                  ],
                  "data_as_of": "2026-10-28T21:45:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/fraud/incidents": {
      "get": {
        "operationId": "getFraudIncidents",
        "tags": [
          "Voice trunk"
        ],
        "summary": "Fraud incidents and losses our fraud engine raised on this account's traffic, against the previous period.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "24h",
                "7d",
                "30d"
              ],
              "default": "24h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudIncidents"
                },
                "example": {
                  "object": "fraud_incidents",
                  "window": "7d",
                  "totals": {
                    "incidents": 3,
                    "incidents_previous_period": 5,
                    "ranges": 2,
                    "territories": 2,
                    "origins": 1,
                    "loss": {
                      "amount": "4.12",
                      "currency": "USD"
                    }
                  },
                  "by_signal": [
                    {
                      "signal": "irsf",
                      "label": "IRSF / high-risk destination",
                      "incidents": 2
                    },
                    {
                      "signal": "wangiri",
                      "label": "Wangiri / short-call abuse",
                      "incidents": 1
                    }
                  ],
                  "unavailable": [],
                  "data_as_of": "2026-10-28T21:40:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/risk_ranges": {
      "get": {
        "operationId": "listRiskRanges",
        "tags": [
          "Dips"
        ],
        "summary": "Search the high-risk and premium-rate number ranges our network screens against. total and truncated say when a search matched more than one answer holds (500).",
        "x-scope": "read",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 60,
              "description": "A number prefix (such as 4470) or a name (such as Albania)."
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "required": [
                        "total",
                        "truncated"
                      ],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/RiskRange"
                          }
                        },
                        "total": {
                          "type": "integer"
                        },
                        "truncated": {
                          "type": "boolean"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "risk_range",
                      "prefix": "355900",
                      "label": "Albania (Republic of) - Shared Revenue Services (premium-rate only per national plan data)",
                      "kind": "premium_rate_international"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "total": 1,
                  "truncated": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/number_requirements": {
      "get": {
        "operationId": "listNumberRequirements",
        "tags": [
          "Numbers"
        ],
        "summary": "What you must supply, per country and number type, before a number goes live: personal, business and address documents, and notes. Leave out country for every country.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "description": "ISO 3166 alpha-2, for example DE."
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/NumberRequirement"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "number_requirement",
                      "country": "DE",
                      "country_name": "Germany",
                      "region": "Europe",
                      "documentation_required": true,
                      "number_types": [
                        {
                          "category": "landline",
                          "personal": [
                            "Name, last name",
                            "Contact phone number",
                            "German passport or ID copy"
                          ],
                          "business": [
                            "Name, last name",
                            "Contact phone number",
                            "Company name",
                            "German company incorporation certificate copy"
                          ],
                          "address": [
                            "Address matching: the DID area code, address in the certificate/ID (street, building number, postal code, city and country)",
                            "A copy of a utility bill (less than 6 months old)"
                          ],
                          "notes": [
                            "We reserve the right in our sole discretion to request additional information at any stage of the registration process."
                          ]
                        },
                        {
                          "category": "tollfree",
                          "personal": [
                            "Name, last name",
                            "Contact phone number",
                            "Proof of allocation (Zuteilungsbescheid) from the German national regulator (BNetzA)"
                          ],
                          "business": [
                            "Name, last name",
                            "Contact phone number",
                            "Company name",
                            "Proof of allocation (Zuteilungsbescheid) from the German national regulator (BNetzA)"
                          ],
                          "address": [
                            "Address in Germany (street, building number, postal code, city and country)"
                          ],
                          "notes": [
                            "We reserve the right in our sole discretion to request additional information at any stage of the registration process."
                          ]
                        }
                      ]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "502": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/webhook_events": {
      "get": {
        "operationId": "listWebhookEvents",
        "tags": [
          "Webhooks"
        ],
        "summary": "The events you can subscribe a webhook to.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WebhookEvent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "webhook_event",
                      "code": "invoice.issued",
                      "description": "A new invoice was issued"
                    },
                    {
                      "object": "webhook_event",
                      "code": "porting.updated",
                      "description": "A number transfer changed status"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "Your account's webhooks, newest first. The signing secret is never shown here, only its last 4 characters.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Webhook"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "webhook",
                      "id": "wh_4c1e9a07",
                      "event": "invoice.issued",
                      "description": "A new invoice was issued",
                      "url": "https://example.com/hooks/voicepro",
                      "status": "active",
                      "created_at": "2026-10-28T21:15:02Z",
                      "last_delivery_at": "2026-10-28T21:16:40Z",
                      "last_response_code": 200,
                      "failing_since": null,
                      "secret_last4": "a1b2",
                      "events": [
                        "invoice.issued"
                      ]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Subscribe an HTTPS endpoint to an event. The answer carries the signing secret, the only time it is shown: keep it to check X-VoicePro-Signature (HMAC-SHA256 of the raw body).",
        "x-scope": "webhooks:write",
        "description": "Needs the webhooks:write scope and an Idempotency-Key. A locked account gets 423 account_locked. The URL must be a public HTTPS address (checked again before every delivery; redirects are never followed). An account can have at most 25 webhooks: the 26th is 409 state_conflict.",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreate"
              },
              "example": {
                "event": "invoice.issued",
                "url": "https://example.com/hooks/voicepro"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCreated"
                },
                "example": {
                  "object": "webhook",
                  "id": "wh_4c1e9a07",
                  "event": "invoice.issued",
                  "description": "A new invoice was issued",
                  "url": "https://example.com/hooks/voicepro",
                  "status": "active",
                  "created_at": "2026-10-28T21:15:02Z",
                  "last_delivery_at": null,
                  "last_response_code": null,
                  "failing_since": null,
                  "secret_last4": "a1b2",
                  "secret": "whsec_example0000000000000000000a1b2",
                  "events": [
                    "invoice.issued"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "One webhook.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook's id, such as wh_ab12cd34.",
            "schema": {
              "type": "string",
              "pattern": "^wh_[0-9a-f]{8}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "object": "webhook",
                  "id": "wh_4c1e9a07",
                  "event": "invoice.issued",
                  "description": "A new invoice was issued",
                  "url": "https://example.com/hooks/voicepro",
                  "status": "active",
                  "created_at": "2026-10-28T21:15:02Z",
                  "last_delivery_at": "2026-10-28T21:16:40Z",
                  "last_response_code": 200,
                  "failing_since": null,
                  "secret_last4": "a1b2",
                  "events": [
                    "invoice.issued"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Change the URL, or pause and resume deliveries. A refused URL changes nothing.",
        "x-scope": "webhooks:write",
        "description": "Needs the webhooks:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook's id, such as wh_ab12cd34.",
            "schema": {
              "type": "string",
              "pattern": "^wh_[0-9a-f]{8}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdate"
              },
              "example": {
                "status": "paused"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "object": "webhook",
                  "id": "wh_4c1e9a07",
                  "event": "invoice.issued",
                  "description": "A new invoice was issued",
                  "url": "https://example.com/hooks/voicepro",
                  "status": "paused",
                  "created_at": "2026-10-28T21:15:02Z",
                  "last_delivery_at": "2026-10-28T21:16:40Z",
                  "last_response_code": 200,
                  "failing_since": null,
                  "secret_last4": "a1b2",
                  "events": [
                    "invoice.issued"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook. Deliveries stop at once.",
        "x-scope": "webhooks:write",
        "description": "Needs the webhooks:write scope and an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-charged": false,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook's id, such as wh_ab12cd34.",
            "schema": {
              "type": "string",
              "pattern": "^wh_[0-9a-f]{8}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeleted"
                },
                "example": {
                  "object": "webhook",
                  "id": "wh_4c1e9a07",
                  "deleted": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "operationId": "testWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a signed test delivery (type \"test\", header X-VoicePro-Test: true) and see how your endpoint answered. At most 10 an hour per webhook and 30 per account.",
        "x-scope": "webhooks:write",
        "description": "Needs the webhooks:write scope and an Idempotency-Key. A locked account gets 423 account_locked. Over the hourly limit is 429 rate_limited.",
        "x-charged": false,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook's id, such as wh_ab12cd34.",
            "schema": {
              "type": "string",
              "pattern": "^wh_[0-9a-f]{8}$"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                },
                "example": {
                  "object": "webhook_delivery",
                  "id": "whd_8f2b61d0c4",
                  "webhook_id": "wh_4c1e9a07",
                  "event": "invoice.issued",
                  "test": true,
                  "attempted_at": "2026-10-28T21:16:40Z",
                  "duration_ms": 212,
                  "ok": true,
                  "response_code": 200,
                  "response_excerpt": "{\"received\":true}",
                  "event_id": null,
                  "attempt": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "tags": [
          "Webhooks"
        ],
        "summary": "The last 50 deliveries to a webhook, newest first, with how your endpoint answered.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook's id, such as wh_ab12cd34.",
            "schema": {
              "type": "string",
              "pattern": "^wh_[0-9a-f]{8}$"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WebhookDelivery"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "webhook_delivery",
                      "id": "whd_8f2b61d0c4",
                      "webhook_id": "wh_4c1e9a07",
                      "event": "invoice.issued",
                      "test": true,
                      "attempted_at": "2026-10-28T21:16:40Z",
                      "duration_ms": 212,
                      "ok": true,
                      "response_code": 200,
                      "response_excerpt": "{\"received\":true}",
                      "event_id": null,
                      "attempt": 1
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}/esim": {
      "get": {
        "operationId": "getIotSimEsim",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "The SIM's eSIM profile state (for example RELEASED, DOWNLOADED, ENABLED); null for a physical SIM.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotEsim"
                },
                "example": {
                  "object": "iot_esim",
                  "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "profile_status": null,
                  "data_as_of": "2026-10-28T09:01:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}/sms": {
      "get": {
        "operationId": "listIotSimSms",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "The SIM's last 100 SMS, newest first: time, direction and status. Message text is not kept here; it arrives by the iot.sms webhook.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotSms"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_sms",
                      "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                      "at": "2026-10-28T08:40:12Z",
                      "direction": "to_device",
                      "status": null
                    },
                    {
                      "object": "iot_sms",
                      "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                      "at": "2026-10-27T17:02:45Z",
                      "direction": "from_device",
                      "status": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "sendIotSimSms",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "Send a text SMS to the device on an IoT SIM (configuration, wake-up).",
        "description": "Needs an Idempotency-Key, so a retry never sends twice. Up to 5 messages a minute to one SIM and 30 a minute per account (429 rate_limited). 503 upstream_unavailable when the network did not confirm the send: check GET /iot/sims/{id}/sms before trying again. A locked account gets 423 account_locked.",
        "x-scope": "sms:send",
        "x-charged": false,
        "x-events": [
          "iot.sms_status"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotSmsSend"
              },
              "example": {
                "text": "APN=iot.example"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotSmsAccepted"
                },
                "example": {
                  "object": "iot_sms",
                  "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "direction": "to_device",
                  "text": "APN=iot.example",
                  "status": "accepted",
                  "accepted_at": "2026-10-29T09:30:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/sims/{id}/network_list": {
      "patch": {
        "operationId": "setIotSimNetworkList",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "Restrict a SIM to one of your account's network lists, or lift the restriction (name null).",
        "x-scope": "sims:write",
        "description": "Needs the sims:write scope and an Idempotency-Key. A locked account gets 423 account_locked. A name that is not one of your lists is 404.",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IotSimNetworkListSet"
              },
              "example": {
                "name": "uk-only"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IotSimNetworkList"
                },
                "example": {
                  "object": "iot_sim_network_list",
                  "sim_id": "sim_7k2mqqxw4hd3nvbc5rtfz6ya",
                  "network_list": "uk-only"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/iot/network_lists": {
      "get": {
        "operationId": "listIotNetworkLists",
        "tags": [
          "IoT SIMs"
        ],
        "summary": "Your account's network lists: the mobile networks (MCC and MNC) a SIM on the list may use. Lists are set up with our IoT team.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/IotNetworkList"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "iot_network_list",
                      "name": "uk-only",
                      "networks": [
                        {
                          "mcc": "234",
                          "mnc": "10"
                        },
                        {
                          "mcc": "234",
                          "mnc": "15"
                        },
                        {
                          "mcc": "234",
                          "mnc": "20"
                        },
                        {
                          "mcc": "234",
                          "mnc": "30"
                        }
                      ]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/numbers/{id}/cancel": {
      "post": {
        "operationId": "cancelNumber",
        "tags": [
          "Numbers"
        ],
        "summary": "Cancel a number: no further charges; it keeps working to the end of the month already paid, then is released.",
        "description": "Needs an Idempotency-Key. Cancelling again answers the same end date. 409 state_conflict when the number is already being released. A locked account gets 423 account_locked.",
        "x-scope": "numbers:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberCancellation"
                },
                "example": {
                  "object": "number_cancellation",
                  "number_id": "num_8d2f5a1c",
                  "phone_number": "+442079460123",
                  "ends_at": "2026-11-14T10:00:00.000Z",
                  "further_charges": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/number_watches": {
      "get": {
        "operationId": "listNumberWatches",
        "tags": [
          "Dips"
        ],
        "summary": "The account's number watches, newest first.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/NumberWatch"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "number_watch",
                      "id": "nw_6f1c2a9e0b7d4c3e8a5f1b2c3d4e5f60",
                      "phone_number": "+447700900123",
                      "label": "Supplier hotline",
                      "products": [
                        "nrv",
                        "last_port"
                      ],
                      "created_at": "2026-10-29T09:12:44Z",
                      "last_checked_at": "2026-10-30T05:13:20Z",
                      "last_change_at": null,
                      "current": {
                        "validity": "valid",
                        "ported": "false",
                        "range_holder": "Example Mobile"
                      },
                      "currency": "GBP"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "operationId": "createNumberWatch",
        "tags": [
          "Dips"
        ],
        "summary": "Watch a number: re-checked daily, with every change recorded and sent to your webhooks.",
        "description": "Checked once a day (05:13 UTC). Each check runs the products chosen and is charged to the account at the GET /dips/products price for each product that answers; setting up a watch costs nothing. While the balance cannot cover a check, or the account is locked, the watch waits and nothing is charged. A change is kept as an event and sent to webhooks subscribed to number.watch_changed. At most 100 watches per account. Needs an Idempotency-Key. 409 state_conflict when the account already has 100.",
        "x-scope": "dips:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NumberWatchCreate"
              },
              "example": {
                "number": "+447700900123",
                "products": [
                  "nrv",
                  "last_port"
                ],
                "label": "Supplier hotline"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberWatch"
                },
                "example": {
                  "object": "number_watch",
                  "id": "nw_6f1c2a9e0b7d4c3e8a5f1b2c3d4e5f60",
                  "phone_number": "+447700900123",
                  "label": "Supplier hotline",
                  "products": [
                    "nrv",
                    "last_port"
                  ],
                  "created_at": "2026-10-29T09:12:44Z",
                  "last_checked_at": null,
                  "last_change_at": null,
                  "current": null,
                  "currency": "GBP"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        },
        "x-events": [
          "number.watch_changed"
        ]
      }
    },
    "/number_watches/{id}": {
      "get": {
        "operationId": "getNumberWatch",
        "tags": [
          "Dips"
        ],
        "summary": "One number watch, with the number's answer at the last check.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberWatch"
                },
                "example": {
                  "object": "number_watch",
                  "id": "nw_6f1c2a9e0b7d4c3e8a5f1b2c3d4e5f60",
                  "phone_number": "+447700900123",
                  "label": "Supplier hotline",
                  "products": [
                    "nrv",
                    "last_port"
                  ],
                  "created_at": "2026-10-29T09:12:44Z",
                  "last_checked_at": "2026-10-30T05:13:20Z",
                  "last_change_at": null,
                  "current": {
                    "validity": "valid",
                    "ported": "false",
                    "range_holder": "Example Mobile"
                  },
                  "currency": "GBP"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "operationId": "deleteNumberWatch",
        "tags": [
          "Dips"
        ],
        "summary": "Stop watching a number. Its change history goes with it.",
        "x-scope": "dips:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberWatchDeleted"
                },
                "example": {
                  "object": "number_watch",
                  "id": "nw_6f1c2a9e0b7d4c3e8a5f1b2c3d4e5f60",
                  "deleted": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/number_watches/{id}/events": {
      "get": {
        "operationId": "listNumberWatchEvents",
        "tags": [
          "Dips"
        ],
        "summary": "A watch's changes, newest first (the last 50).",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/NumberWatchEvent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "number_watch_event",
                      "watch_id": "nw_6f1c2a9e0b7d4c3e8a5f1b2c3d4e5f60",
                      "at": "2026-11-02T05:13:41Z",
                      "changes": {
                        "ported": {
                          "from": "false",
                          "to": "true"
                        },
                        "serving_network": {
                          "from": null,
                          "to": "Example Mobile 2"
                        }
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sims/{id}/suspend": {
      "post": {
        "operationId": "suspendSim",
        "tags": [
          "SIMs"
        ],
        "summary": "Suspend a SIM on the network: no calls, texts or data until it is reactivated.",
        "description": "Needs an Idempotency-Key. A SIM already suspended is answered as it is, with nothing sent to the network. Until suspending on the network is switched on for accounts, the answer is 503 network_action_unavailable. A locked account gets 423 account_locked.",
        "x-scope": "sims:write",
        "x-charged": false,
        "x-events": [
          "sim.suspended"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimState"
                },
                "example": {
                  "object": "sim_state",
                  "sim_id": "sim_K7M2Q9",
                  "status": "suspended"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/sims/{id}/reactivate": {
      "post": {
        "operationId": "reactivateSim",
        "tags": [
          "SIMs"
        ],
        "summary": "Reactivate a suspended SIM.",
        "description": "Needs an Idempotency-Key. A SIM already active is answered as it is, with nothing sent to the network. Until suspending on the network is switched on for accounts, the answer is 503 network_action_unavailable. A locked account gets 423 account_locked.",
        "x-scope": "sims:write",
        "x-charged": false,
        "x-events": [
          "sim.suspended"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimState"
                },
                "example": {
                  "object": "sim_state",
                  "sim_id": "sim_K7M2Q9",
                  "status": "active"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/invoices/{id}/payment_link": {
      "post": {
        "operationId": "createInvoicePaymentLink",
        "tags": [
          "Billing"
        ],
        "summary": "A secure payment link for an open invoice, to pay it or send it on.",
        "description": "The same hosted payment page the portal's Pay now opens, for the invoice's own amount. While a link is open it is the one returned, so an invoice has one live link at a time. 409 state_conflict when the invoice is paid or not open. Needs an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-scope": "billing:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicePaymentLink"
                },
                "example": {
                  "object": "invoice_payment_link",
                  "invoice_id": "inv_2610AB12",
                  "url": "https://pay.example.com/c/cs_example",
                  "amount": {
                    "amount": 50400,
                    "currency": "GBP"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "listEvents",
        "tags": [
          "Webhooks"
        ],
        "summary": "Your account's events from the last 30 days, newest first, as sent to your webhooks.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "spend.threshold",
                "sim.data_cap",
                "sim.roaming",
                "sim.suspended",
                "trunk.asr_drop",
                "invoice.issued",
                "invoice.overdue",
                "porting.updated",
                "incident.opened",
                "alert.rule",
                "iot.attached",
                "iot.detached",
                "iot.authentication",
                "iot.data_limit",
                "iot.cost_alert",
                "iot.sms",
                "iot.sms_status",
                "iot.bulk_job_done",
                "number.watch_changed"
              ]
            },
            "description": "Only events of this type."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Event"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "event",
                      "id": "evt_3f9c2a71b8e04d6a9c1e5b27",
                      "type": "invoice.issued",
                      "occurred_at": "2026-10-29T09:00:00Z",
                      "data": {
                        "id": "INV-26-10AB12",
                        "period": "2026-10",
                        "totalGbp": 42,
                        "dueAt": "2026-11-12T00:00:00.000Z"
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "operationId": "getEvent",
        "tags": [
          "Webhooks"
        ],
        "summary": "One event from the last 30 days.",
        "x-scope": "read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                },
                "example": {
                  "object": "event",
                  "id": "evt_3f9c2a71b8e04d6a9c1e5b27",
                  "type": "invoice.issued",
                  "occurred_at": "2026-10-29T09:00:00Z",
                  "data": {
                    "id": "INV-26-10AB12",
                    "period": "2026-10",
                    "totalGbp": 42,
                    "dueAt": "2026-11-12T00:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/events/{id}/resend": {
      "post": {
        "operationId": "resendEvent",
        "tags": [
          "Webhooks"
        ],
        "summary": "Send an event again: to every webhook that receives its type, or to one.",
        "description": "The same event (same id and data) with a fresh signature; a failed resend is retried like any delivery. Needs an Idempotency-Key. A locked account gets 423 account_locked.",
        "x-scope": "webhooks:write",
        "x-charged": false,
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventResendRequest"
              },
              "example": {
                "webhook_id": "wh_4c1e9a07"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventResend"
                },
                "example": {
                  "object": "event_resend",
                  "event_id": "evt_3f9c2a71b8e04d6a9c1e5b27",
                  "webhooks": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "423": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer vpk_live_... (real data) or vpk_test_... (sandbox). Keys are created by owners and admins in the portal; the secret is shown once. Every request made with a key, including refusals of a recognised key (revoked, expired, IP not allowed, account not active), is written to that key's access log, kept 30 days and visible to owners and admins, so a leaked key leaves a trail."
      }
    },
    "headers": {
      "StandardSet": {
        "description": "Every response carries Request-Id. Every response where the key was resolved also carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, reporting whichever of the key and account limits has less remaining; a 401 raised before the key is known has no bucket and carries Request-Id only. A 429 also carries Retry-After (seconds).",
        "schema": {
          "type": "string"
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Required on every POST. 8-128 characters: letters, digits, dot, colon, hyphen or underscore. The first response is stored for 24 hours and replayed for any retry with the same key and the same body. Two rules, set per operation by x-charged. Charged or partner-side operations (x-charged true: dips, dip batches, orders, SMS, porting) never re-run while a first attempt is unfinished: a retry answers 409 idempotency_key_in_use (outcome pending) until the first outcome is stored, and the key is also given to the partner as its own reference, so one key never causes more than one order, charge or message, even across failures. A charged operation that fails part-way stores that failure as the key's answer; only a refusal before anything ran (400, 401, 402, 403, 404, 429) frees the key for a retry. Operations with no outside effect (x-charged false) hold their key for at most 2 minutes; after that a retry runs fresh. Missing: 400 missing_parameter (param Idempotency-Key). Malformed: 400 invalid_parameter. Same key, different body: 409 idempotency_key_reused. First request still running: 409 idempotency_key_in_use.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9.:_-]{8,128}$"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "default": 50
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "schema": {
          "type": "string",
          "description": "next_cursor from the previous page."
        }
      },
      "From": {
        "name": "from",
        "in": "query",
        "schema": {
          "type": "string",
          "description": "Default: 24 hours before to.",
          "format": "date-time"
        }
      },
      "To": {
        "name": "to",
        "in": "query",
        "schema": {
          "type": "string",
          "description": "Default: now.",
          "format": "date-time"
        }
      },
      "Step": {
        "name": "step",
        "in": "query",
        "schema": {
          "type": "string",
          "description": "Default by range: 5m up to a day, 1h up to a week, else 1d.",
          "enum": [
            "5m",
            "1h",
            "1d"
          ]
        }
      },
      "CompareFrom": {
        "name": "compare_from",
        "in": "query",
        "schema": {
          "type": "string",
          "description": "With compare_to: a previous period to compare.",
          "format": "date-time"
        }
      },
      "CompareTo": {
        "name": "compare_to",
        "in": "query",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "Id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Error": {
        "description": "An error. The body is always an ErrorResponse; the HTTP status for each code is fixed in x-error-codes.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "code",
              "message",
              "request_id"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "$ref": "#/components/schemas/ErrorType"
              },
              "code": {
                "type": "string",
                "description": "Stable machine code from x-error-codes. Never renamed within v3; new codes may be added."
              },
              "message": {
                "type": "string",
                "description": "For humans. May change at any time; never parse it."
              },
              "param": {
                "type": "string",
                "description": "The request parameter or body field at fault, when there is one."
              },
              "request_id": {
                "type": "string",
                "pattern": "^req_[A-Za-z0-9]{16,}$"
              }
            }
          }
        }
      },
      "ErrorType": {
        "type": "string",
        "enum": [
          "authentication",
          "permission",
          "invalid_request",
          "not_found",
          "conflict",
          "payment_required",
          "rate_limited",
          "upstream_unavailable",
          "internal"
        ]
      },
      "List": {
        "type": "object",
        "description": "Envelope for every list. Paging: limit (default 50, maximum 500) and cursor (the next_cursor of the previous page).",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Money": {
        "type": "object",
        "required": [
          "amount",
          "currency"
        ],
        "additionalProperties": false,
        "description": "Integer minor units (pence, cents) plus ISO 4217 currency. Per-minute rates use a decimal string instead (see Rate).",
        "properties": {
          "amount": {
            "type": "integer"
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "object",
          "id",
          "name",
          "legal_name",
          "status",
          "country",
          "timezone",
          "currency",
          "parent_account_id",
          "created_at",
          "services",
          "spending_limit",
          "sso",
          "open_invoice_count",
          "authenticated_as"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "const": "account"
          },
          "id": {
            "type": "string",
            "pattern": "^acct_[A-Za-z0-9]+$",
            "description": "Maps to the internal workspace id (WS-XXXXXX)."
          },
          "name": {
            "type": "string",
            "description": "Trading name, or the legal name when no trading name is set."
          },
          "legal_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_review",
              "msa_pending",
              "active",
              "suspended",
              "closed",
              "unknown"
            ]
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$"
          },
          "timezone": {
            "type": "string",
            "description": "IANA zone. Day boundaries in usage reports follow it."
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$",
            "description": "Display and spending-limit currency."
          },
          "parent_account_id": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^acct_[A-Za-z0-9]+$"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "services": {
            "type": "object",
            "required": [
              "mobile_sims",
              "numbers",
              "voice_trunk",
              "sms_route",
              "iot"
            ],
            "additionalProperties": false,
            "properties": {
              "mobile_sims": {
                "type": "object",
                "required": [
                  "enabled",
                  "count",
                  "active_count"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "count": {
                    "type": "integer"
                  },
                  "active_count": {
                    "type": "integer"
                  }
                }
              },
              "numbers": {
                "type": "object",
                "required": [
                  "enabled",
                  "count"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "count": {
                    "type": "integer"
                  }
                }
              },
              "voice_trunk": {
                "type": "object",
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              },
              "sms_route": {
                "type": "object",
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              },
              "iot": {
                "type": "object",
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "spending_limit": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "limit",
              "alert_percentages"
            ],
            "additionalProperties": false,
            "properties": {
              "limit": {
                "$ref": "#/components/schemas/Money"
              },
              "alert_percentages": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 200
                },
                "maxItems": 5
              }
            },
            "description": "null when no limit is set, or the key lacks billing:read."
          },
          "sso": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "domain",
              "providers",
              "required"
            ],
            "additionalProperties": false,
            "properties": {
              "domain": {
                "type": "string"
              },
              "providers": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "google",
                    "microsoft"
                  ]
                }
              },
              "required": {
                "type": "boolean"
              }
            }
          },
          "open_invoice_count": {
            "type": [
              "integer",
              "null"
            ],
            "description": "null unless the key has billing:read."
          },
          "authenticated_as": {
            "type": "object",
            "required": [
              "type",
              "key_id",
              "mode",
              "scopes"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "api_key"
              },
              "key_id": {
                "type": "string",
                "pattern": "^key_[A-Za-z0-9]+$"
              },
              "mode": {
                "type": "string",
                "enum": [
                  "live",
                  "test"
                ]
              },
              "scopes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Scope"
                }
              }
            }
          }
        }
      },
      "DataAsOf": {
        "type": [
          "string",
          "null"
        ],
        "format": "date-time",
        "description": "Data is complete up to this time: the newest record we hold behind this response. null when we hold no records yet (x-conventions.freshness)."
      },
      "Scope": {
        "type": "string",
        "description": "The permissions an API key can hold. Each operation names the scope it needs.",
        "enum": [
          "read",
          "billing:read",
          "numbers:read",
          "dips:write",
          "orders:write",
          "sims:write",
          "numbers:write",
          "sms:send",
          "porting:write",
          "webhooks:write",
          "iot:write",
          "billing:write"
        ]
      },
      "DecimalMoney": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "amount",
          "currency"
        ],
        "description": "Amounts below a penny or cent (per-minute rates, per-call charges, dip prices): a decimal string plus ISO 4217 currency.",
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]+(\\.[0-9]+)?$"
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
          }
        }
      },
      "TimeRange": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "from",
          "to",
          "step",
          "timezone"
        ],
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "step": {
            "type": "string",
            "enum": [
              "5m",
              "1h",
              "1d"
            ]
          },
          "timezone": {
            "type": "string",
            "description": "IANA zone of the account; days follow it."
          }
        }
      },
      "SimTotals": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data_bytes",
          "roaming_bytes",
          "calls",
          "call_seconds",
          "sms"
        ],
        "properties": {
          "data_bytes": {
            "type": "integer"
          },
          "roaming_bytes": {
            "type": "integer"
          },
          "calls": {
            "type": "integer"
          },
          "call_seconds": {
            "type": "integer"
          },
          "sms": {
            "type": "integer"
          }
        }
      },
      "NumberTotals": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "inbound_calls",
          "outbound_calls",
          "answered_calls",
          "minutes",
          "sms"
        ],
        "properties": {
          "inbound_calls": {
            "type": "integer"
          },
          "outbound_calls": {
            "type": "integer"
          },
          "answered_calls": {
            "type": "integer"
          },
          "minutes": {
            "type": "number"
          },
          "sms": {
            "type": "integer"
          }
        }
      },
      "TrafficTotals": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "calls",
          "answered",
          "asr",
          "acd_seconds",
          "minutes",
          "spend",
          "pdd_seconds",
          "sdr"
        ],
        "properties": {
          "calls": {
            "type": "integer"
          },
          "answered": {
            "type": "integer"
          },
          "asr": {
            "type": [
              "number",
              "null"
            ],
            "description": "Answer-seizure ratio, percent."
          },
          "acd_seconds": {
            "type": [
              "number",
              "null"
            ]
          },
          "minutes": {
            "type": [
              "number",
              "null"
            ]
          },
          "spend": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DecimalMoney"
              },
              {
                "type": "null"
              }
            ]
          },
          "pdd_seconds": {
            "type": [
              "number",
              "null"
            ],
            "description": "Post-dial delay."
          },
          "sdr": {
            "type": [
              "number",
              "null"
            ],
            "description": "Short-duration call ratio, percent."
          }
        }
      },
      "Network": {
        "type": [
          "object",
          "null"
        ],
        "additionalProperties": false,
        "required": [
          "name",
          "country",
          "mcc",
          "mnc"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "mcc": {
            "type": [
              "string",
              "null"
            ]
          },
          "mnc": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "SubAccount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "status",
          "sim_count",
          "number_count",
          "voice_trunk",
          "member_count"
        ],
        "properties": {
          "object": {
            "const": "sub_account"
          },
          "id": {
            "type": "string",
            "pattern": "^acct_[A-Za-z0-9]+$"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_review",
              "msa_pending",
              "active",
              "suspended",
              "closed",
              "unknown"
            ]
          },
          "sim_count": {
            "type": "integer"
          },
          "number_count": {
            "type": "integer"
          },
          "voice_trunk": {
            "type": "boolean"
          },
          "member_count": {
            "type": "integer"
          }
        },
        "description": "Counts only. Spend is per account on GET /spend, because it needs live wholesale data (x-conventions.freshness)."
      },
      "Incident": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "title",
          "kind",
          "impact",
          "components",
          "started_at",
          "resolved_at",
          "status_page_url"
        ],
        "properties": {
          "object": {
            "const": "incident"
          },
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "incident",
              "maintenance"
            ]
          },
          "impact": {
            "type": "string"
          },
          "components": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "resolved_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "status_page_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Sim": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label",
          "plan_name",
          "add_ons",
          "iccid",
          "phone_number",
          "country",
          "status",
          "holder_name",
          "data_cap_gb",
          "created_at",
          "activated_at",
          "month_to_date",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "sim"
          },
          "id": {
            "type": "string",
            "pattern": "^sim_[A-Za-z0-9]+$"
          },
          "label": {
            "type": "string"
          },
          "plan_name": {
            "type": "string"
          },
          "add_ons": {
            "type": "array",
            "description": "Add-on names.",
            "items": {
              "type": "string"
            }
          },
          "iccid": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "E.164."
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended",
              "retired",
              "unknown"
            ]
          },
          "holder_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "data_cap_gb": {
            "type": [
              "number",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "activated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "month_to_date": {
            "$ref": "#/components/schemas/SimMonth"
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "SimUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sim_id",
          "range",
          "totals",
          "previous",
          "series",
          "by_country",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "sim_usage"
          },
          "sim_id": {
            "type": "string"
          },
          "range": {
            "$ref": "#/components/schemas/TimeRange"
          },
          "totals": {
            "$ref": "#/components/schemas/SimTotals"
          },
          "previous": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SimTotals"
              },
              {
                "type": "null"
              }
            ]
          },
          "series": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "t",
                "data_bytes",
                "calls",
                "sms"
              ],
              "properties": {
                "t": {
                  "type": "string",
                  "format": "date-time"
                },
                "data_bytes": {
                  "type": "integer"
                },
                "calls": {
                  "type": "integer"
                },
                "sms": {
                  "type": "integer"
                }
              }
            }
          },
          "by_country": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "country",
                "data_bytes"
              ],
              "properties": {
                "country": {
                  "type": "string",
                  "pattern": "^[A-Z]{2}$"
                },
                "data_bytes": {
                  "type": "integer"
                }
              }
            }
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "IotSim": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "iccid",
          "label",
          "activated",
          "online",
          "network",
          "network_type",
          "last_seen_at",
          "imei_lock",
          "data_limit",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "iot_sim"
          },
          "id": {
            "type": "string",
            "pattern": "^sim_[a-z2-7]{24}$",
            "description": "Opaque and one-way; never the IoT network's SIM id."
          },
          "iccid": {
            "type": [
              "string",
              "null"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "activated": {
            "type": "boolean"
          },
          "online": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "network": {
            "$ref": "#/components/schemas/Network"
          },
          "network_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "imei_lock": {
            "type": [
              "string",
              "null"
            ]
          },
          "data_limit": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": false,
            "required": [
              "total_bytes",
              "period",
              "alert_bytes"
            ],
            "properties": {
              "total_bytes": {
                "type": "integer"
              },
              "period": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "daily",
                  "monthly",
                  null
                ]
              },
              "alert_bytes": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "month_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Data this calendar month (UTC), on the single-SIM view only; null if the network could not say just now."
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "IotEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "time",
          "type",
          "outcome",
          "reason",
          "message",
          "network",
          "network_type",
          "imei",
          "ip",
          "session_id",
          "upload_bytes",
          "download_bytes",
          "bytes",
          "location"
        ],
        "properties": {
          "object": {
            "const": "iot_event"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "type": "string",
            "enum": [
              "authentication",
              "attach",
              "data_session_start",
              "detach",
              "location",
              "other"
            ],
            "description": "authentication: the SIM asked to use a network. attach: registered on a network (SMS possible). data_session_start: a data session opened. detach: deregistered, closing any data session. location: an approximate location at the start or end of a session, or after a move. other: a type this API does not name yet."
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "allowed",
              "refused",
              null
            ],
            "description": "For authentication only."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the network refused an authentication, for example network_whitelist (the network is not on the SIM's network list) or an IMEI lock."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "The reason, else the network's status code. Kept for compatibility; prefer reason."
          },
          "network": {
            "$ref": "#/components/schemas/Network"
          },
          "network_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "GSM, 2G/3G, 3G, 4G and so on."
          },
          "imei": {
            "type": [
              "string",
              "null"
            ],
            "description": "The device's IMEI when the network reported it."
          },
          "ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "The SIM's private IPv4 address for the session."
          },
          "session_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "upload_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "On detach: bytes the device sent in the session."
          },
          "download_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "On detach: bytes the device received in the session."
          },
          "bytes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "upload_bytes plus download_bytes."
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": false,
            "required": [
              "cell_id",
              "area_code",
              "accuracy_m",
              "lat",
              "lng"
            ],
            "description": "On location events: the serving cell and an approximate position (null when it could not be determined). Kept 7 days.",
            "properties": {
              "cell_id": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "area_code": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "accuracy_m": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Radius in metres."
              },
              "lat": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "lng": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        }
      },
      "IotUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "period_start",
          "period_end",
          "bytes",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "iot_usage"
          },
          "period_start": {
            "type": "string",
            "format": "date-time"
          },
          "period_end": {
            "type": "string",
            "format": "date-time"
          },
          "bytes": {
            "type": "integer"
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "IotConnectorType": {
        "type": "string",
        "enum": [
          "https",
          "tls",
          "azure_iot_hub",
          "aws_iot_core"
        ],
        "description": "aws_iot_core is in beta on the IoT network and is offered only when listed in types."
      },
      "IotConnectorSettings": {
        "type": "object",
        "additionalProperties": false,
        "description": "Non-secret settings, by type. https: url. tls: host, port, server_name. aws_iot_core: region, role_arn, publish_topic, subscribe_topic, default_protocol, default_port. azure_iot_hub: none.",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "https:// only, no username or password."
          },
          "host": {
            "type": "string"
          },
          "port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
          "server_name": {
            "type": "string",
            "description": "TLS server name (SNI)."
          },
          "region": {
            "type": "string"
          },
          "role_arn": {
            "type": "string"
          },
          "publish_topic": {
            "type": "string"
          },
          "subscribe_topic": {
            "type": "string"
          },
          "default_protocol": {
            "type": "string",
            "enum": [
              "tcp",
              "udp"
            ]
          },
          "default_port": {
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          }
        }
      },
      "IotConnectorSecrets": {
        "type": "object",
        "additionalProperties": false,
        "description": "Write-only. tls: private_key (RSA, PEM), certificate and ca_certificate (PEM). azure_iot_hub: connection_string.",
        "properties": {
          "private_key": {
            "type": "string",
            "writeOnly": true
          },
          "certificate": {
            "type": "string",
            "writeOnly": true
          },
          "ca_certificate": {
            "type": "string",
            "writeOnly": true
          },
          "connection_string": {
            "type": "string",
            "writeOnly": true
          }
        }
      },
      "IotPassthroughRule": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "protocol"
        ],
        "description": "Traffic that bypasses the connector.",
        "properties": {
          "protocol": {
            "type": "string",
            "enum": [
              "icmp",
              "tcp",
              "udp"
            ]
          },
          "ip": {
            "type": [
              "string",
              "null"
            ]
          },
          "port": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 65535
          }
        }
      },
      "IotConnectorCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{3,60}$"
          },
          "type": {
            "$ref": "#/components/schemas/IotConnectorType"
          },
          "settings": {
            "$ref": "#/components/schemas/IotConnectorSettings"
          },
          "secrets": {
            "$ref": "#/components/schemas/IotConnectorSecrets"
          },
          "passthrough": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/IotPassthroughRule"
            }
          }
        }
      },
      "IotConnectorUpdate": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/IotConnectorSettings"
          },
          "secrets": {
            "$ref": "#/components/schemas/IotConnectorSecrets"
          },
          "passthrough": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/IotPassthroughRule"
            }
          }
        }
      },
      "IotConnector": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "name",
          "type",
          "settings",
          "secrets",
          "passthrough",
          "sim_count"
        ],
        "properties": {
          "object": {
            "const": "iot_connector"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/IotConnectorType"
          },
          "settings": {
            "type": "object",
            "description": "As IotConnectorSettings; url is shown without its query string, and url_query says whether one is set.",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri",
                "description": "https:// only, no username or password."
              },
              "host": {
                "type": "string"
              },
              "port": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "server_name": {
                "type": "string",
                "description": "TLS server name (SNI)."
              },
              "region": {
                "type": "string"
              },
              "role_arn": {
                "type": "string"
              },
              "publish_topic": {
                "type": "string"
              },
              "subscribe_topic": {
                "type": "string"
              },
              "default_protocol": {
                "type": "string",
                "enum": [
                  "tcp",
                  "udp"
                ]
              },
              "default_port": {
                "type": "integer",
                "minimum": 1,
                "maximum": 65535
              },
              "url_query": {
                "type": "string",
                "enum": [
                  "set",
                  "not set"
                ]
              }
            }
          },
          "secrets": {
            "type": "object",
            "description": "Each secret of the type: set or not set. Values are never returned.",
            "properties": {
              "private_key": {
                "type": "string",
                "enum": [
                  "set",
                  "not set"
                ]
              },
              "certificate": {
                "type": "string",
                "enum": [
                  "set",
                  "not set"
                ]
              },
              "ca_certificate": {
                "type": "string",
                "enum": [
                  "set",
                  "not set"
                ]
              },
              "connection_string": {
                "type": "string",
                "enum": [
                  "set",
                  "not set"
                ]
              }
            }
          },
          "passthrough": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IotPassthroughRule"
            }
          },
          "sim_count": {
            "type": "integer",
            "description": "Your IoT SIMs using this connector."
          }
        }
      },
      "IotConnectorDeleted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "name",
          "deleted"
        ],
        "properties": {
          "object": {
            "const": "iot_connector"
          },
          "name": {
            "type": "string"
          },
          "deleted": {
            "const": true
          }
        }
      },
      "IotConnectorTest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "name",
          "delivered",
          "status",
          "detail",
          "recent_errors"
        ],
        "properties": {
          "object": {
            "const": "iot_connector_test"
          },
          "name": {
            "type": "string"
          },
          "delivered": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "HTTPS only: whether your endpoint accepted the test POST. null for other types."
          },
          "status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Your endpoint's HTTP status."
          },
          "detail": {
            "type": "string"
          },
          "recent_errors": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "time",
                "message"
              ],
              "properties": {
                "time": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "IotSimConnectorUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "connector"
        ],
        "properties": {
          "connector": {
            "type": [
              "string",
              "null"
            ],
            "description": "One of your connector names, or null for none."
          }
        }
      },
      "IotSimConnector": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "connector"
        ],
        "properties": {
          "object": {
            "const": "iot_sim_connector"
          },
          "sim_id": {
            "type": "string"
          },
          "connector": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Number": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "phone_number",
          "holder_name",
          "status",
          "provisioned_at",
          "routing"
        ],
        "properties": {
          "object": {
            "const": "number"
          },
          "id": {
            "type": "string",
            "pattern": "^num_[a-z2-7]{24}$",
            "description": "Opaque and one-way; never the supplier's id."
          },
          "phone_number": {
            "type": "string",
            "description": "E.164."
          },
          "holder_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "pending_removal",
              "unknown"
            ]
          },
          "provisioned_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "routing": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "mode",
              "forward_to"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "app",
                  "forward"
                ]
              },
              "forward_to": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "E.164."
              }
            }
          }
        }
      },
      "NumberUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number_id",
          "range",
          "totals",
          "previous",
          "series"
        ],
        "properties": {
          "object": {
            "const": "number_usage"
          },
          "number_id": {
            "type": "string"
          },
          "range": {
            "$ref": "#/components/schemas/TimeRange"
          },
          "totals": {
            "$ref": "#/components/schemas/NumberTotals"
          },
          "previous": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NumberTotals"
              },
              {
                "type": "null"
              }
            ]
          },
          "series": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "t",
                "calls",
                "sms"
              ],
              "properties": {
                "t": {
                  "type": "string",
                  "format": "date-time"
                },
                "calls": {
                  "type": "integer"
                },
                "sms": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "PortRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "numbers",
          "current_provider",
          "account_reference",
          "authorised_name",
          "status",
          "transfer_date",
          "action_needed",
          "history",
          "created_at"
        ],
        "properties": {
          "object": {
            "const": "port_request"
          },
          "id": {
            "type": "string",
            "pattern": "^port_[A-Za-z0-9]+$"
          },
          "numbers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "current_provider": {
            "type": "string"
          },
          "account_reference": {
            "type": "string"
          },
          "authorised_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "submitted",
              "validating",
              "accepted",
              "completed",
              "rejected",
              "cancelled"
            ]
          },
          "transfer_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "action_needed": {
            "type": [
              "string",
              "null"
            ]
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "at",
                "status",
                "note"
              ],
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "status": {
                  "type": "string"
                },
                "note": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Trunk": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "active",
          "call_limit",
          "cps_limit",
          "max_call_seconds",
          "allowed_ips",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "trunk"
          },
          "name": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "call_limit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cps_limit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_call_seconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "Rate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "destination",
          "rate",
          "billing_increment",
          "effective_from",
          "effective_until"
        ],
        "properties": {
          "object": {
            "const": "rate"
          },
          "destination": {
            "type": "string"
          },
          "rate": {
            "$ref": "#/components/schemas/DecimalMoney"
          },
          "billing_increment": {
            "type": "string",
            "description": "For example 60/60."
          },
          "effective_from": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "effective_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Call": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "started_at",
          "from",
          "to",
          "country",
          "seconds",
          "result",
          "charge",
          "data_as_of",
          "sip_call_id"
        ],
        "properties": {
          "object": {
            "const": "call"
          },
          "id": {
            "type": "string",
            "pattern": "^call_[a-z2-7]+$",
            "description": "Encodes the call's SIP Call-ID; use it with GET /calls/{id}."
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "from": {
            "type": [
              "string",
              "null"
            ]
          },
          "to": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "seconds": {
            "type": "integer"
          },
          "result": {
            "type": "string"
          },
          "charge": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DecimalMoney"
              },
              {
                "type": "null"
              }
            ]
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          },
          "sip_call_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The SIP Call-ID of the call, to match your own records."
          }
        }
      },
      "Traffic": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "range",
          "totals",
          "previous",
          "series",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "traffic"
          },
          "range": {
            "$ref": "#/components/schemas/TimeRange"
          },
          "totals": {
            "$ref": "#/components/schemas/TrafficTotals"
          },
          "previous": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TrafficTotals"
              },
              {
                "type": "null"
              }
            ]
          },
          "series": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "t",
                "calls",
                "answered",
                "minutes",
                "spend"
              ],
              "properties": {
                "t": {
                  "type": "string",
                  "format": "date-time"
                },
                "calls": {
                  "type": "integer"
                },
                "answered": {
                  "type": "integer"
                },
                "minutes": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "spend": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/DecimalMoney"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            }
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "TrafficDestination": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "country",
          "calls",
          "answered",
          "asr",
          "minutes",
          "spend"
        ],
        "properties": {
          "object": {
            "const": "traffic_destination"
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$"
          },
          "calls": {
            "type": "integer"
          },
          "answered": {
            "type": "integer"
          },
          "asr": {
            "type": [
              "number",
              "null"
            ]
          },
          "minutes": {
            "type": [
              "number",
              "null"
            ]
          },
          "spend": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DecimalMoney"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Activity": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "at",
          "kind",
          "direction",
          "via",
          "from",
          "to",
          "country",
          "roaming_country",
          "seconds",
          "bytes",
          "result",
          "ok",
          "charge"
        ],
        "properties": {
          "object": {
            "const": "activity"
          },
          "id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "type": "string",
            "enum": [
              "call",
              "sms",
              "data"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "via": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "type",
              "id",
              "label"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "sim",
                  "number",
                  "trunk"
                ]
              },
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              }
            }
          },
          "from": {
            "type": [
              "string",
              "null"
            ]
          },
          "to": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "roaming_country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "seconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "result": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "charge": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DecimalMoney"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Invoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "period",
          "status",
          "subtotal",
          "vat",
          "total",
          "issued_at",
          "due_at",
          "paid_at",
          "line_count"
        ],
        "properties": {
          "object": {
            "const": "invoice"
          },
          "id": {
            "type": "string",
            "pattern": "^inv_[A-Za-z0-9]+$"
          },
          "period": {
            "type": "string",
            "pattern": "^[0-9]{4}-[0-9]{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "paid",
              "overdue",
              "void"
            ]
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "vat": {
            "$ref": "#/components/schemas/Money"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "due_at": {
            "type": "string",
            "format": "date-time"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "line_count": {
            "type": "integer"
          }
        }
      },
      "InvoiceDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "period",
          "status",
          "subtotal",
          "vat",
          "total",
          "issued_at",
          "due_at",
          "paid_at",
          "line_count",
          "lines",
          "notes"
        ],
        "properties": {
          "object": {
            "const": "invoice"
          },
          "id": {
            "type": "string",
            "pattern": "^inv_[A-Za-z0-9]+$"
          },
          "period": {
            "type": "string",
            "pattern": "^[0-9]{4}-[0-9]{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "paid",
              "overdue",
              "void"
            ]
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "vat": {
            "$ref": "#/components/schemas/Money"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "due_at": {
            "type": "string",
            "format": "date-time"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "line_count": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "description",
                "quantity",
                "unit_price",
                "total",
                "kind"
              ],
              "properties": {
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unit_price": {
                  "$ref": "#/components/schemas/Money"
                },
                "total": {
                  "$ref": "#/components/schemas/Money"
                },
                "kind": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "plan",
                    "add_on",
                    "usage",
                    "one_off",
                    "discount",
                    null
                  ]
                }
              }
            }
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "WholesaleInvoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number",
          "period_start",
          "period_end",
          "issued_at",
          "due_at",
          "total",
          "status"
        ],
        "properties": {
          "object": {
            "const": "wholesale_invoice"
          },
          "number": {
            "type": "string"
          },
          "period_start": {
            "type": "string",
            "format": "date"
          },
          "period_end": {
            "type": "string",
            "format": "date"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "due_at": {
            "type": "string",
            "format": "date-time"
          },
          "total": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "paid",
              "unpaid"
            ]
          }
        }
      },
      "WholesalePayment": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "date",
          "amount",
          "reference"
        ],
        "properties": {
          "object": {
            "const": "wholesale_payment"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "amount": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Balance": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "wholesale",
          "prepaid",
          "default_currency",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "balance"
          },
          "wholesale": {
            "type": "array",
            "description": "Per currency: invoices issued minus payments received. Positive means you owe us.",
            "items": {
              "$ref": "#/components/schemas/Money"
            }
          },
          "prepaid": {
            "type": "array",
            "description": "Your prepaid balances, one per currency you hold (a currency never topped up is absent). Every API purchase is paid from one of them. Top up by card in the portal, or by bank transfer.",
            "items": {
              "$ref": "#/components/schemas/Money"
            }
          },
          "default_currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$",
            "description": "Your account's own currency: what a purchase pays in when it names none."
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "Spend": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "period",
          "days_elapsed",
          "days_in_month",
          "lines",
          "totals",
          "limit"
        ],
        "properties": {
          "object": {
            "const": "spend"
          },
          "period": {
            "type": "string",
            "pattern": "^[0-9]{4}-[0-9]{2}$"
          },
          "days_elapsed": {
            "type": "number"
          },
          "days_in_month": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "service",
                "kind",
                "month_to_date",
                "today",
                "projected",
                "note"
              ],
              "properties": {
                "service": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "fixed",
                    "usage"
                  ]
                },
                "month_to_date": {
                  "$ref": "#/components/schemas/Money"
                },
                "today": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Money"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "projected": {
                  "$ref": "#/components/schemas/Money"
                },
                "note": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "totals": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "month_to_date",
                "projected"
              ],
              "properties": {
                "month_to_date": {
                  "$ref": "#/components/schemas/Money"
                },
                "projected": {
                  "$ref": "#/components/schemas/Money"
                }
              }
            }
          },
          "limit": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "limit",
                  "used",
                  "projected"
                ],
                "properties": {
                  "limit": {
                    "$ref": "#/components/schemas/Money"
                  },
                  "used": {
                    "$ref": "#/components/schemas/Money"
                  },
                  "projected": {
                    "$ref": "#/components/schemas/Money"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "DipProduct": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "name",
          "price"
        ],
        "properties": {
          "object": {
            "const": "dip_product"
          },
          "code": {
            "type": "string",
            "description": "Product key, for example live_status."
          },
          "name": {
            "type": "string"
          },
          "price": {
            "$ref": "#/components/schemas/DecimalMoney"
          }
        },
        "description": "Only products with a live price are listed. HLR and Live-Status are not offered by API by default."
      },
      "Dip": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "number",
          "country",
          "products",
          "risk",
          "score",
          "validity",
          "network",
          "status",
          "created_at"
        ],
        "properties": {
          "object": {
            "const": "dip"
          },
          "id": {
            "type": "string",
            "pattern": "^dip_[A-Za-z0-9]+$"
          },
          "number": {
            "type": "string"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "risk": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "type": [
              "number",
              "null"
            ]
          },
          "validity": {
            "type": [
              "string",
              "null"
            ]
          },
          "network": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DipBatch": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "total",
          "done",
          "products",
          "state",
          "created_at",
          "finished_at"
        ],
        "properties": {
          "object": {
            "const": "dip_batch"
          },
          "id": {
            "type": "string",
            "pattern": "^dipb_[A-Za-z0-9]+$"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "total": {
            "type": "integer"
          },
          "done": {
            "type": "integer"
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "state": {
            "type": "string",
            "enum": [
              "running",
              "done",
              "failed",
              "unknown"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "DipResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number",
          "product",
          "result_code",
          "result"
        ],
        "properties": {
          "object": {
            "const": "dip_result"
          },
          "number": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "result_code": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "DipUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "month",
          "total",
          "by_product"
        ],
        "properties": {
          "object": {
            "const": "dip_usage"
          },
          "month": {
            "type": "string",
            "pattern": "^[0-9]{4}-[0-9]{2}$"
          },
          "total": {
            "type": "integer"
          },
          "by_product": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Dips this month per product code; anything we cannot name is counted under other."
          }
        }
      },
      "SimMonth": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data_bytes",
          "roaming_bytes",
          "calls",
          "sms",
          "countries"
        ],
        "properties": {
          "data_bytes": {
            "type": "integer"
          },
          "roaming_bytes": {
            "type": "integer"
          },
          "calls": {
            "type": "integer"
          },
          "sms": {
            "type": "integer"
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[A-Z]{2}$"
            },
            "description": "Countries the SIM used data in outside the UK this month."
          }
        }
      },
      "NumberRoutingUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "routing"
        ],
        "properties": {
          "routing": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "mode"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "app",
                  "forward"
                ],
                "description": "app rings the VoicePro app; forward diverts calls to forward_to."
              },
              "forward_to": {
                "type": "string",
                "pattern": "^\\+[1-9][0-9]{7,14}$",
                "description": "E.164. Required when mode is forward. Premium-rate numbers (UK 09, 118, 0871, 0872, 0873) are refused."
              }
            }
          }
        }
      },
      "NumberRouting": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "number_id",
          "mode",
          "forward_to",
          "state",
          "note"
        ],
        "properties": {
          "object": {
            "const": "number_routing"
          },
          "number_id": {
            "type": "string",
            "pattern": "^num_[a-z2-7]{24}$"
          },
          "mode": {
            "type": "string",
            "enum": [
              "app",
              "forward"
            ]
          },
          "forward_to": {
            "type": [
              "string",
              "null"
            ],
            "description": "E.164."
          },
          "state": {
            "type": "string",
            "enum": [
              "active",
              "pending"
            ],
            "description": "pending: saved, but not yet in effect (a forward diverts once outbound calling is on for the number); note says why."
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "DipCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number"
        ],
        "properties": {
          "number": {
            "type": "string",
            "pattern": "^\\+?[1-9][0-9]{6,14}$",
            "description": "International format, 7 to 15 digits."
          },
          "products": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "string"
            },
            "description": "Codes from GET /dips/products; default every product listed there. A code not listed is 400 invalid_parameter. HLR and Live Status are not offered to API keys."
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Za-z]{3}$",
            "description": "The currency this is paid in: GBP, EUR, USD, JPY, AUD, CAD, CHF, HKD, SGD, INR, AED, KRW or SAR. Paid from your prepaid balance in that currency; left out, your account's own currency. Prices are converted from our USD price list at today's rate. Balances are never converted into one another: a short balance in this currency is 402 insufficient_balance, whatever you hold in others."
          }
        }
      },
      "DipCreated": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "number",
          "country",
          "products",
          "results",
          "charge",
          "created_at"
        ],
        "properties": {
          "object": {
            "const": "dip"
          },
          "id": {
            "type": "string",
            "pattern": "^dip_[A-Za-z0-9]+$"
          },
          "number": {
            "type": "string"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The products that answered. Only these are charged."
          },
          "results": {
            "type": "object",
            "additionalProperties": {
              "type": "object"
            },
            "description": "One result object per product code that answered."
          },
          "charge": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DecimalMoney"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taken from the prepaid balance; null when the account is billed monthly instead."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NumberOffer": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "country",
          "prefix",
          "area_name",
          "category",
          "channels_included",
          "monthly_price",
          "setup_price",
          "first_payment",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "number_offer"
          },
          "id": {
            "type": "string",
            "pattern": "^nof_[a-z2-7]{24}$",
            "description": "Opaque and one-way; pass it as offer_id to POST /number_orders."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$"
          },
          "prefix": {
            "type": "string",
            "description": "E.164 prefix of the numbers in this offer."
          },
          "area_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "mobile",
              "landline",
              "tollfree",
              "national"
            ],
            "description": "Premium rate and shared cost numbers are never offered."
          },
          "channels_included": {
            "type": "integer",
            "minimum": 0
          },
          "monthly_price": {
            "$ref": "#/components/schemas/Money"
          },
          "setup_price": {
            "$ref": "#/components/schemas/Money"
          },
          "first_payment": {
            "$ref": "#/components/schemas/Money"
          },
          "data_as_of": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DataAsOf"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "NumberOrder": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "offer_id",
          "phone_number",
          "number_id",
          "charged",
          "balance_after",
          "created_at"
        ],
        "properties": {
          "object": {
            "const": "number_order"
          },
          "id": {
            "type": "string",
            "pattern": "^nord_[a-z2-7]{24}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed"
            ],
            "description": "completed: the number is live and routed to the account owner's app. pending: ordered and paid; the number is finished as soon as it is assigned. If it is cancelled instead, the charge is returned to your balance."
          },
          "offer_id": {
            "type": "string",
            "pattern": "^nof_[a-z2-7]{24}$"
          },
          "phone_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "E.164, or null when the number is assigned shortly after the order."
          },
          "number_id": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^num_[a-z2-7]{24}$"
          },
          "charged": {
            "$ref": "#/components/schemas/Money"
          },
          "balance_after": {
            "$ref": "#/components/schemas/Money"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "IotBulkChange": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "activated": {
            "type": "boolean",
            "description": "false stops the SIMs connecting; true lets them connect again."
          },
          "data_limit": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "total_bytes",
              "period"
            ],
            "properties": {
              "total_bytes": {
                "type": "integer",
                "minimum": 500000
              },
              "period": {
                "type": "string",
                "enum": [
                  "daily",
                  "monthly"
                ]
              },
              "alert_bytes": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 500000,
                "description": "Below total_bytes."
              }
            }
          },
          "technologies": {
            "type": "object",
            "additionalProperties": false,
            "minProperties": 1,
            "properties": {
              "sms": {
                "type": "boolean"
              },
              "network_2g_3g": {
                "type": "boolean"
              },
              "network_4g": {
                "type": "boolean"
              }
            },
            "description": "Changing these while a device is attached can drop it from the network."
          }
        }
      },
      "IotBulkJobCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "change"
        ],
        "properties": {
          "sim_ids": {
            "type": "array",
            "maxItems": 5000,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^sim_[a-z2-7]+$"
            }
          },
          "iccids": {
            "type": "array",
            "maxItems": 5000,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[0-9]{18,22}$"
            }
          },
          "change": {
            "$ref": "#/components/schemas/IotBulkChange"
          }
        },
        "description": "sim_ids and iccids together name 1 to 5,000 SIMs, each once."
      },
      "IotBulkJob": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "status",
          "change",
          "total",
          "processed",
          "succeeded",
          "failed",
          "created_at",
          "finished_at"
        ],
        "properties": {
          "object": {
            "const": "iot_bulk_job"
          },
          "id": {
            "type": "string",
            "pattern": "^bulk_[a-f0-9]{24}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "done"
            ]
          },
          "change": {
            "type": "object",
            "description": "The change as asked (IotBulkChange fields; a job made in the portal can also carry label and imei_lock)."
          },
          "total": {
            "type": "integer"
          },
          "processed": {
            "type": "integer"
          },
          "succeeded": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "IotBulkResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "iccid",
          "status",
          "reason"
        ],
        "properties": {
          "object": {
            "const": "iot_bulk_result"
          },
          "sim_id": {
            "type": "string"
          },
          "iccid": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "failed",
              "pending"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why a SIM failed, in plain words."
          }
        }
      },
      "TrunkChannels": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "range",
          "bucket_seconds",
          "trunks",
          "history_through",
          "unavailable",
          "data_as_of"
        ],
        "description": "Channels in use per trunk. One channel is one call on the trunk from setup to hang-up (ringing counts against the limit too).",
        "properties": {
          "object": {
            "const": "trunk_channels"
          },
          "range": {
            "type": "string",
            "enum": [
              "1h",
              "24h",
              "7d",
              "30d"
            ]
          },
          "bucket_seconds": {
            "type": "integer",
            "description": "Width of each point in the series."
          },
          "history_through": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The newest call record the series includes."
          },
          "unavailable": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Fields that could not be filled just now, such as now when the live view is over two minutes old."
          },
          "trunks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "name",
                "limit",
                "now",
                "now_at",
                "peak",
                "peak_at",
                "series"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "limit": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "description": "The trunk's channel limit; null when it has none."
                },
                "now": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "description": "Channels in use now; null when the live view is stale."
                },
                "now_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "peak": {
                  "type": "integer",
                  "description": "Most channels in use at once in the range."
                },
                "peak_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "series": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "at",
                      "channels"
                    ],
                    "properties": {
                      "at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "channels": {
                        "type": "integer"
                      }
                    }
                  }
                }
              }
            }
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "FraudIncidents": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "window",
          "totals",
          "by_signal",
          "unavailable",
          "data_as_of"
        ],
        "description": "Fraud incidents our fraud engine raised on this account's traffic, with the previous period of the same length for comparison.",
        "properties": {
          "object": {
            "const": "fraud_incidents"
          },
          "window": {
            "type": "string",
            "enum": [
              "24h",
              "7d",
              "30d"
            ]
          },
          "totals": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "incidents",
              "incidents_previous_period",
              "ranges",
              "territories",
              "origins",
              "loss"
            ],
            "properties": {
              "incidents": {
                "type": "integer"
              },
              "incidents_previous_period": {
                "type": "integer"
              },
              "ranges": {
                "type": "integer",
                "description": "Distinct number ranges involved."
              },
              "territories": {
                "type": "integer",
                "description": "Distinct destination countries involved."
              },
              "origins": {
                "type": "integer",
                "description": "Distinct calling origins involved."
              },
              "loss": {
                "$ref": "#/components/schemas/DecimalMoney"
              }
            }
          },
          "by_signal": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "signal",
                "label",
                "incidents"
              ],
              "properties": {
                "signal": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "incidents": {
                  "type": "integer"
                }
              }
            }
          },
          "unavailable": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "RiskRange": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "prefix",
          "label",
          "kind"
        ],
        "properties": {
          "object": {
            "const": "risk_range"
          },
          "prefix": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "high_risk",
              "premium_rate_uk",
              "premium_rate_international",
              "other"
            ],
            "description": "high_risk: on our fraud high-risk list. premium_rate_uk: UK premium-rate or barred service ranges. premium_rate_international: premium-rate and shared-revenue ranges abroad."
          }
        }
      },
      "NumberRequirement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "country",
          "country_name",
          "region",
          "documentation_required",
          "number_types"
        ],
        "properties": {
          "object": {
            "const": "number_requirement"
          },
          "country": {
            "type": "string",
            "description": "ISO 3166 alpha-2."
          },
          "country_name": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "documentation_required": {
            "type": "boolean",
            "description": "true when numbers in the country need documents before they go live."
          },
          "number_types": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "category",
                "personal",
                "business",
                "address",
                "notes"
              ],
              "properties": {
                "category": {
                  "type": "string",
                  "enum": [
                    "landline",
                    "mobile",
                    "national",
                    "tollfree",
                    "shared_cost",
                    "other"
                  ],
                  "description": "The /number_offers category, plus shared_cost."
                },
                "personal": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "For a number in a person's name."
                },
                "business": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "For a number in a company's name."
                },
                "address": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "notes": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "code",
          "description"
        ],
        "properties": {
          "object": {
            "const": "webhook_event"
          },
          "code": {
            "type": "string",
            "enum": [
              "spend.threshold",
              "sim.data_cap",
              "sim.roaming",
              "sim.suspended",
              "trunk.asr_drop",
              "invoice.issued",
              "invoice.overdue",
              "porting.updated",
              "incident.opened",
              "alert.rule",
              "iot.attached",
              "iot.detached",
              "iot.authentication",
              "iot.data_limit",
              "iot.cost_alert",
              "iot.sms",
              "iot.sms_status",
              "iot.bulk_job_done",
              "number.watch_changed"
            ]
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "event",
          "events",
          "description",
          "url",
          "status",
          "created_at",
          "last_delivery_at",
          "last_response_code",
          "failing_since",
          "secret_last4"
        ],
        "properties": {
          "object": {
            "const": "webhook"
          },
          "id": {
            "type": "string",
            "description": "wh_ and 8 characters."
          },
          "event": {
            "type": "string",
            "enum": [
              "spend.threshold",
              "sim.data_cap",
              "sim.roaming",
              "sim.suspended",
              "trunk.asr_drop",
              "invoice.issued",
              "invoice.overdue",
              "porting.updated",
              "incident.opened",
              "alert.rule",
              "iot.attached",
              "iot.detached",
              "iot.authentication",
              "iot.data_limit",
              "iot.cost_alert",
              "iot.sms",
              "iot.sms_status",
              "iot.bulk_job_done",
              "number.watch_changed"
            ],
            "description": "The first event type in events (kept for webhooks made with one event)."
          },
          "description": {
            "type": "string",
            "description": "What the event means."
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "failing"
            ],
            "description": "failing: the last delivery was not answered 2xx; the next good one makes it active again."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_delivery_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_response_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "failing_since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "secret_last4": {
            "type": "string",
            "description": "The last 4 characters of the signing secret."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "spend.threshold",
                "sim.data_cap",
                "sim.roaming",
                "sim.suspended",
                "trunk.asr_drop",
                "invoice.issued",
                "invoice.overdue",
                "porting.updated",
                "incident.opened",
                "alert.rule",
                "iot.attached",
                "iot.detached",
                "iot.authentication",
                "iot.data_limit",
                "iot.cost_alert",
                "iot.sms",
                "iot.sms_status",
                "iot.bulk_job_done",
                "number.watch_changed"
              ]
            },
            "description": "Every event type this webhook receives."
          }
        }
      },
      "WebhookCreated": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "event",
          "events",
          "description",
          "url",
          "status",
          "created_at",
          "last_delivery_at",
          "last_response_code",
          "failing_since",
          "secret_last4",
          "secret"
        ],
        "properties": {
          "object": {
            "const": "webhook"
          },
          "id": {
            "type": "string",
            "description": "wh_ and 8 characters."
          },
          "event": {
            "type": "string",
            "enum": [
              "spend.threshold",
              "sim.data_cap",
              "sim.roaming",
              "sim.suspended",
              "trunk.asr_drop",
              "invoice.issued",
              "invoice.overdue",
              "porting.updated",
              "incident.opened",
              "alert.rule",
              "iot.attached",
              "iot.detached",
              "iot.authentication",
              "iot.data_limit",
              "iot.cost_alert",
              "iot.sms",
              "iot.sms_status",
              "iot.bulk_job_done",
              "number.watch_changed"
            ],
            "description": "The first event type in events (kept for webhooks made with one event)."
          },
          "description": {
            "type": "string",
            "description": "What the event means."
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "failing"
            ],
            "description": "failing: the last delivery was not answered 2xx; the next good one makes it active again."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_delivery_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_response_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "failing_since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "secret_last4": {
            "type": "string",
            "description": "The last 4 characters of the signing secret."
          },
          "secret": {
            "type": "string",
            "description": "The signing secret (whsec_...). Shown in this answer only."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "spend.threshold",
                "sim.data_cap",
                "sim.roaming",
                "sim.suspended",
                "trunk.asr_drop",
                "invoice.issued",
                "invoice.overdue",
                "porting.updated",
                "incident.opened",
                "alert.rule",
                "iot.attached",
                "iot.detached",
                "iot.authentication",
                "iot.data_limit",
                "iot.cost_alert",
                "iot.sms",
                "iot.sms_status",
                "iot.bulk_job_done",
                "number.watch_changed"
              ]
            },
            "description": "Every event type this webhook receives."
          }
        }
      },
      "WebhookCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "url"
        ],
        "properties": {
          "event": {
            "type": "string",
            "enum": [
              "spend.threshold",
              "sim.data_cap",
              "sim.roaming",
              "sim.suspended",
              "trunk.asr_drop",
              "invoice.issued",
              "invoice.overdue",
              "porting.updated",
              "incident.opened",
              "alert.rule",
              "iot.attached",
              "iot.detached",
              "iot.authentication",
              "iot.data_limit",
              "iot.cost_alert",
              "iot.sms",
              "iot.sms_status",
              "iot.bulk_job_done",
              "number.watch_changed"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "A public HTTPS address."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "spend.threshold",
                "sim.data_cap",
                "sim.roaming",
                "sim.suspended",
                "trunk.asr_drop",
                "invoice.issued",
                "invoice.overdue",
                "porting.updated",
                "incident.opened",
                "alert.rule",
                "iot.attached",
                "iot.detached",
                "iot.authentication",
                "iot.data_limit",
                "iot.cost_alert",
                "iot.sms",
                "iot.sms_status",
                "iot.bulk_job_done",
                "number.watch_changed"
              ]
            },
            "description": "The event types to receive, 1 to 20. Send events, or event for just one."
          }
        },
        "description": "Send events (several types) or event (one type), and url."
      },
      "WebhookUpdate": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "spend.threshold",
                "sim.data_cap",
                "sim.roaming",
                "sim.suspended",
                "trunk.asr_drop",
                "invoice.issued",
                "invoice.overdue",
                "porting.updated",
                "incident.opened",
                "alert.rule",
                "iot.attached",
                "iot.detached",
                "iot.authentication",
                "iot.data_limit",
                "iot.cost_alert",
                "iot.sms",
                "iot.sms_status",
                "iot.bulk_job_done",
                "number.watch_changed"
              ]
            },
            "description": "Replaces the event types this webhook receives."
          }
        }
      },
      "WebhookDeleted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "deleted"
        ],
        "properties": {
          "object": {
            "const": "webhook"
          },
          "id": {
            "type": "string"
          },
          "deleted": {
            "const": true
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "webhook_id",
          "event",
          "test",
          "attempted_at",
          "duration_ms",
          "ok",
          "response_code",
          "response_excerpt",
          "event_id",
          "attempt"
        ],
        "properties": {
          "object": {
            "const": "webhook_delivery"
          },
          "id": {
            "type": "string"
          },
          "webhook_id": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "test": {
            "type": "boolean",
            "description": "true for a test delivery."
          },
          "attempted_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ms": {
            "type": "integer"
          },
          "ok": {
            "type": "boolean",
            "description": "Your endpoint answered 2xx."
          },
          "response_code": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Your endpoint's HTTP status; null when it could not be reached."
          },
          "response_excerpt": {
            "type": [
              "string",
              "null"
            ],
            "description": "The first 200 characters of your answer, or why it could not be delivered."
          },
          "event_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The event delivered (GET /events/{id}); null on test sends and on deliveries before 29 October 2026."
          },
          "attempt": {
            "type": "integer",
            "minimum": 1,
            "description": "1 for the first send, then each retry."
          }
        }
      },
      "IotSimUpdate": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "activated": {
            "type": "boolean",
            "description": "false stops the SIMs connecting; true lets them connect again."
          },
          "data_limit": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "total_bytes",
              "period"
            ],
            "properties": {
              "total_bytes": {
                "type": "integer",
                "minimum": 500000
              },
              "period": {
                "type": "string",
                "enum": [
                  "daily",
                  "monthly"
                ]
              },
              "alert_bytes": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 500000,
                "description": "Below total_bytes."
              }
            }
          },
          "technologies": {
            "type": "object",
            "additionalProperties": false,
            "minProperties": 1,
            "properties": {
              "sms": {
                "type": "boolean"
              },
              "network_2g_3g": {
                "type": "boolean"
              },
              "network_4g": {
                "type": "boolean"
              }
            },
            "description": "Changing these while a device is attached can drop it from the network."
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120,
            "description": "A name for the SIM; null clears it."
          },
          "imei_lock": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9]{14,16}$",
            "description": "Lock the SIM to one device IMEI; null lifts it."
          }
        }
      },
      "IotEsim": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "profile_status",
          "data_as_of"
        ],
        "properties": {
          "object": {
            "const": "iot_esim"
          },
          "sim_id": {
            "type": "string"
          },
          "profile_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "data_as_of": {
            "$ref": "#/components/schemas/DataAsOf"
          }
        }
      },
      "IotSms": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "at",
          "direction",
          "status"
        ],
        "properties": {
          "object": {
            "const": "iot_sms"
          },
          "sim_id": {
            "type": "string"
          },
          "at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "direction": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "from_device",
              "to_device",
              null
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "The delivery status as the IoT network reports it; null when it gave none."
          }
        }
      },
      "IotSimNetworkList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "network_list"
        ],
        "properties": {
          "object": {
            "const": "iot_sim_network_list"
          },
          "sim_id": {
            "type": "string"
          },
          "network_list": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "IotSimNetworkListSet": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "One of your network lists, or null to lift the restriction."
          }
        }
      },
      "IotNetworkList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "name",
          "networks"
        ],
        "properties": {
          "object": {
            "const": "iot_network_list"
          },
          "name": {
            "type": "string"
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "mcc",
                "mnc"
              ],
              "properties": {
                "mcc": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "mnc": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "NumberCancellation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "number_id",
          "phone_number",
          "ends_at",
          "further_charges"
        ],
        "properties": {
          "object": {
            "const": "number_cancellation"
          },
          "number_id": {
            "type": "string"
          },
          "phone_number": {
            "type": "string"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "The number keeps working until then (the end of the month already paid) and is released after it."
          },
          "further_charges": {
            "const": false
          }
        }
      },
      "NumberWatch": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "phone_number",
          "label",
          "products",
          "created_at",
          "last_checked_at",
          "last_change_at",
          "current",
          "currency"
        ],
        "properties": {
          "object": {
            "const": "number_watch"
          },
          "id": {
            "type": "string",
            "description": "nw_ and 32 characters."
          },
          "phone_number": {
            "type": "string"
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dip product codes run at each check (GET /dips/products)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_checked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_change_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "current": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "The number's answer at the last check, by field: validity, ported, serving_network, range_holder, line_status, do_not_originate, high_risk. null before the first check."
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "description": "The balance each check is paid from."
          }
        }
      },
      "NumberWatchCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "number"
        ],
        "properties": {
          "number": {
            "type": "string",
            "description": "International format, 7 to 15 digits, such as +447700900123."
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dip product codes to run at each check; all products on sale when left out."
          },
          "label": {
            "type": "string",
            "maxLength": 80
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Za-z]{3}$",
            "description": "The currency this is paid in: GBP, EUR, USD, JPY, AUD, CAD, CHF, HKD, SGD, INR, AED, KRW or SAR. Paid from your prepaid balance in that currency; left out, your account's own currency. Prices are converted from our USD price list at today's rate. Balances are never converted into one another: a short balance in this currency is 402 insufficient_balance, whatever you hold in others."
          }
        }
      },
      "NumberWatchEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "watch_id",
          "at",
          "changes"
        ],
        "properties": {
          "object": {
            "const": "number_watch_event"
          },
          "watch_id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "changes": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "required": [
                "from",
                "to"
              ],
              "properties": {
                "from": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "to": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            },
            "description": "Each field that changed: validity, ported, serving_network, range_holder, line_status, do_not_originate, high_risk."
          }
        }
      },
      "NumberWatchDeleted": {
        "type": "object",
        "required": [
          "object",
          "id",
          "deleted"
        ],
        "properties": {
          "object": {
            "const": "number_watch"
          },
          "id": {
            "type": "string"
          },
          "deleted": {
            "const": true
          }
        }
      },
      "IotSmsSend": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160,
            "description": "The message, 1 to 160 characters."
          }
        }
      },
      "IotSmsAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "direction",
          "text",
          "status",
          "accepted_at"
        ],
        "properties": {
          "object": {
            "const": "iot_sms"
          },
          "sim_id": {
            "type": "string"
          },
          "direction": {
            "const": "to_device"
          },
          "text": {
            "type": "string"
          },
          "status": {
            "const": "accepted",
            "description": "Accepted by the network. Delivery shows in GET /iot/sims/{id}/sms and the iot.sms_status webhook."
          },
          "accepted_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SimState": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "sim_id",
          "status"
        ],
        "properties": {
          "object": {
            "const": "sim_state"
          },
          "sim_id": {
            "type": "string"
          },
          "status": {
            "enum": [
              "active",
              "suspended"
            ]
          }
        }
      },
      "PortRequestCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "numbers",
          "current_provider",
          "account_reference",
          "authorised_name"
        ],
        "properties": {
          "numbers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
              "type": "string"
            },
            "description": "The numbers to transfer in, international format, such as +442071234567."
          },
          "current_provider": {
            "type": "string",
            "maxLength": 80,
            "description": "The provider the numbers are with now."
          },
          "account_reference": {
            "type": "string",
            "maxLength": 60,
            "description": "Your account number with that provider."
          },
          "authorised_name": {
            "type": "string",
            "maxLength": 80,
            "description": "The person authorised on that account."
          }
        }
      },
      "DipBatchStarted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "total",
          "done",
          "products",
          "state",
          "created_at",
          "finished_at",
          "charge"
        ],
        "properties": {
          "object": {
            "const": "dip_batch"
          },
          "id": {
            "type": "string",
            "pattern": "^dipb_[A-Za-z0-9]+$"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "total": {
            "type": "integer"
          },
          "done": {
            "type": "integer"
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "state": {
            "type": "string",
            "enum": [
              "running",
              "done",
              "failed",
              "unknown"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "charge": {
            "$ref": "#/components/schemas/DecimalMoney"
          }
        }
      },
      "DipBatchCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "numbers"
        ],
        "properties": {
          "numbers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20000,
            "items": {
              "type": "string"
            },
            "description": "1 to 20,000 numbers in international format, such as +447700900123."
          },
          "products": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dip product codes from GET /dips/products; all products on sale when left out."
          },
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Za-z]{3}$",
            "description": "The currency this is paid in: GBP, EUR, USD, JPY, AUD, CAD, CHF, HKD, SGD, INR, AED, KRW or SAR. Paid from your prepaid balance in that currency; left out, your account's own currency. Prices are converted from our USD price list at today's rate. Balances are never converted into one another: a short balance in this currency is 402 insufficient_balance, whatever you hold in others."
          }
        }
      },
      "InvoicePaymentLink": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "invoice_id",
          "url",
          "amount"
        ],
        "properties": {
          "object": {
            "const": "invoice_payment_link"
          },
          "invoice_id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "A secure hosted payment page for the invoice (card, Apple Pay, Google Pay). Card details never pass through VoicePro."
          },
          "amount": {
            "$ref": "#/components/schemas/Money"
          }
        }
      },
      "Event": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "type",
          "occurred_at",
          "data"
        ],
        "properties": {
          "object": {
            "const": "event"
          },
          "id": {
            "type": "string",
            "description": "evt_ and 24 characters; the id field of the webhook body."
          },
          "type": {
            "type": "string",
            "enum": [
              "spend.threshold",
              "sim.data_cap",
              "sim.roaming",
              "sim.suspended",
              "trunk.asr_drop",
              "invoice.issued",
              "invoice.overdue",
              "porting.updated",
              "incident.opened",
              "alert.rule",
              "iot.attached",
              "iot.detached",
              "iot.authentication",
              "iot.data_limit",
              "iot.cost_alert",
              "iot.sms",
              "iot.sms_status",
              "iot.bulk_job_done",
              "number.watch_changed"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "description": "The event's data, exactly as sent to your webhooks."
          }
        }
      },
      "EventResend": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "event_id",
          "webhooks"
        ],
        "properties": {
          "object": {
            "const": "event_resend"
          },
          "event_id": {
            "type": "string"
          },
          "webhooks": {
            "type": "integer",
            "description": "How many webhooks it was sent to."
          }
        }
      },
      "EventResendRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "webhook_id": {
            "type": "string",
            "description": "Send to this webhook only. Left out: every active webhook that receives the event's type."
          }
        }
      },
      "SimCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "plan"
        ],
        "properties": {
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "A name for the line, such as Field ops, Berlin lead."
          },
          "plan": {
            "type": "string",
            "enum": [
              "essentials",
              "elite"
            ],
            "description": "Business+ Essentials or Business+ Elite, at your account's plan prices."
          },
          "add_ons": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "travel_data",
                "premium_number",
                "international_calling"
              ]
            },
            "description": "Monthly add-ons for this line."
          }
        }
      }
    }
  },
  "x-conventions": {
    "paging": "Every list: limit (default 50, maximum 500) and cursor. The cursor is opaque: clients pass back next_cursor unchanged. A malformed cursor is 400 invalid_cursor. Lists are ordered newest first and pages are stable.",
    "freshness": "No read calls a network partner live for each row. Reads come from stored or cached copies, and any response built from them carries data_as_of (ISO 8601 UTC): the time the copy was taken.",
    "fields": "Responses are explicit, documented shapes. They never carry internal ids, partner or supplier names, rate-plan codes or staff-only fields, and never pass a stored record through as it is. Public ids use the type prefixes (acct_, key_, sim_, num_, inv_, dip_, evt_, we_).",
    "scoping": "Every query is limited to the key's own account before anything else; ids from another account answer 404 resource_not_found.",
    "statuses": "Every stored status maps explicitly to a listed value; a status we do not recognise is sent as unknown, never guessed."
  },
  "x-error-codes": {
    "missing_api_key": {
      "type": "authentication",
      "status": 401,
      "description": "No Authorization header, or not a Bearer key."
    },
    "invalid_api_key": {
      "type": "authentication",
      "status": 401,
      "description": "The key is not recognised."
    },
    "api_key_revoked": {
      "type": "authentication",
      "status": 401,
      "description": "The key was revoked in the portal."
    },
    "api_key_expired": {
      "type": "authentication",
      "status": 401,
      "description": "The key passed the expiry date set on it."
    },
    "missing_scope": {
      "type": "permission",
      "status": 403,
      "description": "The key lacks the scope this endpoint needs; param names the scope."
    },
    "ip_not_allowed": {
      "type": "permission",
      "status": 403,
      "description": "The key has an IP allowlist and this request came from elsewhere."
    },
    "account_not_active": {
      "type": "permission",
      "status": 403,
      "description": "The workspace is suspended or closed."
    },
    "invalid_parameter": {
      "type": "invalid_request",
      "status": 400,
      "description": "A query parameter or body field has a bad value; param names it."
    },
    "missing_parameter": {
      "type": "invalid_request",
      "status": 400,
      "description": "A required parameter or field is missing; param names it."
    },
    "unknown_parameter": {
      "type": "invalid_request",
      "status": 400,
      "description": "A parameter or field that this endpoint does not accept; param names it."
    },
    "invalid_json": {
      "type": "invalid_request",
      "status": 400,
      "description": "The body is not valid JSON."
    },
    "invalid_cursor": {
      "type": "invalid_request",
      "status": 400,
      "description": "The cursor is malformed, expired or from a different list."
    },
    "invalid_time_range": {
      "type": "invalid_request",
      "status": 400,
      "description": "from or to is not an ISO 8601 date-time, or to is not after from."
    },
    "range_too_long": {
      "type": "invalid_request",
      "status": 400,
      "description": "The time range is longer than this endpoint allows (stated in the endpoint)."
    },
    "body_too_large": {
      "type": "invalid_request",
      "status": 413,
      "description": "The body is over 1 MiB."
    },
    "method_not_allowed": {
      "type": "invalid_request",
      "status": 405,
      "description": "The path exists but not with this method."
    },
    "route_not_found": {
      "type": "not_found",
      "status": 404,
      "description": "No such path in v3."
    },
    "resource_not_found": {
      "type": "not_found",
      "status": 404,
      "description": "No object with that id on this account."
    },
    "service_not_enabled": {
      "type": "not_found",
      "status": 404,
      "description": "The account does not have this service (voice trunk, IoT, numbers); param names it."
    },
    "idempotency_key_reused": {
      "type": "conflict",
      "status": 409,
      "description": "This Idempotency-Key was used within 24 hours with a different request."
    },
    "idempotency_key_in_use": {
      "type": "conflict",
      "status": 409,
      "description": "A request with this Idempotency-Key is still running, or its outcome at a partner is not yet known (message: outcome pending); retry shortly with the same key. If a charged request never finished, the message says so: check your balance and orders before sending it again with a new key."
    },
    "state_conflict": {
      "type": "conflict",
      "status": 409,
      "description": "The object is not in a state that allows this action (for example resuming an active SIM)."
    },
    "insufficient_balance": {
      "type": "payment_required",
      "status": 402,
      "description": "Prepaid funds or the account's order limit do not cover this charged action (a dip, an SMS or an order)."
    },
    "rate_limited": {
      "type": "rate_limited",
      "status": 429,
      "description": "Too many requests for this key or for the whole account (the message says which); wait Retry-After seconds."
    },
    "upstream_unavailable": {
      "type": "upstream_unavailable",
      "status": 503,
      "description": "A network partner or data service behind this endpoint is unavailable."
    },
    "upstream_timeout": {
      "type": "upstream_unavailable",
      "status": 504,
      "description": "A network partner did not answer in time; the action may not have happened. Retry with the same Idempotency-Key."
    },
    "network_action_unavailable": {
      "type": "upstream_unavailable",
      "status": 503,
      "description": "This network action is not switched on for the account yet (for example SIM suspend)."
    },
    "internal_error": {
      "type": "internal",
      "status": 500,
      "description": "Our fault. Quote the request_id to support."
    },
    "service_unavailable": {
      "type": "upstream_unavailable",
      "status": 503,
      "description": "API v3 itself is briefly unavailable (for example a configuration problem on our side); the rest of VoicePro is unaffected. Retry later."
    },
    "account_locked": {
      "type": "permission",
      "status": 423,
      "description": "The account is locked pending a Trust & Safety review; writes, including charged actions, are refused until it is cleared. Reads still work."
    }
  },
  "x-rate-limits": {
    "default_per_key": "at least 10 requests a second, bursts of 25",
    "default_per_account": "30 requests a second, bursts of 75, shared by all of an account's keys",
    "headers": "RateLimit-* report whichever of the key and account limits has less remaining; a 429 message says which limit was hit",
    "dips": "dips follow partner capacity, currently 10 a second"
  }
}
