---
title: "Purchase a phone number"
method: POST
path: "/v1/phone-numbers"
---

# Purchase a phone number

`POST /v1/phone-numbers`

## Request

- Base URL: `https://api.zavu.dev`
- URL: `https://api.zavu.dev/v1/phone-numbers`
- Auth: HTTP bearer

Purchase an available phone number. Requires a paid plan: the Free plan cannot purchase phone numbers and receives `402` with code `paid_plan_required`.

**The included number.** A paid plan includes one number at no charge, once per account: it must be a US or Canadian number (a +1 number) costing $20 a month or less. `isFreeEligible` in `GET /v1/phone-numbers/available` marks the numbers that qualify. Claiming it spends the benefit for good, across every team the account owner owns, so releasing that number does not make another one free.

**Numbers with regulatory requirements.** Which numbers need regulatory information is decided per number, not by a fixed country list. The purchase looks the requirements up for the exact number before charging anything:

1. `GET /v1/phone-numbers/requirements?phoneNumber=...`. If `items` is empty, buy normally.
2. Create what it asks for: addresses with `POST /v1/addresses`, documents with `POST /v1/documents`.
3. Purchase with `type` and `regulatoryRequirements`. The number is bought and billed at once with `regulatoryStatus: pending_review`.
4. Poll `GET /v1/phone-numbers/{phoneNumberId}` until `regulatoryStatus` is `approved`. Assign it to a sender before or after approval; it starts carrying messages once approved.

**Reuse.** Information you submitted is kept for your project, per country and `type`, and a later purchase there may omit `regulatoryRequirements`. Reuse only happens when what is kept still covers every requirement of the new number and every address and document in it belongs to the project. Otherwise, or when nothing is kept, the purchase returns `400 regulatory_compliance_required` with the missing requirements in `details`.

Invalid values (a missing, unknown or repeated requirement id, an address or document from another project, or one rejected in review) return `400 invalid_request`. If an address or document cannot be registered for review, the purchase returns `400 invalid_request` naming the requirement. If the requirements cannot be looked up, the purchase returns `502 requirements_unavailable`, except for US and Canadian numbers, which are sold as numbers without requirements. None of these errors charge anything.

## Request body

- PhoneNumberPurchaseRequest
  - `phoneNumber` string, required: Phone number in E.164 format.
  - `name` string: Optional custom name for the phone number.
  - `type` 'local' | 'national' | 'tollFree' | 'mobile': Type of phone number. `mobile` is stocked in countries where no geographic (`local`) or non-geographic (`national`) inventory exists, and in several markets it is the only type that can receive SMS.
  - `regulatoryRequirements` object[]: Regulatory information, for numbers whose requirements list is not empty. Get the list with `GET /v1/phone-numbers/requirements?phoneNumber=...` and send one entry per requirement id, except `action` requirements, which take no value. Every required id must be present, once, and no unknown id may be sent; otherwise the purchase is refused with `400 invalid_request` before anything is charged. The information is kept for your project under the number's country and `type`. A later purchase there may omit this field if what is kept still covers that number's requirements. Omit it for numbers without requirements.
    - `requirementType` string, required: A `requirementTypes[].id` from `GET /v1/phone-numbers/requirements`. Each id may appear only once.
    - `fieldValue` string, required: Depends on the requirement's `type`: the text itself for `textual`; for `address`, the `id` of an address created in this project with `POST /v1/addresses`; for `document`, the `id` of a document created with `POST /v1/documents`. An address or document from another project, or one rejected in review, is refused.

## Response `201`

Phone number purchased successfully.

- PhoneNumberResponse
  - `phoneNumber` OwnedPhoneNumber, required
    - `id` string, required
    - `phoneNumber` string, required
    - `name` string: Optional custom name for the phone number.
    - `capabilities` string[], required
    - `status` 'active' | 'suspended' | 'pending' | 'releasing' | 'released', required: Billing state of an owned number, separate from `regulatoryStatus`. `pending` is legacy and is not written to numbers today. The SDKs carry `active`, `suspended` and `pending` only; `releasing` and `released` are returned by the REST API until their next release.
    - `senderId` string: Sender ID if the phone number is assigned to a sender.
    - `pricing` OwnedPhoneNumberPricing, required
      - `monthlyPrice` number: Monthly price in USD.
      - `upfrontCost` number: One-time purchase cost in cents.
      - `monthlyCost` number: Monthly cost in cents.
      - `isFreeNumber` boolean: Whether this is a free number.
    - `regulatoryStatus` 'approved' | 'pending_review' | 'rejected', required: Regulatory review state. Numbers that need no review are `approved` immediately. A number bought with regulatory information is owned and billed from purchase and starts `pending_review`; it cannot send messages or place calls until this is `approved`. The state is re-checked every 6 hours: poll `GET /v1/phone-numbers/{phoneNumberId}` to follow it. Assign it to a sender with `PATCH /v1/phone-numbers/{phoneNumberId}` (`senderId`) before or after approval. A number assigned while under review is recorded and connected to that sender when it is approved; the connection is retried until it succeeds. A sender created over the API is set up for SMS as part of the assignment. `rejected` means review refused the information: the number cannot be assigned to a sender. A number that stays `pending_review` may be waiting on information the API cannot supply; contact support.
    - `nextRenewalDate` string, date-time
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time

## Other responses

- `400`: Invalid request, the number is no longer available or not listed under the `type` sent (`number_unavailable`), the country is restricted, regulatory information is missing (`regulatory_compliance_required`), or the regulatory information sent is invalid (`invalid_request`).
- `401`: Unauthorized.
- `402`: Payment required. Either the balance cannot cover the purchase (code `insufficient_balance`) or the team is on the Free plan (code `paid_plan_required`): buying phone numbers requires a paid plan, which includes one US number.
- `502`: The number's regulatory requirements could not be looked up, so nothing was charged. Retry. Not returned for US and Canadian numbers.

---

[API](https://skmtc.dev/zavudev/apis/zavu-unified-messaging-layer-api.md) - [All operations](https://skmtc.dev/zavudev/apis/zavu-unified-messaging-layer-api/llms.txt) - [OpenAPI document](https://skmtc.dev/zavudev/apis/zavu-unified-messaging-layer-api/revisions/75bc777b0ffb?raw)
