{"openapi":"3.1.0","info":{"title":"Virtual PBX API","version":"1.0.0","description":"Hosted virtual PBX for small businesses: signup, phone numbers, call handling, voicemail, recordings, call history, invoices, and support tickets. Money is in US cents, phone numbers in E.164, and timestamps in ISO-8601 UTC. Everything the website does goes through this API, plus Stripe.js calls in the browser to collect cards."},"servers":[{"url":"/","description":"The NGINX gateway: Billing under /v1, every other service under /api/v1."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An `accessToken` from POST /api/v1/auth/login or POST /api/v1/auth/register; every service accepts it. Provider operations use one from POST /api/v1/provider/login."}},"schemas":{"Error":{"type":"object","description":"Accounts, Calling and the gateway answer errors in this shape (503 `service_unavailable` while a service isn't running).","required":["error"],"properties":{"error":{"type":"object","description":"Details of the error.","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code, e.g. `card_invalid` or `payment_failed`."},"message":{"type":"string","description":"Human-readable explanation, safe to show to the user."}}}}},"BillingError":{"type":"object","description":"Billing, Numbers, Tickets, History and Replay answer errors in this shape.","required":["detail"],"properties":{"detail":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}],"description":"A message, or a list of validation problems with `loc`, `msg` and `type`."}}},"Ok":{"type":"object","description":"Confirms the request succeeded.","required":["ok"],"properties":{"ok":{"const":true,"description":"Always true."}}},"Addon":{"type":"object","description":"An add-on's state, from Billing. Buy one with POST /v1/quotes and POST /v1/purchases; remove or keep it with /v1/subscriptions/items.","required":["key","name","enabled","removing","worksUntil","priceCents","priceAvailable"],"properties":{"key":{"type":"string","enum":["international_calling","call_recording"],"description":"Which add-on this is."},"name":{"type":"string","description":"Display name."},"enabled":{"type":"boolean","description":"Whether the add-on works right now."},"removing":{"type":"boolean","description":"True once removed: it keeps working until `worksUntil`, then is not renewed."},"worksUntil":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When a removed add-on stops; null otherwise."},"priceCents":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Price in US cents per 7-day period; null when Billing has no approved price."},"priceAvailable":{"type":"boolean","description":"False when the add-on can't be bought right now."}}},"Account":{"type":"object","description":"The business account. Identity fields come from Accounts; the rest come live from Billing and are null when Billing can't be reached.","required":["id","businessName","timeZone","sipDomain","createdAt","billingAvailable","status","activationState","restriction","canCallOutgoing","canCallInternational","canRecord","planId","includedExtensions","currentPeriodStart","currentPeriodEnd","includedMinutesGranted","includedMinutesUsed","addons"],"properties":{"id":{"type":"string","description":"Account ID, `acct_…`."},"businessName":{"type":"string","description":"Name of the business."},"timeZone":{"type":"string","description":"IANA time zone, fixed after signup. Governs billing periods and business hours."},"sipDomain":{"type":"string","description":"SIP domain that phones register at."},"createdAt":{"type":"string","format":"date-time","description":"When the account signed up."},"billingAvailable":{"type":"boolean","description":"False when Billing couldn't be reached; every field below is then null."},"status":{"anyOf":[{"type":"string","enum":["active","past_due"]},{"type":"null"}],"description":"`past_due` when a renewal is unpaid 24 hours after its period ended; outgoing calls are blocked."},"activationState":{"anyOf":[{"type":"string","enum":["pending","active"]},{"type":"null"}],"description":"`pending` until the base plan is paid; no calling until `active`."},"restriction":{"anyOf":[{"type":"string","enum":["active","blocked"]},{"type":"null"}],"description":"`blocked` when outgoing calls are blocked."},"canCallOutgoing":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Outgoing calls allowed right now."},"canCallInternational":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Calls outside the US allowed; needs the international calling add-on."},"canRecord":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Call recording allowed; needs the call recording add-on."},"planId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Billing product code of the active base plan."},"includedExtensions":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Extensions included in the plan."},"currentPeriodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Start of the current 7-day billing period."},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of the current 7-day billing period."},"includedMinutesGranted":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Shared included US minutes this period."},"includedMinutesUsed":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Included US minutes used so far this period."},"addons":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Addon"}},{"type":"null"}],"description":"The account's add-ons."}}},"User":{"type":"object","description":"A person who can sign in to an account.","required":["id","accountId","email","name","role","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"email":{"type":"string","description":"Email address, used to sign in. Unique across all accounts."},"name":{"type":"string","description":"Full name."},"role":{"type":"string","enum":["admin","user"],"description":"Admins manage users and the account."},"createdAt":{"type":"string","format":"date-time","description":"When the user was added."}}},"SetupIntent":{"type":"object","description":"A SetupIntent for collecting the signup card with Stripe.js.","required":["id","clientSecret","publishableKey"],"properties":{"id":{"type":"string","description":"SetupIntent ID. After the browser confirms it, send it as `setupIntentId` to POST /api/v1/auth/register."},"clientSecret":{"type":"string","description":"The SetupIntent client_secret. Pass to `stripe.confirmCardSetup` in the browser."},"publishableKey":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Gateway publishable key for initializing Stripe.js."}}},"SignupRequest":{"type":"object","description":"A new account and its admin user.","required":["businessName","timeZone","adminName","adminEmail","password","planId","setupIntentId"],"properties":{"businessName":{"type":"string","description":"Name of the business."},"timeZone":{"type":"string","description":"IANA time zone, e.g. America/New_York. Can't be changed later."},"adminName":{"type":"string","description":"Full name of the admin user."},"adminEmail":{"type":"string","description":"Email of the admin user."},"password":{"type":"string","description":"Password of the admin user; at least 8 characters."},"planId":{"type":"string","description":"Billing product code of the base plan: the `code` of a `kind: plan` product in GET /v1/catalog (public), e.g. `plan_standard`."},"setupIntentId":{"type":"string","description":"ID of a SetupIntent from POST /api/v1/signup/setup-intents that the browser confirmed with Stripe.js."}}},"LoginRequest":{"type":"object","description":"Sign-in credentials.","required":["email","password"],"properties":{"email":{"type":"string","description":"Email address."},"password":{"type":"string","description":"Password."}}},"AuthResponse":{"type":"object","description":"A signed-in session.","required":["user","account","accessToken","expiresIn","refreshToken","refreshExpiresIn","tokenType"],"properties":{"user":{"$ref":"#/components/schemas/User","description":"The signed-in user."},"account":{"$ref":"#/components/schemas/Account","description":"The user's account."},"accessToken":{"type":"string","description":"RS256 JWT. Send as `Authorization: Bearer <accessToken>` to Accounts and Billing."},"expiresIn":{"type":"integer","description":"Seconds until the access token expires."},"refreshToken":{"type":"string","description":"Single-use token for POST /api/v1/auth/refresh."},"refreshExpiresIn":{"type":"integer","description":"Seconds until the refresh token expires."},"tokenType":{"const":"Bearer","description":"Always `Bearer`."},"planStatus":{"anyOf":[{"type":"string","enum":["active","pending_payment"]},{"type":"null"}],"description":"Only on registration: `pending_payment` if the plan charge couldn't be confirmed yet."}}},"RefreshRequest":{"type":"object","description":"A refresh token to trade in.","required":["refreshToken"],"properties":{"refreshToken":{"type":"string","description":"Refresh token from a previous sign-in or refresh."}}},"LogoutRequest":{"type":"object","description":"Which session to end.","required":[],"properties":{"refreshToken":{"type":"string","description":"Revoke just this session. Omit to sign out everywhere."}}},"UpdateMeRequest":{"type":"object","description":"Changes to your profile; omitted fields are unchanged.","required":[],"properties":{"name":{"type":"string","description":"New name."},"email":{"type":"string","description":"New login email."}}},"ChangePasswordRequest":{"type":"object","description":"A password change.","required":["currentPassword","newPassword"],"properties":{"currentPassword":{"type":"string","description":"Your current password."},"newPassword":{"type":"string","description":"At least 8 characters."}}},"UpdateAccountRequest":{"type":"object","description":"Changes to the account; omitted fields are unchanged.","required":[],"properties":{"businessName":{"type":"string","description":"New business name."}}},"CreateUserRequest":{"type":"object","description":"A user to add.","required":["name","email","password"],"properties":{"name":{"type":"string","description":"Full name."},"email":{"type":"string","description":"Email address, used to sign in."},"password":{"type":"string","description":"Password; at least 8 characters."},"role":{"type":"string","enum":["admin","user"],"description":"The user's role; defaults to `user`."}}},"UpdateUserRequest":{"type":"object","description":"Changes to a user; omitted fields are unchanged.","required":[],"properties":{"name":{"type":"string","description":"New name."},"role":{"type":"string","enum":["admin","user"],"description":"New role. The account must keep at least one admin."}}},"DestinationExtension":{"type":"object","description":"Ring an extension.","required":["type","extensionId"],"properties":{"type":{"const":"extension","description":"Always \"extension\"."},"extensionId":{"type":"string","description":"ID of the extension."}}},"DestinationRingGroup":{"type":"object","description":"Ring a ring group.","required":["type","ringGroupId"],"properties":{"type":{"const":"ring_group","description":"Always \"ring_group\"."},"ringGroupId":{"type":"string","description":"ID of the ring group."}}},"DestinationIvr":{"type":"object","description":"Play an IVR menu.","required":["type","ivrMenuId"],"properties":{"type":{"const":"ivr","description":"Always \"ivr\"."},"ivrMenuId":{"type":"string","description":"ID of the IVR menu."}}},"DestinationVoicemail":{"type":"object","description":"Go to an extension's voicemail box.","required":["type","extensionId"],"properties":{"type":{"const":"voicemail","description":"Always \"voicemail\"."},"extensionId":{"type":"string","description":"ID of the extension that owns the box."}}},"DestinationExternal":{"type":"object","description":"Connect to an external number. This leg is charged to the account.","required":["type","number"],"properties":{"type":{"const":"external","description":"Always \"external\"."},"number":{"type":"string","description":"E.164 number."}}},"DestinationSchedule":{"type":"object","description":"Apply a business-hours schedule.","required":["type","businessHoursId"],"properties":{"type":{"const":"schedule","description":"Always \"schedule\"."},"businessHoursId":{"type":"string","description":"ID of the schedule."}}},"DestinationRepeat":{"type":"object","description":"Replay the IVR menu. Only valid for an IVR's timeout and invalid-input actions.","required":["type"],"properties":{"type":{"const":"repeat","description":"Always \"repeat\"."}}},"DestinationHangup":{"type":"object","description":"End the call.","required":["type"],"properties":{"type":{"const":"hangup","description":"Always \"hangup\"."}}},"Destination":{"description":"Where a call goes.","oneOf":[{"$ref":"#/components/schemas/DestinationExtension"},{"$ref":"#/components/schemas/DestinationRingGroup"},{"$ref":"#/components/schemas/DestinationIvr"},{"$ref":"#/components/schemas/DestinationVoicemail"},{"$ref":"#/components/schemas/DestinationExternal"},{"$ref":"#/components/schemas/DestinationSchedule"},{"$ref":"#/components/schemas/DestinationRepeat"},{"$ref":"#/components/schemas/DestinationHangup"}],"discriminator":{"propertyName":"type"}},"AvailableNumber":{"type":"object","description":"A number the DID provider can sell. An offer, not a reservation.","required":["number","type","country","region","city","area_code"],"properties":{"number":{"type":"string","description":"E.164 number."},"type":{"type":"string","enum":["local","toll_free"],"description":"Type of number."},"country":{"type":"string","description":"ISO country code; only `US` for now."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code; null for toll-free."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City; null for toll-free."},"area_code":{"type":"string","description":"Area code, or the 8XX prefix for toll-free."}}},"PhoneNumber":{"type":"object","description":"A phone number the account owns.","required":["number","type","country","region","city","area_code","status","destination","paid_until"],"properties":{"number":{"type":"string","description":"E.164 number."},"type":{"type":"string","enum":["local","toll_free"],"description":"Type of number."},"country":{"type":"string","description":"ISO country code; only `US` for now."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code; null for toll-free."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City; null for toll-free."},"area_code":{"type":"string","description":"Area code, or the 8XX prefix for toll-free."},"status":{"type":"string","enum":["pending","active","releasing"],"description":"`pending`: the provider is processing the order. `releasing`: released, works until `paid_until`."},"destination":{"anyOf":[{"$ref":"#/components/schemas/NumberDestination"},{"type":"null"}],"description":"Where its calls go; null while unrouted."},"paid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of the paid period. Null while pending."}}},"NumberDestination":{"type":"object","description":"Where Numbers sends a number's calls; Calling resolves `id` in the account's call handling.","required":["type","id"],"properties":{"type":{"type":"string","enum":["extension","ring_group","ivr","schedule"],"description":"What `id` names."},"id":{"type":"string","description":"ID of the extension, ring group, IVR menu, or business-hours schedule."}}},"NumberReservation":{"type":"object","description":"A found number held for the account while it buys it (about 30 minutes).","required":["number","expires_at"],"properties":{"number":{"type":"string","description":"E.164 number."},"expires_at":{"type":"string","format":"date-time","description":"When the hold ends."}}},"CallerId":{"type":"object","description":"The number shown on the account's outgoing calls.","required":["number","account_id","usable"],"properties":{"number":{"type":"string","description":"E.164 number."},"account_id":{"type":"string","description":"The account."},"usable":{"type":"boolean","description":"False while the chosen number is still pending."}}},"SetCallerIdRequest":{"type":"object","description":"The caller ID to show.","required":["number"],"properties":{"number":{"type":"string","description":"One of the account's numbers, E.164."}}},"CatalogProduct":{"type":"object","description":"A product Billing sells, priced per 7-day period.","required":["product_id","code","kind","catalog_version_id","amount","currency","unit","available","unavailable_reason","product_details","price_details"],"properties":{"product_id":{"type":"string","description":"Product ID, for quotes and purchases."},"code":{"type":"string","description":"Stable code, e.g. `plan_standard` or `call_recording`."},"kind":{"type":"string","enum":["plan","extension","number","addon"],"description":"What kind of product this is."},"catalog_version_id":{"type":"string","description":"Catalog version this price belongs to."},"amount":{"type":"string","description":"Price per `unit`, as a decimal USD string."},"currency":{"type":"string","description":"Always USD."},"unit":{"type":"string","description":"Always `week`."},"available":{"type":"boolean","description":"Unavailable products must not be bought."},"unavailable_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why it's unavailable."},"product_details":{"type":"object","description":"Plans: `included_quantity` (extensions). Numbers: `number_type`. Add-ons: `addon_code`."},"price_details":{"type":"object","description":"Plans: `included_us_seconds`."}}},"CatalogRate":{"type":"object","description":"A per-minute rate for a destination prefix.","required":["kind","prefix","region","destination","amount_per_minute","available","unavailable_reason"],"properties":{"kind":{"type":"string","enum":["us_overage","international","toll_free"],"description":"What the rate applies to."},"prefix":{"type":"string","description":"Destination prefix with +. The longest matching prefix wins."},"region":{"type":"string","description":"Matched when rating: empty, or `US` for incoming toll-free calls."},"destination":{"type":"string","description":"Destination name, e.g. `United Kingdom` or `Canada`."},"amount_per_minute":{"type":"string","description":"Decimal USD per minute."},"available":{"type":"boolean","description":"Whether the rate is in effect."},"unavailable_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why it isn't."}}},"Catalog":{"type":"object","description":"Every approved price.","required":["catalog_version","catalog_version_id","products","rates"],"properties":{"catalog_version":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Catalog version name."},"catalog_version_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Catalog version ID."},"products":{"type":"array","items":{"$ref":"#/components/schemas/CatalogProduct"},"description":"Plans, extensions, numbers and add-ons."},"rates":{"type":"array","items":{"$ref":"#/components/schemas/CatalogRate"},"description":"Per-minute rates."}}},"QuoteRequest":{"type":"object","description":"A product to price.","required":["product_id"],"properties":{"product_id":{"type":"string","description":"From the catalog."},"quantity":{"type":"integer","description":"1 to 100; default 1. Plans, numbers and add-ons must be 1."},"did_e164":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Numbers only: the E.164 number to buy."}}},"Quote":{"type":"object","description":"A point-in-time prorated price. Doesn't reserve or charge anything.","required":["catalog_version","catalog_version_id","product_id","product_code","product_kind","product_details","price_details","quantity","did_e164","period_start","period_end","scheduled_start","fraction","weekly_price_id","weekly_amount","weekly_cents","setup_price_id","setup_amount","setup_cents","total_cents","full_included_us_seconds","included_us_seconds","initial_included_us_seconds","per_unit_included_us_seconds"],"properties":{"catalog_version":{"type":"string","description":"Catalog version name."},"catalog_version_id":{"type":"string","description":"Send this to POST /v1/purchases."},"product_id":{"type":"string","description":"The product."},"product_code":{"type":"string","description":"The product's code."},"product_kind":{"type":"string","description":"The product's kind."},"product_details":{"type":"object","description":"Product details."},"price_details":{"type":"object","description":"Price details."},"quantity":{"type":"integer","description":"Quantity."},"did_e164":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Numbers only."},"period_start":{"type":"string","format":"date-time","description":"Start of the current period."},"period_end":{"type":"string","format":"date-time","description":"End of the current period."},"scheduled_start":{"type":"string","format":"date-time","description":"When the item would start."},"fraction":{"type":"string","description":"Share of the period left."},"weekly_price_id":{"type":"string","description":"Weekly price ID."},"weekly_amount":{"type":"string","description":"Full weekly price, decimal USD."},"weekly_cents":{"type":"integer","description":"Full weekly price in cents."},"setup_price_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Setup price ID, if any."},"setup_amount":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Setup price, if any."},"setup_cents":{"type":"integer","description":"Setup price in cents."},"total_cents":{"type":"integer","description":"What the purchase charges now. Send as `expected_total_cents`."},"full_included_us_seconds":{"type":"integer","description":"Included US seconds for a full period."},"included_us_seconds":{"type":"integer","description":"Included US seconds for the rest of this period."},"initial_included_us_seconds":{"type":"integer","description":"Included US seconds granted now."},"per_unit_included_us_seconds":{"type":"integer","description":"Included US seconds per unit."}}},"PurchaseRequest":{"type":"object","description":"A purchase at a quoted price.","required":["product_id","catalog_version_id","expected_total_cents"],"properties":{"product_id":{"type":"string","description":"From the catalog."},"quantity":{"type":"integer","description":"Same as the quote."},"did_e164":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Numbers only."},"catalog_version_id":{"type":"string","description":"From the quote. A stale version returns 409."},"expected_total_cents":{"type":"integer","description":"The quote's `total_cents`. A changed amount returns 409."}}},"Purchase":{"type":"object","description":"A purchase order.","required":["id","invoice_id","status"],"properties":{"id":{"type":"string","description":"Order ID."},"invoice_id":{"type":"string","description":"The invoice charged for it."},"status":{"type":"string","description":"`pending_payment`, `active`, `canceled`, or a provisioning state for numbers."}}},"PurchaseListItem":{"type":"object","description":"A purchase order with its price snapshot.","required":["id","invoice_id","status","price_snapshot"],"properties":{"id":{"type":"string","description":"Order ID."},"invoice_id":{"type":"string","description":"Invoice ID."},"status":{"type":"string","description":"Order status."},"price_snapshot":{"type":"object","description":"The price it was bought at."}}},"PurchaseStatus":{"type":"object","description":"A purchase order with its invoice and provisioning status.","required":["id","invoice_id","status","price_snapshot","invoice_status","number_status"],"properties":{"id":{"type":"string","description":"Order ID."},"invoice_id":{"type":"string","description":"Invoice ID."},"status":{"type":"string","description":"Order status."},"price_snapshot":{"type":"object","description":"The price it was bought at."},"invoice_status":{"type":"string","description":"The invoice's status."},"number_status":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Numbers only: provisioning state."}}},"SubscriptionItem":{"type":"object","description":"A recurring item.","required":["item_id","product_id","quantity","status","active_from","paid_through","removal_at","entitlement","did_e164"],"properties":{"item_id":{"type":"string","description":"Item ID, for remove and resume."},"product_id":{"type":"string","description":"The product."},"quantity":{"type":"integer","description":"Quantity."},"status":{"type":"string","description":"`pending`, `active`, `removing`, or `removed`."},"active_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it started."},"paid_through":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Paid until this time."},"removal_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When a removed item stops."},"entitlement":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What it enables."},"did_e164":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For a phone number's item, the number it pays for (E.164); null for other products. Remove this item to release the number."}}},"Removal":{"type":"object","description":"A removal or resume result.","required":["item_id","status","removal_at"],"properties":{"item_id":{"type":"string","description":"Item ID."},"status":{"type":"string","description":"New status."},"removal_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it stops; null after resume."}}},"CardSetup":{"type":"object","description":"A SetupIntent for replacing the card with Stripe.js.","required":["setup_intent_id","client_secret","publishable_key"],"properties":{"setup_intent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Send to POST /v1/card/complete after the browser confirms it."},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pass to `stripe.confirmCardSetup` in the browser."},"publishable_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Gateway publishable key for Stripe.js."}}},"CompleteCardRequest":{"type":"object","description":"A confirmed SetupIntent.","required":["setup_intent_id"],"properties":{"setup_intent_id":{"type":"string","description":"ID of a SetupIntent the browser confirmed with Stripe.js."}}},"Card":{"type":"object","description":"The account's card. Card numbers are never available.","required":["id","brand","last4","exp_month","exp_year"],"properties":{"id":{"type":"string","description":"Payment method ID."},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Card brand."},"last4":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Last 4 digits."},"exp_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Expiry month."},"exp_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Expiry year."}}},"BillingDetails":{"type":"object","description":"Name and address shown on invoices.","required":["name","email","address_line1","city","postal_code","country"],"properties":{"name":{"type":"string","description":"Name."},"email":{"type":"string","description":"Billing email."},"company":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company."},"address_line1":{"type":"string","description":"Address."},"address_line2":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Address, second line."},"city":{"type":"string","description":"City."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Region or state."},"postal_code":{"type":"string","description":"Postal code."},"country":{"type":"string","description":"Country code."}}},"InvoiceSummary":{"type":"object","description":"An invoice.","required":["id","kind","status","currency","total_cents","period_id","period_start","period_end","issued_at","due_at","paid_at"],"properties":{"id":{"type":"string","description":"Invoice ID."},"kind":{"type":"string","enum":["purchase","renewal"],"description":"`purchase` is a mid-period charge; `renewal` is the 7-day invoice."},"status":{"type":"string","enum":["draft","open","paid","past_due","void"],"description":"`open` and `past_due` invoices are being retried."},"currency":{"type":"string","description":"Always USD."},"total_cents":{"type":"integer","description":"Total in US cents."},"period_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Billing period it belongs to."},"period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Start of that billing period."},"period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of that billing period."},"issued_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was issued."},"due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was due."},"paid_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was paid; null if unpaid."}}},"InvoiceLine":{"type":"object","description":"One line of an invoice.","required":["id","kind","description","quantity","unit_amount","amount_cents","source_type","source_id","price_snapshot"],"properties":{"id":{"type":"string","description":"Line ID."},"kind":{"type":"string","description":"`recurring`, `setup`, or `usage`."},"description":{"type":"string","description":"What the customer sees."},"quantity":{"type":"string","description":"Quantity, as a decimal string."},"unit_amount":{"type":"string","description":"Price per unit, decimal USD."},"amount_cents":{"type":"integer","description":"Amount in US cents."},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What it bills for."},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ID of what it bills for."},"price_snapshot":{"type":"object","description":"The price used."}}},"InvoiceDetail":{"type":"object","description":"An invoice, itemized.","required":["id","kind","status","currency","total_cents","period_id","period_start","period_end","issued_at","due_at","paid_at","lines","allowance"],"properties":{"id":{"type":"string","description":"Invoice ID."},"kind":{"type":"string","enum":["purchase","renewal"],"description":"Kind."},"status":{"type":"string","enum":["draft","open","paid","past_due","void"],"description":"Status."},"currency":{"type":"string","description":"Always USD."},"total_cents":{"type":"integer","description":"Total in US cents."},"period_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Billing period."},"period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Start of that billing period."},"period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of that billing period."},"issued_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was issued."},"due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was due."},"paid_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was paid."},"lines":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLine"},"description":"Recurring charges, plus usage itemized by call."},"allowance":{"type":"object","description":"Included US allowance: `period_id`, `granted_seconds`, `used_seconds`."}}},"Transaction":{"type":"object","description":"A settled payment.","required":["id","invoice_id","kind","amount_cents","currency","settled_at","gateway_object_id"],"properties":{"id":{"type":"string","description":"Transaction ID."},"invoice_id":{"type":"string","description":"Invoice it paid."},"kind":{"type":"string","description":"Kind."},"amount_cents":{"type":"integer","description":"Amount in US cents."},"currency":{"type":"string","description":"Always USD."},"settled_at":{"type":"string","format":"date-time","description":"When it settled."},"gateway_object_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Gateway reference."}}},"ForwardTargetExtension":{"type":"object","description":"Forward to an extension.","required":["type","extensionId"],"properties":{"type":{"const":"extension","description":"Always \"extension\"."},"extensionId":{"type":"string","description":"ID of the extension."}}},"ForwardTargetExternal":{"type":"object","description":"Forward to an external number. This leg is charged to the account.","required":["type","number"],"properties":{"type":{"const":"external","description":"Always \"external\"."},"number":{"type":"string","description":"E.164 number."}}},"ForwardTarget":{"description":"Where a forwarded call goes.","oneOf":[{"$ref":"#/components/schemas/ForwardTargetExtension"},{"$ref":"#/components/schemas/ForwardTargetExternal"}],"discriminator":{"propertyName":"type"}},"Forwarding":{"type":"object","description":"An extension's forwarding rules.","required":["always","busy","noAnswer","noAnswerSeconds"],"properties":{"always":{"anyOf":[{"$ref":"#/components/schemas/ForwardTarget"},{"type":"null"}],"description":"Forward every call; null to not."},"busy":{"anyOf":[{"$ref":"#/components/schemas/ForwardTarget"},{"type":"null"}],"description":"Forward when busy; null to not."},"noAnswer":{"anyOf":[{"$ref":"#/components/schemas/ForwardTarget"},{"type":"null"}],"description":"Forward on no answer; null to not."},"noAnswerSeconds":{"type":"integer","description":"Seconds to ring before no-answer forwarding."}}},"RegisteredDevice":{"type":"object","description":"A phone registered to an extension.","required":["id","userAgent","transport","codec","srtp","contact","registeredAt","expiresAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"userAgent":{"type":"string","description":"The phone's SIP User-Agent."},"transport":{"type":"string","enum":["udp","tls"],"description":"How it registered."},"codec":{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"],"description":"The codec it supports."},"srtp":{"type":"boolean","description":"True for TLS phones, which use SRTP with SDES."},"contact":{"type":"string","description":"SIP contact URI."},"registeredAt":{"type":"string","format":"date-time","description":"When it registered."},"expiresAt":{"type":"string","format":"date-time","description":"When its registration expires."}}},"Extension":{"type":"object","description":"An extension.","required":["id","accountId","number","name","sipUsername","sipPassword","status","purchaseState","purchaseId","voicemailBox","forwarding","simultaneousRing","userId","devices","presence","billable","removing","worksUntil","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"number":{"type":"string","description":"Number, unique in the account, e.g. 101."},"name":{"type":"string","description":"Display name."},"sipUsername":{"type":"string","description":"SIP username for registering phones."},"sipPassword":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"SIP password for registering phones; null until active, and for non-admins."},"status":{"type":"string","enum":["purchase_pending","pending","active","removing","removed"],"description":"`purchase_pending`: an extra extension awaiting payment; `pending`: its SIP login is being set up."},"purchaseState":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Billing purchase state, or null when included capacity was used."},"purchaseId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Billing purchase ID for an extra extension."},"voicemailBox":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Not reported yet: null."},"forwarding":{"$ref":"#/components/schemas/Forwarding","description":"Forwarding rules."},"simultaneousRing":{"type":"array","items":{"type":"string"},"description":"External numbers that ring with this extension. The first answer wins."},"userId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"User associated with it."},"devices":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/RegisteredDevice"}},{"type":"null"}],"description":"Not reported yet: null."},"presence":{"type":"string","description":"Not reported yet: `unknown`."},"billable":{"type":"boolean","description":"True if beyond the plan's included extensions, so it has a recurring price."},"removing":{"type":"boolean","description":"True once removed: it works until `worksUntil`."},"worksUntil":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When a removed extension stops; null otherwise."},"createdAt":{"type":"string","format":"date-time","description":"When it was created."}}},"AcceptedExtensionPurchase":{"type":"object","description":"An extension quote the admin accepted.","required":["productId","catalogVersionId","expectedTotalCents"],"properties":{"productId":{"type":"string","description":"The extension product, from GET /v1/catalog."},"catalogVersionId":{"type":"string","description":"From the quote."},"expectedTotalCents":{"type":"integer","description":"From the quote; a changed price needs a new quote."}}},"CreateExtensionRequest":{"type":"object","description":"A new extension.","required":["number","name"],"properties":{"number":{"type":"string","description":"Number, unique in the account: 2 to 6 digits."},"name":{"type":"string","description":"Display name."},"forwarding":{"$ref":"#/components/schemas/Forwarding","description":"Forwarding rules; none by default."},"simultaneousRing":{"type":"array","items":{"type":"string"},"description":"External numbers that ring with this extension."},"purchase":{"$ref":"#/components/schemas/AcceptedExtensionPurchase","description":"Only when the plan's extensions are used up (409 `extension_capacity_exhausted`): buy one at this quote."}}},"ExtensionQuoteRequest":{"type":"object","description":"The extension product to price.","required":["productId"],"properties":{"productId":{"type":"string","description":"The extension product, from GET /v1/catalog."}}},"ExtensionQuote":{"type":"object","description":"Billing's price for one more extension.","required":["productId","productCode","catalogVersionId","expectedTotalCents","weeklyCents","setupCents","periodEnd"],"properties":{"productId":{"type":"string","description":"The extension product."},"productCode":{"type":"string","description":"Its code."},"catalogVersionId":{"type":"string","description":"Accept it in `purchase`."},"expectedTotalCents":{"type":"integer","description":"Charged now, prorated to the end of the period."},"weeklyCents":{"type":"integer","description":"Recurring price per 7 days."},"setupCents":{"type":"integer","description":"One-time setup price."},"periodEnd":{"type":"string","format":"date-time","description":"End of the current period."}}},"UpdateExtensionRequest":{"type":"object","description":"Changes to an extension; omitted fields are unchanged.","required":[],"properties":{"number":{"type":"string","description":"New number."},"name":{"type":"string","description":"New display name."},"forwarding":{"$ref":"#/components/schemas/Forwarding","description":"New forwarding rules."},"simultaneousRing":{"type":"array","items":{"type":"string"},"description":"New external numbers to ring."},"regeneratePassword":{"type":"boolean","description":"True generates a new SIP password."}}},"RingGroupMember":{"type":"object","description":"An extension in a ring group.","required":["extensionId","ringSeconds"],"properties":{"extensionId":{"type":"string","description":"ID of the extension."},"ringSeconds":{"type":"integer","description":"For a sequential group, how long this member rings before the next."}}},"RingGroup":{"type":"object","description":"A ring group.","required":["id","accountId","name","strategy","members","timeoutSeconds","noAnswerDestination","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"name":{"type":"string","description":"Name of the ring group."},"strategy":{"type":"string","enum":["simultaneous","sequential"],"description":"`simultaneous` rings everyone at once; `sequential` rings members in order."},"members":{"type":"array","items":{"$ref":"#/components/schemas/RingGroupMember"},"description":"Extensions in the group. For a sequential group, in ringing order."},"timeoutSeconds":{"type":"integer","description":"For a simultaneous group, how many seconds everyone rings."},"noAnswerDestination":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if nobody answers."},"updatedAt":{"type":"string","format":"date-time","description":"When it last changed."}}},"UpsertRingGroupRequest":{"type":"object","description":"A ring group to create or replace.","required":["name","strategy","members","timeoutSeconds","noAnswerDestination"],"properties":{"name":{"type":"string","description":"Name of the ring group."},"strategy":{"type":"string","enum":["simultaneous","sequential"],"description":"`simultaneous` rings everyone at once; `sequential` rings members in order."},"members":{"type":"array","items":{"$ref":"#/components/schemas/RingGroupMember"},"description":"Extensions in the group. For a sequential group, in ringing order."},"timeoutSeconds":{"type":"integer","description":"For a simultaneous group, how many seconds everyone rings."},"noAnswerDestination":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if nobody answers."}}},"BusinessHoursInterval":{"type":"object","description":"A weekly open interval.","required":["day","open","close"],"properties":{"day":{"type":"integer","description":"Day of the week; 0 is Sunday."},"open":{"type":"string","description":"Opening time as HH:MM, in the account's time zone."},"close":{"type":"string","description":"Closing time as HH:MM, in the account's time zone."}}},"BusinessHours":{"type":"object","description":"A business-hours schedule.","required":["id","accountId","name","intervals","openDestination","closedDestination","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"name":{"type":"string","description":"Name of the schedule."},"intervals":{"type":"array","items":{"$ref":"#/components/schemas/BusinessHoursInterval"},"description":"Weekly open intervals, in the account's time zone. A day with none is closed."},"openDestination":{"$ref":"#/components/schemas/Destination","description":"Where calls go while open."},"closedDestination":{"$ref":"#/components/schemas/Destination","description":"Where calls go while closed."},"updatedAt":{"type":"string","format":"date-time","description":"When it last changed."}}},"UpsertBusinessHoursRequest":{"type":"object","description":"A schedule to create or replace.","required":["name","intervals","openDestination","closedDestination"],"properties":{"name":{"type":"string","description":"Name of the schedule."},"intervals":{"type":"array","items":{"$ref":"#/components/schemas/BusinessHoursInterval"},"description":"Weekly open intervals, in the account's time zone. A day with none is closed."},"openDestination":{"$ref":"#/components/schemas/Destination","description":"Where calls go while open."},"closedDestination":{"$ref":"#/components/schemas/Destination","description":"Where calls go while closed."}}},"IvrGreeting":{"type":"object","description":"A menu's uploaded greeting.","required":["fileName","durationSeconds","uploadedAt"],"properties":{"fileName":{"type":"string","description":"Name of the uploaded file."},"durationSeconds":{"type":"number","description":"Length in seconds."},"uploadedAt":{"type":"string","format":"date-time","description":"When it was uploaded."}}},"IvrOption":{"type":"object","description":"A digit in a menu.","required":["digit","label","destination"],"properties":{"digit":{"type":"string","enum":["0","1","2","3","4","5","6","7","8","9","*","#"],"description":"The digit the caller presses."},"label":{"type":"string","description":"Display label."},"destination":{"$ref":"#/components/schemas/Destination","description":"An extension, ring group, menu, voicemail box, or external number."}}},"IvrMenu":{"type":"object","description":"An IVR menu.","required":["id","accountId","name","timeoutSeconds","timeoutAction","invalidInputAction","maxRepeats","options","greeting","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"name":{"type":"string","description":"Name of the menu."},"timeoutSeconds":{"type":"integer","description":"Seconds to wait for a digit before the timeout action."},"timeoutAction":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if the caller presses nothing. May be `repeat`."},"invalidInputAction":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if the caller presses an unassigned digit. May be `repeat`."},"maxRepeats":{"type":"integer","description":"How many times `repeat` replays the menu before hanging up."},"options":{"type":"array","items":{"$ref":"#/components/schemas/IvrOption"},"description":"The digits callers can press."},"greeting":{"anyOf":[{"$ref":"#/components/schemas/IvrGreeting"},{"type":"null"}],"description":"The uploaded greeting; null until one is uploaded."},"updatedAt":{"type":"string","format":"date-time","description":"When it last changed."}}},"UpsertIvrMenuRequest":{"type":"object","description":"A menu to create or replace. Upload its greeting separately.","required":["name","timeoutSeconds","timeoutAction","invalidInputAction","maxRepeats","options"],"properties":{"name":{"type":"string","description":"Name of the menu."},"timeoutSeconds":{"type":"integer","description":"Seconds to wait for a digit before the timeout action."},"timeoutAction":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if the caller presses nothing. May be `repeat`."},"invalidInputAction":{"$ref":"#/components/schemas/Destination","description":"Where the call goes if the caller presses an unassigned digit. May be `repeat`."},"maxRepeats":{"type":"integer","description":"How many times `repeat` replays the menu before hanging up."},"options":{"type":"array","items":{"$ref":"#/components/schemas/IvrOption"},"description":"The digits callers can press."}}},"Recording":{"type":"object","description":"A call recording.","required":["id","account_id","call_id","calling_number","called_number","started_at","duration_ms","complete"],"properties":{"id":{"type":"string","description":"Unique ID."},"account_id":{"type":"string","description":"ID of the owning account."},"call_id":{"type":"string","description":"ID of the recorded call."},"calling_number":{"type":"string","description":"Calling number."},"called_number":{"type":"string","description":"Called number."},"started_at":{"type":"string","format":"date-time","description":"When recording started."},"duration_ms":{"type":"integer","description":"Length in milliseconds."},"complete":{"type":"boolean","description":"False while the call is still being recorded."}}},"VoicemailMessage":{"type":"object","description":"A voicemail message.","required":["id","account_id","call_id","calling_number","called_number","started_at","duration_ms","complete","extension_id","status"],"properties":{"id":{"type":"string","description":"Unique ID."},"account_id":{"type":"string","description":"ID of the owning account."},"call_id":{"type":"string","description":"ID of the call that left it."},"calling_number":{"type":"string","description":"Caller's number."},"called_number":{"type":"string","description":"Number they called."},"started_at":{"type":"string","format":"date-time","description":"When it was left."},"duration_ms":{"type":"integer","description":"Length in milliseconds."},"complete":{"type":"boolean","description":"False while it's still being recorded."},"extension_id":{"type":"string","description":"ID of the extension whose box it's in."},"status":{"type":"string","enum":["new","saved"],"description":"Whether it's new or saved."}}},"UpdateVoicemailRequest":{"type":"object","description":"A message's new status.","required":["status"],"properties":{"status":{"type":"string","enum":["new","saved"],"description":"The new status."}}},"BlockedCaller":{"type":"object","description":"A blocked caller.","required":["id","accountId","number","note","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"number":{"type":"string","description":"E.164 number."},"note":{"type":"string","description":"Why they're blocked."},"createdAt":{"type":"string","format":"date-time","description":"When they were blocked."}}},"CreateBlockedCallerRequest":{"type":"object","description":"A caller to block.","required":["number"],"properties":{"number":{"type":"string","description":"The number to block."},"note":{"type":"string","description":"Why they're being blocked."}}},"TicketSummary":{"type":"object","description":"A support ticket in a list.","required":["id","title","status","account_id","created_at"],"properties":{"id":{"type":"string","description":"Unique ID."},"title":{"type":"string","description":"Title."},"status":{"type":"string","enum":["open","closed"],"description":"Whether it's open or closed."},"account_id":{"type":"string","description":"ID of the account it came from."},"created_at":{"type":"string","format":"date-time","description":"When it was opened."}}},"TicketReply":{"type":"object","description":"A reply on a ticket.","required":["user_id","text"],"properties":{"user_id":{"type":"string","description":"Who wrote it: a user of the account, or provider staff."},"text":{"type":"string","description":"The reply."}}},"Ticket":{"type":"object","description":"A support ticket with its replies.","required":["id","title","status","account_id","created_at","user_id","description","closed_at","replies"],"properties":{"id":{"type":"string","description":"Unique ID."},"title":{"type":"string","description":"Title."},"status":{"type":"string","enum":["open","closed"],"description":"Whether it's open or closed."},"account_id":{"type":"string","description":"ID of the account it came from."},"created_at":{"type":"string","format":"date-time","description":"When it was opened."},"user_id":{"type":"string","description":"ID of the user who opened it."},"description":{"type":"string","description":"Description."},"closed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was closed; null if open."},"replies":{"type":"array","items":{"$ref":"#/components/schemas/TicketReply"},"description":"Replies, oldest first."}}},"CreateTicketRequest":{"type":"object","description":"A new support ticket.","required":["title","description"],"properties":{"title":{"type":"string","description":"Title."},"description":{"type":"string","description":"Description."}}},"CreateTicketReplyRequest":{"type":"object","description":"A reply to add.","required":["text"],"properties":{"text":{"type":"string","description":"The reply."}}},"ProviderTicket":{"type":"object","description":"An open support ticket in the provider's queue.","required":["id","title","status","account_id","created_at"],"properties":{"id":{"type":"string","description":"Unique ID."},"title":{"type":"string","description":"Title."},"status":{"type":"string","enum":["open","closed"],"description":"Always open here."},"account_id":{"type":"string","description":"ID of the account it came from."},"created_at":{"type":"string","format":"date-time","description":"When it was opened."}}},"ProviderLoginResponse":{"type":"object","description":"A provider session.","required":["accessToken","email","expiresIn"],"properties":{"accessToken":{"type":"string","description":"Send as `Authorization: Bearer <accessToken>` to provider operations."},"email":{"type":"string","description":"The provider staff member's email."},"expiresIn":{"type":"integer","description":"Seconds until the token expires."}}},"LiveCall":{"type":"object","description":"A call in progress.","required":["id","accountId","direction","from","to","did","fromExtensionId","ringingExtensionIds","ringingExternalNumbers","answeredExtensionId","state","codec","elapsedSeconds","path","voicemailPrompt","consultForCallId"],"properties":{"id":{"type":"string","description":"Unique ID."},"accountId":{"type":"string","description":"ID of the owning account."},"direction":{"type":"string","enum":["incoming","outgoing","internal"],"description":"Direction of the call."},"from":{"type":"string","description":"Calling number or extension."},"to":{"type":"string","description":"Called number or extension."},"did":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The account's number the call came in on or presents as caller ID."},"fromExtensionId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Extension placing the call, for outgoing and internal calls."},"ringingExtensionIds":{"type":"array","items":{"type":"string"},"description":"Extensions ringing now."},"ringingExternalNumbers":{"type":"array","items":{"type":"string"},"description":"External numbers ringing with them."},"answeredExtensionId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Extension talking on the call."},"state":{"type":"string","enum":["ringing","active","on-hold"],"description":"State of the call."},"codec":{"anyOf":[{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"]},{"type":"null"}],"description":"Not reported yet: null."},"elapsedSeconds":{"type":"integer","description":"Seconds since the call started."},"path":{"type":"array","items":{"type":"string"},"description":"Path through routing so far."},"voicemailPrompt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For a call to *98, what the voicemail system is saying now."},"consultForCallId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For an attended transfer, the held call this one consults about."}}},"CallAction":{"type":"object","description":"What to do to a live call.","required":["action"],"properties":{"action":{"type":"string","enum":["answer","answer_external","reject","hold","resume","hangup","forward","transfer","transfer_complete","dtmf"],"description":"`answer` and `answer_external` make only that extension or number ring (a person still picks up). `transfer_complete` is sent on the held call; `hangup` on the consult call ends the consultation."},"extensionId":{"type":"string","description":"For `answer`, the extension to ring (required). For `reject`, the extension declining; omit to reject the call."},"number":{"type":"string","description":"For `answer_external`, the number to ring."},"to":{"type":"string","description":"For `forward` and `transfer`, the extension or number to send the call to."},"type":{"type":"string","enum":["blind","attended"],"description":"For `transfer`: `blind` hands off immediately; `attended` holds the call and calls the target."},"digit":{"type":"string","enum":["0","1","2","3","4","5","6","7","8","9","*","#"],"description":"For `dtmf`, the digit to send."}}},"CallActionResponse":{"type":"object","description":"The result of a call action.","required":["call","consultCall"],"properties":{"call":{"anyOf":[{"$ref":"#/components/schemas/LiveCall"},{"type":"null"}],"description":"The call after the action; null if it ended."},"consultCall":{"anyOf":[{"$ref":"#/components/schemas/LiveCall"},{"type":"null"}],"description":"For an attended transfer, the new call to the target."}}},"DialRequest":{"type":"object","description":"A call to place.","required":["extensionId","to"],"properties":{"extensionId":{"type":"string","description":"ID of the extension placing the call. Its phones (or web phone) ring first."},"to":{"type":"string","description":"10 digits, 1 + 10 digits, E.164 (+), 011 + number, another extension's number, or *98."}}},"IceServer":{"type":"object","description":"A STUN/TURN server for the browser's RTCPeerConnection.","required":["urls"],"properties":{"urls":{"type":"array","items":{"type":"string"},"description":"Server URLs, e.g. `turn:pbx.example:3478`."},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"TURN username."},"credential":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"TURN password."}}},"RegisterWebPhoneRequest":{"type":"object","description":"A browser to register as a web phone.","required":["extensionId"],"properties":{"extensionId":{"type":"string","description":"Extension it rings for and calls as."},"deviceId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Keep this web phone from an earlier registration."}}},"WebPhone":{"type":"object","description":"A registered web phone.","required":["deviceId","extensionId","expiresInSeconds","iceServers"],"properties":{"deviceId":{"type":"string","description":"Its ID. Poll its calls to stay registered."},"extensionId":{"type":"string","description":"Extension it rings for and calls as."},"expiresInSeconds":{"type":"integer","description":"How long it stays registered without polling."},"iceServers":{"type":"array","items":{"$ref":"#/components/schemas/IceServer"},"description":"STUN/TURN servers for WebRTC."}}},"WebCall":{"type":"object","description":"A web phone's call.","required":["id","callId","direction","state","peer","offer","answer","status"],"properties":{"id":{"type":"string","description":"The browser's leg (`web:…`): answer, reject or hang up with it."},"callId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The live call, for hold, transfer and keys."},"direction":{"type":"string","enum":["incoming","outgoing"],"description":"Ringing the browser, or placed from it."},"state":{"type":"string","enum":["ringing","answered","ended"],"description":"Ringing, answered, or ended."},"peer":{"type":"string","description":"The caller's number, or the number dialed."},"offer":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Incoming: the PBX's WebRTC offer."},"answer":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Outgoing: the PBX's WebRTC answer once answered."},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"180 while the far end rings; 486, 480, 403… when it failed."}}},"WebSdpRequest":{"type":"object","description":"The browser's WebRTC SDP.","required":["sdp"],"properties":{"sdp":{"type":"string","description":"Complete SDP, after ICE gathering (no trickle)."}}},"WebDialRequest":{"type":"object","description":"A call from the web phone.","required":["to","sdp"],"properties":{"to":{"type":"string","description":"10 digits, 1 + 10 digits, E.164, 011 + number, an extension, or *98."},"sdp":{"type":"string","description":"The browser's complete WebRTC offer."}}},"CallRecord":{"type":"object","description":"A call detail record. Charges come from Billing once it has rated the call.","required":["id","account_id","direction","calling_number","called_number","did","extensions","path","status","outcome","codec","vendor","start_time","answer_time","end_time","recording_id","billable_seconds","charge_cents","cost_cents","included_seconds","rate_description"],"properties":{"id":{"type":"string","description":"Unique ID."},"account_id":{"type":"string","description":"ID of the owning account."},"direction":{"type":"string","enum":["incoming","outgoing","internal"],"description":"Direction of the call."},"calling_number":{"type":"string","description":"Calling number or extension."},"called_number":{"type":"string","description":"Called number or extension."},"did":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The account's number involved, if any."},"extensions":{"type":"array","items":{"type":"string"},"description":"Extension numbers on the call."},"path":{"type":"array","items":{"type":"string"},"description":"Path through routing."},"status":{"type":"string","enum":["active","ended","interrupted"],"description":"`active` while it runs; `interrupted` if its media server stopped."},"outcome":{"anyOf":[{"type":"string","enum":["answered","busy","no_answer","failed","blocked"]},{"type":"null"}],"description":"How the call ended; null while active."},"codec":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Negotiated codec, if answered."},"vendor":{"anyOf":[{"type":"string","enum":["us","international"]},{"type":"null"}],"description":"PSTN vendor for outgoing calls; null otherwise."},"start_time":{"type":"string","format":"date-time","description":"When the call started."},"answer_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it was answered; null if it wasn't."},"end_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it ended; null while active."},"recording_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ID of the recording, if any."},"billable_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Answered time after 30/6 rounding; null while active."},"charge_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"What the account is billed, in US cents; null until Billing rates it."},"cost_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"What the PSTN vendor charges, in US cents; null when unknown."},"included_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Billable seconds covered by included US minutes."},"rate_description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The rate used, e.g. `International (+44)`."}}},"CallRecordPage":{"type":"object","description":"A page of call records.","required":["items","next_cursor","limit"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CallRecord"},"description":"Call records, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pass as `cursor` for the next page; null on the last page."},"limit":{"type":"integer","description":"The page size used."}}},"CallStats":{"type":"object","description":"Call totals for the current billing period; null when the period can't be read.","required":["calls_this_period","answered_rate","avg_duration_seconds","active_calls","period_start","period_end"],"properties":{"calls_this_period":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Number of calls."},"answered_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Fraction answered, from 0 to 1."},"avg_duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Average answered call length."},"active_calls":{"type":"integer","description":"Calls in progress now."},"period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Start of the billing period."},"period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of the billing period."}}},"PhoneSettings":{"type":"object","description":"Account-wide phone settings.","required":["codecPriority","enabledCodecs","holdMusic","callerIdNumberId"],"properties":{"codecPriority":{"type":"array","items":{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"]},"description":"Codecs in order of preference."},"enabledCodecs":{"type":"array","items":{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"]},"description":"Codecs preferred when offering; calls between any two supported codecs still work."},"holdMusic":{"type":"string","description":"What held callers hear."},"callerIdNumberId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Always null: the caller ID is set with PUT /api/v1/numbers/caller-id."}}},"UpdatePhoneSettingsRequest":{"type":"object","description":"Changes to phone settings; omitted fields are unchanged.","required":[],"properties":{"codecPriority":{"type":"array","items":{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"]},"description":"Codecs in order of preference."},"enabledCodecs":{"type":"array","items":{"type":"string","enum":["PCMU","PCMA","G729","G723","OPUS"]},"description":"Codecs preferred when offering."},"holdMusic":{"type":"string","description":"What held callers hear."},"callerIdNumberId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Ignored: set the caller ID with PUT /api/v1/numbers/caller-id."}}}}},"paths":{"/api/v1/signup/setup-intents":{"post":{"operationId":"signupSetupIntent","tags":["accounts"],"summary":"Step 1 of signup.","description":"Step 1 of signup. Returns a SetupIntent client_secret (`clientSecret`) and the gateway's `publishableKey` for Stripe.js: call `stripe.confirmCardSetup(clientSecret, ...)` in the browser, then pass the `id` to POST /api/v1/auth/register. Card numbers never reach this API. The same card may be used for any number of accounts.","responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupIntent"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/register":{"post":{"operationId":"authRegister","tags":["accounts"],"summary":"Step 2 of signup.","description":"Step 2 of signup. Creates the account and its admin user, saves the confirmed card through Billing, buys the plan `planId` (charged now, prorated to the end of the first 7-day period), and signs the admin in. If the charge is declined, nothing is created (402 `payment_failed`). The time zone is fixed after signup.","requestBody":{"required":true,"description":"A new account and its admin user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/login":{"post":{"operationId":"authLogin","tags":["accounts"],"summary":"Exchange an email and password for an access token (24 hours) and a refresh token.","description":"Exchange an email and password for an access token (24 hours) and a refresh token.","requestBody":{"required":true,"description":"Sign-in credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/refresh":{"post":{"operationId":"authRefresh","tags":["accounts"],"summary":"Trade a refresh token for a new access token and a new refresh token.","description":"Trade a refresh token for a new access token and a new refresh token. The old refresh token stops working; reusing one signs the user out everywhere.","requestBody":{"required":true,"description":"A refresh token to trade in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/logout":{"post":{"operationId":"authLogout","tags":["accounts"],"summary":"Revoke the given refresh token, or every refresh token for this user if none is given.","description":"Revoke the given refresh token, or every refresh token for this user if none is given. Access tokens stay valid until they expire, so discard yours.","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"description":"Which session to end.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/me":{"get":{"operationId":"authMe","tags":["accounts"],"summary":"Return the signed-in user.","description":"Return the signed-in user.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"authUpdateMe","tags":["accounts"],"summary":"Change your own name or email.","description":"Change your own name or email.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"Changes to your profile; omitted fields are unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMeRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/me/password":{"post":{"operationId":"authChangePassword","tags":["accounts"],"summary":"Change your password.","description":"Change your password. Signs out every other session.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A password change.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/account":{"get":{"operationId":"accountGet","tags":["accounts"],"summary":"Return the account.","description":"Return the account. Billing fields (status, plan, current period, included minutes, calling permissions, add-ons) come live from Billing and are null when Billing can't be reached (`billingAvailable: false`).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"accountUpdate","tags":["accounts"],"summary":"Change the business name.","description":"Change the business name. Admins only. The time zone can't be changed.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"Changes to the account; omitted fields are unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/users":{"get":{"operationId":"usersList","tags":["accounts"],"summary":"List the account's users, oldest first.","description":"List the account's users, oldest first.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/User"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"usersCreate","tags":["accounts"],"summary":"Add a user to the account.","description":"Add a user to the account. Admins only.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A user to add.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/users/{id}":{"get":{"operationId":"usersGet","tags":["accounts"],"summary":"Return one user in the account.","description":"Return one user in the account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"usersUpdate","tags":["accounts"],"summary":"Change a user's name or role.","description":"Change a user's name or role. Admins only. The account must keep at least one admin.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Changes to a user; omitted fields are unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"usersDelete","tags":["accounts"],"summary":"Remove a user from the account and sign them out.","description":"Remove a user from the account and sign them out. Admins only. You can't remove yourself.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/numbers":{"get":{"operationId":"numbersList","tags":["numbers"],"summary":"List the account's phone numbers, sorted, including `releasing` ones and `pending` orders: a number bought through Billing (POST /v1/purchases with `did_e164`) is listed as `pending` right away, until the provider has set it up.","description":"List the account's phone numbers, sorted, including `releasing` ones and `pending` orders: a number bought through Billing (POST /v1/purchases with `did_e164`) is listed as `pending` right away, until the provider has set it up.","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 1000; default 100.","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"How many to skip; default 0.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PhoneNumber"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/numbers/available":{"get":{"operationId":"numbersSearch","tags":["numbers"],"summary":"Search the DID provider for numbers to buy: type, country (US only), two-letter state code, city, area code.","description":"Search the DID provider for numbers to buy: type, country (US only), two-letter state code, city, area code. Offers, not reservations. Prices are in GET /v1/catalog; buy with POST /v1/quotes then POST /v1/purchases with `did_e164`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"type","in":"query","required":false,"description":"Type of number; default `local`.","schema":{"type":"string","enum":["local","toll_free"]}},{"name":"country","in":"query","required":false,"description":"ISO country code; only `US` for now (the default).","schema":{"type":"string"}},{"name":"region","in":"query","required":false,"description":"Two-letter state code, e.g. `NY`. Ignored for toll-free.","schema":{"type":"string"}},{"name":"city","in":"query","required":false,"description":"City, case-insensitive. Ignored for toll-free.","schema":{"type":"string"}},{"name":"area_code","in":"query","required":false,"description":"Three-digit area code, or the 8XX prefix for toll-free.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Most results to return, 1 to 50; default 5.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailableNumber"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/numbers/{number}":{"get":{"operationId":"numbersGet","tags":["numbers"],"summary":"One of the account's numbers, re-checked with the provider while its order is pending.","description":"One of the account's numbers, re-checked with the provider while its order is pending. A number just bought through Billing is returned as `pending` right away.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"The E.164 number, e.g. `+16315550142`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumber"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/numbers/{number}/reservation":{"post":{"operationId":"numbersReserve","tags":["numbers"],"summary":"Hold a found number for about 30 minutes while the account buys it through Billing; nobody else can buy it meanwhile.","description":"Hold a found number for about 30 minutes while the account buys it through Billing; nobody else can buy it meanwhile. One hold per account: a new one releases the last. 404 when it's no longer for sale.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"The E.164 number, e.g. `+16315550142`.","schema":{"type":"string"}}],"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberReservation"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/numbers/{number}/destination":{"put":{"operationId":"numbersSetDestination","tags":["numbers"],"summary":"Set where calls to a number go: an extension, ring group, IVR menu, or business-hours schedule (`{type, id}`).","description":"Set where calls to a number go: an extension, ring group, IVR menu, or business-hours schedule (`{type, id}`). Works while the number is pending.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"The E.164 number, e.g. `+16315550142`.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Where Numbers sends a number's calls; Calling resolves `id` in the account's call handling.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberDestination"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumber"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"delete":{"operationId":"numbersClearDestination","tags":["numbers"],"summary":"Unroute a number: its calls go nowhere.","description":"Unroute a number: its calls go nowhere.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"The E.164 number, e.g. `+16315550142`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumber"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/numbers/caller-id":{"get":{"operationId":"numbersCallerId","tags":["numbers"],"summary":"The number shown on outgoing calls: the chosen one while usable, else the account's first usable number.","description":"The number shown on outgoing calls: the chosen one while usable, else the account's first usable number. 404 when the account has none.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallerId"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"put":{"operationId":"numbersSetCallerId","tags":["numbers"],"summary":"Choose which of the account's numbers outgoing calls show.","description":"Choose which of the account's numbers outgoing calls show. It applies once the number is usable.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"The caller ID to show.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCallerIdRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallerId"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/catalog":{"get":{"operationId":"billingCatalog","tags":["billing"],"summary":"Every approved price, no sign-in needed: products (plans, extension, numbers, add-ons) per 7-day period, and per-minute rates by destination prefix (US, international, incoming toll-free) with the destination's name.","description":"Every approved price, no sign-in needed: products (plans, extension, numbers, add-ons) per 7-day period, and per-minute rates by destination prefix (US, international, incoming toll-free) with the destination's name. The plans (`kind: plan`) are the valid `planId` values for signup, e.g. `plan_standard`. Unavailable entries stay listed with `available: false` and must not be bought.","responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/quotes":{"post":{"operationId":"billingQuote","tags":["billing"],"summary":"Price a product now: prorated to the end of the current period, with its included allowance.","description":"Price a product now: prorated to the end of the current period, with its included allowance. Doesn't reserve or charge anything.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A product to price.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/purchases":{"post":{"operationId":"billingPurchase","tags":["billing"],"summary":"Buy a product at a quoted price, charged to the account's card now.","description":"Buy a product at a quoted price, charged to the account's card now. Admins only. Send the quote's `catalog_version_id` and `total_cents`; a stale quote returns 409. The item activates once payment (and, for numbers, provisioning) succeeds.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per operation; retrying with the same key never charges twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A purchase at a quoted price.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Purchase"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"get":{"operationId":"billingPurchases","tags":["billing"],"summary":"List the account's purchase orders, newest first.","description":"List the account's purchase orders, newest first.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseListItem"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/purchases/{id}":{"get":{"operationId":"billingPurchaseStatus","tags":["billing"],"summary":"One purchase order with its invoice status and, for numbers, provisioning status.","description":"One purchase order with its invoice status and, for numbers, provisioning status.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseStatus"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/subscriptions":{"get":{"operationId":"billingSubscriptions","tags":["billing"],"summary":"The account's recurring items (plan, extensions, numbers, add-ons) with paid-through and removal times.","description":"The account's recurring items (plan, extensions, numbers, add-ons) with paid-through and removal times. A number's item names the number in `did_e164`: to release a number, find its item here, then POST /v1/subscriptions/items/{id}/remove.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionItem"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/subscriptions/items/{id}/remove":{"post":{"operationId":"billingRemoveItem","tags":["billing"],"summary":"Remove a recurring item.","description":"Remove a recurring item. Admins only. It keeps working until its paid period ends and is not renewed. This is also how a number is released: remove the item whose `did_e164` is the number (GET /v1/subscriptions).","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"`item_id` from GET /v1/subscriptions.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Removal"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/subscriptions/items/{id}/resume":{"post":{"operationId":"billingResumeItem","tags":["billing"],"summary":"Keep a removed add-on before its paid period ends, at no charge.","description":"Keep a removed add-on before its paid period ends, at no charge. Admins only.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"`item_id` from GET /v1/subscriptions.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Removal"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/card/setup":{"post":{"operationId":"billingCardSetup","tags":["billing"],"summary":"Start replacing the account's card.","description":"Start replacing the account's card. Admins only. Returns a SetupIntent `client_secret` for Stripe.js: call `stripe.confirmCardSetup(client_secret, ...)` in the browser, then send `setup_intent_id` to POST /v1/card/complete.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per operation; retrying with the same key never charges twice.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardSetup"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/card/complete":{"post":{"operationId":"billingCardComplete","tags":["billing"],"summary":"Make the card from a confirmed SetupIntent the account's card.","description":"Make the card from a confirmed SetupIntent the account's card. Admins only. Overdue invoices are retried on it right away.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A confirmed SetupIntent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteCardRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Card"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/card/default":{"get":{"operationId":"billingCard","tags":["billing"],"summary":"The account's card: brand, last 4 digits and expiry, or null.","description":"The account's card: brand, last 4 digits and expiry, or null.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/Card"},{"type":"null"}]}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/billing-details":{"get":{"operationId":"billingDetails","tags":["billing"],"summary":"The name and address shown on invoices, or null.","description":"The name and address shown on invoices, or null.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BillingDetails"},{"type":"null"}]}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"put":{"operationId":"billingUpdateDetails","tags":["billing"],"summary":"Replace the name and address shown on invoices.","description":"Replace the name and address shown on invoices. Admins only.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"Name and address shown on invoices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingDetails"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingDetails"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/invoices":{"get":{"operationId":"billingInvoices","tags":["billing"],"summary":"List invoices, newest first.","description":"List invoices, newest first.","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100; default 25.","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"How many to skip; default 0.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceSummary"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/invoices/{id}":{"get":{"operationId":"billingInvoice","tags":["billing"],"summary":"One invoice, itemized, with the included US allowance used.","description":"One invoice, itemized, with the included US allowance used.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetail"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/v1/transactions":{"get":{"operationId":"billingTransactions","tags":["billing"],"summary":"List settled payments, newest first.","description":"List settled payments, newest first.","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100; default 25.","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"How many to skip; default 0.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/extensions":{"get":{"operationId":"extensionsList","tags":["extensions"],"summary":"List extensions with their SIP username and password, forwarding and simultaneous-ring numbers.","description":"List extensions with their SIP username and password, forwarding and simultaneous-ring numbers. Admins only.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Extension"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"extensionsCreate","tags":["extensions"],"summary":"Create an extension; SIP credentials are generated and returned.","description":"Create an extension; SIP credentials are generated and returned. When the plan's extensions are used up it fails with 409 `extension_capacity_exhausted`: get a quote and send it back as `purchase` to buy one. Replay the same body and Idempotency-Key to finish a pending purchase.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per operation; retrying with the same key never charges twice.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A new extension.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExtensionRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/extensions/quote":{"post":{"operationId":"extensionsQuote","tags":["extensions"],"summary":"Price one more extension now (prorated) and per week, without charging.","description":"Price one more extension now (prorated) and per week, without charging. Accept it in `extensions.create`'s `purchase`.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"The extension product to price.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionQuoteRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionQuote"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/extensions/{id}":{"patch":{"operationId":"extensionsUpdate","tags":["extensions"],"summary":"Update an extension's number, name, forwarding, or simultaneous-ring numbers, or generate a new SIP password.","description":"Update an extension's number, name, forwarding, or simultaneous-ring numbers, or generate a new SIP password.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Changes to an extension; omitted fields are unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateExtensionRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"extensionsDelete","tags":["extensions"],"summary":"Remove an included extension.","description":"Remove an included extension. It works until the paid period ends.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ring-groups":{"get":{"operationId":"ringGroupsList","tags":["call-handling"],"summary":"List the account's ring groups.","description":"List the account's ring groups.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RingGroup"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"ringGroupsCreate","tags":["call-handling"],"summary":"Create a ring group.","description":"Create a ring group.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A ring group to create or replace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertRingGroupRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RingGroup"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ring-groups/{id}":{"put":{"operationId":"ringGroupsUpdate","tags":["call-handling"],"summary":"Replace a ring group.","description":"Replace a ring group.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A ring group to create or replace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertRingGroupRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RingGroup"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"ringGroupsDelete","tags":["call-handling"],"summary":"Delete a ring group.","description":"Delete a ring group. Numbers routed to it become unrouted, and other destinations pointing to it hang up.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/business-hours":{"get":{"operationId":"hoursList","tags":["call-handling"],"summary":"List the account's business-hours schedules.","description":"List the account's business-hours schedules.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BusinessHours"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"hoursCreate","tags":["call-handling"],"summary":"Create a business-hours schedule.","description":"Create a business-hours schedule.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A schedule to create or replace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertBusinessHoursRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHours"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/business-hours/{id}":{"put":{"operationId":"hoursUpdate","tags":["call-handling"],"summary":"Replace a business-hours schedule.","description":"Replace a business-hours schedule.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A schedule to create or replace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertBusinessHoursRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHours"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"hoursDelete","tags":["call-handling"],"summary":"Delete a business-hours schedule.","description":"Delete a business-hours schedule. Numbers routed to it become unrouted, and other destinations pointing to it hang up.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ivr/menus":{"get":{"operationId":"ivrList","tags":["call-handling"],"summary":"List the account's IVR menus.","description":"List the account's IVR menus.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IvrMenu"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"ivrCreate","tags":["call-handling"],"summary":"Create a IVR menu.","description":"Create a IVR menu.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A menu to create or replace. Upload its greeting separately.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertIvrMenuRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IvrMenu"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ivr/menus/{id}":{"put":{"operationId":"ivrUpdate","tags":["call-handling"],"summary":"Replace a IVR menu.","description":"Replace a IVR menu.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A menu to create or replace. Upload its greeting separately.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertIvrMenuRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IvrMenu"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"ivrDelete","tags":["call-handling"],"summary":"Delete a IVR menu.","description":"Delete a IVR menu. Numbers routed to it become unrouted, and other destinations pointing to it hang up.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ivr/menus/{id}/greeting":{"put":{"operationId":"ivrUploadGreeting","tags":["call-handling"],"summary":"Upload a menu's greeting.","description":"Upload a menu's greeting. The request body is a WAV file: 16-bit PCM, mono, 8 kHz. Other formats are rejected with 400.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}},{"name":"fileName","in":"query","required":false,"description":"Name of the uploaded file.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A WAV file: 16-bit PCM, mono, 8 kHz.","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"The WAV file's bytes."}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IvrMenu"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"ivrGreetingAudio","tags":["call-handling"],"summary":"Download a menu's greeting as WAV (16-bit PCM mono, 8 kHz).","description":"Download a menu's greeting as WAV (16-bit PCM mono, 8 kHz).","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"WAV audio: 16-bit PCM, mono, 8 kHz."}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/blocklist":{"get":{"operationId":"blocklistList","tags":["call-handling"],"summary":"List blocked callers.","description":"List blocked callers.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlockedCaller"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"blocklistCreate","tags":["call-handling"],"summary":"Block a caller.","description":"Block a caller. Their calls are rejected and recorded with outcome `blocked`.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A caller to block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlockedCallerRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockedCaller"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/blocklist/{id}":{"delete":{"operationId":"blocklistDelete","tags":["call-handling"],"summary":"Unblock a caller.","description":"Unblock a caller.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/voicemail/messages":{"get":{"operationId":"voicemailList","tags":["voicemail"],"summary":"List voicemail messages, newest first, optionally for one extension or status.","description":"List voicemail messages, newest first, optionally for one extension or status. Changes made by dialing *98 show here.","security":[{"bearerAuth":[]}],"parameters":[{"name":"extension_id","in":"query","required":false,"description":"Only this extension's box.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Only messages with this status.","schema":{"type":"string","enum":["new","saved"]}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VoicemailMessage"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/voicemail/messages/{id}":{"patch":{"operationId":"voicemailUpdate","tags":["voicemail"],"summary":"Mark a message new or saved.","description":"Mark a message new or saved. The change also shows when dialing *98.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A message's new status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVoicemailRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoicemailMessage"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"delete":{"operationId":"voicemailDelete","tags":["voicemail"],"summary":"Delete a message.","description":"Delete a message. The change also shows when dialing *98.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/voicemail/messages/{id}/audio":{"get":{"operationId":"voicemailAudio","tags":["voicemail"],"summary":"Download a message as WAV (16-bit PCM mono, 8 kHz).","description":"Download a message as WAV (16-bit PCM mono, 8 kHz).","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"WAV audio: 16-bit PCM, mono, 8 kHz."}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/recordings":{"get":{"operationId":"recordingsList","tags":["recordings"],"summary":"List call recordings, newest first.","description":"List call recordings, newest first. Calls are recorded while the call recording add-on is on.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Recording"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/recordings/{id}/audio":{"get":{"operationId":"recordingsAudio","tags":["recordings"],"summary":"Download a recording as WAV (16-bit PCM mono, 8 kHz).","description":"Download a recording as WAV (16-bit PCM mono, 8 kHz).","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"WAV audio: 16-bit PCM, mono, 8 kHz."}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/tickets":{"get":{"operationId":"ticketsList","tags":["tickets"],"summary":"List the account's support tickets with their status (open or closed), newest first.","description":"List the account's support tickets with their status (open or closed), newest first.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketSummary"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}},"post":{"operationId":"ticketsCreate","tags":["tickets"],"summary":"Open a support ticket with a title and a description.","description":"Open a support ticket with a title and a description.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A new support ticket.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/tickets/{id}":{"get":{"operationId":"ticketsGet","tags":["tickets"],"summary":"A ticket with its description and replies.","description":"A ticket with its description and replies.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/tickets/{id}/replies":{"post":{"operationId":"ticketsReply","tags":["tickets"],"summary":"Add a reply to a ticket.","description":"Add a reply to a ticket.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A reply to add.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketReplyRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketReply"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/tickets/{id}/close":{"post":{"operationId":"ticketsClose","tags":["tickets"],"summary":"Close a support ticket.","description":"Close a support ticket.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/calls/live":{"get":{"operationId":"callsLive","tags":["calls"],"summary":"Calls currently ringing, active, or on hold.","description":"Calls currently ringing, active, or on hold.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiveCall"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/calls/{id}/actions":{"post":{"operationId":"callsAction","tags":["calls"],"summary":"Control a live call: answer, reject, hold, resume, hang up, forward, transfer (blind or attended), complete an attended transfer, or send a DTMF digit.","description":"Control a live call: answer, reject, hold, resume, hang up, forward, transfer (blind or attended), complete an attended transfer, or send a DTMF digit.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID of the resource.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"What to do to a live call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallAction"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallActionResponse"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/calls/dial":{"post":{"operationId":"callsDial","tags":["calls"],"summary":"Place a call from an extension.","description":"Place a call from an extension. Accepts US numbers as 10 digits or 1 + 10 digits, any number as E.164 (+) or with 011, another extension's number, or *98 for voicemail. Fails with 402 if the account is past due, and with 403 for destinations outside the US without international calling.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A call to place.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DialRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveCall"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/calls/history":{"get":{"operationId":"cdrList","tags":["history"],"summary":"Search call history by phone number (full or partial), time range, direction, extension, and outcome.","description":"Search call history by phone number (full or partial), time range, direction, extension, and outcome. Newest first and paged with a cursor. Includes just-ended calls.","security":[{"bearerAuth":[]}],"parameters":[{"name":"phone","in":"query","required":false,"description":"Full or partial phone number, matched against calling and called numbers.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Only calls starting at or after this time.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Only calls starting before this time.","schema":{"type":"string","format":"date-time"}},{"name":"direction","in":"query","required":false,"description":"Only calls in this direction.","schema":{"type":"string","enum":["incoming","outgoing","internal"]}},{"name":"extension","in":"query","required":false,"description":"Only calls involving this extension number.","schema":{"type":"string"}},{"name":"outcome","in":"query","required":false,"description":"Only calls with this outcome.","schema":{"type":"string","enum":["answered","busy","no_answer","failed","blocked"]}},{"name":"cursor","in":"query","required":false,"description":"`next_cursor` from the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size; default 50, at most 100.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallRecordPage"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/calls/stats":{"get":{"operationId":"cdrStats","tags":["history"],"summary":"Call totals for the current billing period.","description":"Call totals for the current billing period.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallStats"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/settings/phone":{"get":{"operationId":"settingsPhone","tags":["settings"],"summary":"Codec preferences and hold music.","description":"Codec preferences and hold music. `callerIdNumberId` is always null: the caller ID is Numbers' (`numbers.callerId`).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneSettings"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"settingsUpdatePhone","tags":["settings"],"summary":"Partially update codec preferences and hold music.","description":"Partially update codec preferences and hold music. Admins only. Every enabled codec must be in the priority list.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"Changes to phone settings; omitted fields are unchanged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePhoneSettingsRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneSettings"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/provider/login":{"post":{"operationId":"providerLogin","tags":["accounts"],"summary":"Provider staff login, separate from customer accounts.","description":"Provider staff login, separate from customer accounts. The token only works on provider endpoints.","requestBody":{"required":true,"description":"Sign-in credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLoginResponse"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/provider/tickets":{"get":{"operationId":"providerTickets","tags":["provider"],"summary":"Open support tickets across all accounts, newest first.","description":"Open support tickets across all accounts, newest first. Provider token required.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderTicket"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"}}}}}}},"/api/v1/softphone/devices":{"post":{"operationId":"softphoneRegister","tags":["softphone"],"summary":"Register this browser as a web phone for an extension: calls to the extension ring it too, and it can call as the extension.","description":"Register this browser as a web phone for an extension: calls to the extension ring it too, and it can call as the extension. Send `deviceId` to keep the same one. Returns the STUN/TURN servers for WebRTC.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"A browser to register as a web phone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterWebPhoneRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebPhone"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/softphone/devices/{deviceId}":{"delete":{"operationId":"softphoneUnregister","tags":["softphone"],"summary":"Unregister a web phone.","description":"Unregister a web phone.","security":[{"bearerAuth":[]}],"parameters":[{"name":"deviceId","in":"path","required":true,"description":"The web phone's `deviceId`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/softphone/devices/{deviceId}/calls":{"get":{"operationId":"softphoneCalls","tags":["softphone"],"summary":"The web phone's calls: ringing (with the PBX's WebRTC offer), answered, and recently ended.","description":"The web phone's calls: ringing (with the PBX's WebRTC offer), answered, and recently ended. Polling keeps it registered; 404 once it expired.","security":[{"bearerAuth":[]}],"parameters":[{"name":"deviceId","in":"path","required":true,"description":"The web phone's `deviceId`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebCall"}}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"softphoneDial","tags":["softphone"],"summary":"Call from the web phone with the browser's complete WebRTC offer (ICE gathered).","description":"Call from the web phone with the browser's complete WebRTC offer (ICE gathered). Poll its calls for the answer. Authorized like the extension's desk phone.","security":[{"bearerAuth":[]}],"parameters":[{"name":"deviceId","in":"path","required":true,"description":"The web phone's `deviceId`.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A call from the web phone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebDialRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebCall"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/softphone/calls/{key}/answer":{"post":{"operationId":"softphoneAnswer","tags":["softphone"],"summary":"Answer a call ringing in the browser with its WebRTC answer.","description":"Answer a call ringing in the browser with its WebRTC answer.","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The web phone's call `id` (`web:…`).","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"The browser's WebRTC SDP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebSdpRequest"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebCall"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/softphone/calls/{key}/reject":{"post":{"operationId":"softphoneReject","tags":["softphone"],"summary":"Decline a call ringing in the browser; other phones keep ringing.","description":"Decline a call ringing in the browser; other phones keep ringing.","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The web phone's call `id` (`web:…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebCall"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/softphone/calls/{key}/hangup":{"post":{"operationId":"softphoneHangup","tags":["softphone"],"summary":"Hang up the browser's call, or cancel one it is still placing.","description":"Hang up the browser's call, or cancel one it is still placing.","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"description":"The web phone's call `id` (`web:…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebCall"}}}},"default":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}