Sign inGet Started

Buy and release a number

Buying a number takes two calls: search a country for what is on sale, then order the one you want. Everything here needs an API key with the numbers scope, and the first purchase in an organization needs identity verification.

Search a country

The search is always scoped to one country, so country_code is required. Narrow it further with number_type, capabilities, or a prefix of national digits.

// The search is always country-scoped, so country_code is required.
const page = await bird.numbers.available.list({
  country_code: "GB",
  capabilities: ["sms", "voice"],
});
for (const candidate of page.data) {
  console.log(candidate.number, candidate.number_type);
}

Use the regional host that matches your key's bk_{region}_ prefix: https://us1.platform.bird.com or https://eu1.platform.bird.com.

Each result describes the number:

Code example
{
  "data": [
    {
      "number": "+447700900123",
      "country_code": "GB",
      "number_type": "mobile",
      "capabilities": ["sms", "voice"],
      "pricing": {
        "setup_price": { "amount": "0.00995", "currency_code": "USD" },
        "recurring_price": { "amount": "0.00995", "currency_code": "USD" },
        "recurring_period": { "unit": "month", "count": 1 },
        "intervals_per_charge": 12
      }
    }
  ],
  "next_cursor": null,
  "prev_cursor": null
}

Each result also carries a pricing object with the price for your organization, net of tax and in your billing currency:

  • setup_price is charged once when you order the number. A published fee of zero has an amount of "0". The field itself is null when no setup fee applies, and also whenever recurring_price is null, because that number cannot be ordered.
  • recurring_price is the rate per recurring_period.
  • intervals_per_charge is how many recurring_periods one charge bills. The recurring charge before tax is recurring_price multiplied by intervals_per_charge, taken when the number is assigned to your workspace and at each renewal. For an order that waits on a carrier, assignment happens when the order completes. A recurring_period of one month with intervals_per_charge: 12 bills 12 months at a time.

The API reference shows an example result with prices. A search result with pricing.recurring_price: null does not quote a recurring price. Contact sales to have that country and number type priced before ordering.

The dashboard and API use the same organization price, including conversion to your billing currency. A price read does not lock a quote: tariff or exchange-rate changes before a later charge can change its amount. If the lookup fails, the search returns 503 with E14009. Retry the read with exponential backoff; a lookup failure never means the number costs nothing.

Our own inventory is returned first and pages normally. The last page can include numbers a carrier is offering live, so a number listed a moment ago may already be gone by the time you order it.

To confirm one is still there before ordering it, read it back with GET /v1/numbers/available/{number}. A 404 means it is not currently available for sale, whether a carrier withdrew it or our own inventory has it reserved. The re-check draws on the same numbers_availability rate limit as the search, so re-check the candidate you are about to order rather than every result.

Order the number

Pass a number from the search to POST /v1/numbers/orders. For retry protection, see Idempotency.

const order = await bird.numbers.orders.create({ number: "+447700900201" });
// Most orders finish inside the request. One that has to wait on a carrier
// comes back without a number_id. Poll it until it is completed or failed.
if (order.status === "completed") {
  console.log("allocated as", order.number_id);
} else {
  console.log("still", order.status, "; poll", order.id);
}

Most orders finish inside the request and answer 201 with the number already yours:

Code example
{
  "id": "nor_01m0da22b0e39anhzyhtw3gzdg",
  "number": "+447700900123",
  "country_code": "GB",
  "number_type": "mobile",
  "status": "completed",
  "number_id": "nda_7eqywfwzxwa1za9n8wp7e1xkr8",
  "failure_reason": null,
  "completed_at": "2026-08-19T15:25:56.479320Z",
  "created_at": "2026-08-19T15:25:56.448051Z",
  "updated_at": "2026-08-19T15:25:56.479320Z"
}

number_id is the handle for everything after this: reading the number, and releasing it.

Poll an order that did not finish

An order that has to wait on a carrier answers 202 instead, with number_id still null. Read it back until status is completed or failed.

const order = await bird.numbers.orders.get("nor_01krdgeqcxet5s7t44vh8rt9mg");
// failure_reason says what went wrong, and only ever on a failed order.
console.log(order.status, order.failure_reason ?? "");

An order moves through charging, ordering, and pending before it settles. On failed, failure_reason says what went wrong in plain terms. A setup fee already taken is not refunded, so a failed order can leave a charge behind; contact support if that happens.

Release a number

Releasing stops the recurring charge and the number stops working for you. Only a dedicated number can be released, and a released number does not go straight back on sale.

// Releasing stops the recurring charge and the number stops working for you.
// Only a dedicated number can be released; a shared one answers E14002.
await bird.numbers.release("nda_01krdgeqcxet5s7t44vh8rt9mg");

A successful release answers 204 with no body. To keep the number until the end of the period you already paid for, cancel it instead: Managing your phone numbers explains both.

When an order is refused

Four refusals cover almost every failed purchase.

402 with E03000 means the wallet cannot cover the number. Top up and order again. No order is created, so nothing is charged.

412 means the organization has not completed the identity verification a first purchase requires. Complete it, then retry.

409 with E14000 means the number went while you were choosing it. Search again and pick another.

409 with E14001 means too many of your orders are already in flight. Let one finish, then order again.

Next steps

Continue with the documentation, guides and examples for this topic.