Comprar y liberar un número
Comprar un número requiere dos llamadas: buscar en un país lo que está en venta y luego pedir el que quieras. Todo aquí necesita una clave API con el alcance numbers, y la primera compra en una organización requiere verificación de identidad.
Buscar en un país
La búsqueda siempre se limita a un país, así que country_code es obligatorio. Acótala con number_type, capabilities o un prefix de dígitos nacionales.
// 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);
}# The search is always country-scoped, so country_code is required.
page = client.numbers.available.list(country_code="GB", capabilities=["sms", "voice"])
for candidate in page.data:
print(candidate.number, candidate.number_type)for candidate, err := range client.Numbers.Available.List(context.Background(), bird.NumbersAvailableListParams{
CountryCode: "GB",
Capabilities: []string{"sms", "voice"},
}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(candidate.Number, candidate.NumberType)
}// The search is always country-scoped, so country_code is required.
$page = $bird->numbers->available->list([
'country_code' => 'GB',
'capabilities' => ['sms', 'voice'],
]);
foreach ($page as $candidate) {
echo $candidate->getNumber(), ' ', $candidate->getNumberType(), "\n";
}curl "https://us1.platform.bird.com/v1/numbers/available?country_code=GB" \
-H "Authorization: Bearer bk_us1_..."Usa el host regional que coincida con el prefijo bk_{region}_ de tu clave: https://us1.platform.bird.com o https://eu1.platform.bird.com.
Cada resultado describe el número:
{
"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
}Cada resultado también incluye un objeto pricing con el precio para tu organización, neto de impuestos y en tu moneda de facturación:
setup_pricese cobra una vez cuando pides el número. Una tarifa publicada de cero tiene unamountde"0". El campo en sí esnullcuando no se aplica ninguna tarifa de activación, y también siempre querecurring_priceseanull, porque ese número no se puede pedir.recurring_pricees la tarifa porrecurring_period.intervals_per_chargeindica cuántosrecurring_periodcubre un cargo. El cargo recurrente antes de impuestos esrecurring_pricemultiplicado porintervals_per_charge, y se cobra cuando el número se asigna a tu espacio de trabajo y en cada renovación. Si el pedido espera a un operador, la asignación se produce cuando el pedido se completa. Unrecurring_periodde un mes conintervals_per_charge: 12factura 12 meses a la vez.
La referencia de API muestra un resultado de ejemplo con precios. Un resultado de búsqueda con pricing.recurring_price: null no indica un precio recurrente. Contacta con ventas para que te coticen ese país y tipo de número antes de hacer el pedido.
El panel de control y API usan el mismo precio de organización, incluida la conversión a tu moneda de facturación. Consultar un precio no fija una cotización: si la tarifa o el tipo de cambio varían antes de un cargo posterior, el importe de ese cargo puede cambiar. Si la consulta falla, la búsqueda devuelve 503 con E14009. Reintenta la lectura con retroceso exponencial; un fallo en la consulta nunca significa que el número no cueste nada.
Nuestro propio inventario se devuelve primero y pagina con normalidad. La última página puede incluir números que un operador ofrece en tiempo real, así que un número listado hace un momento puede haberse agotado para cuando lo pidas.
Para confirmar que un número sigue disponible antes de pedirlo, consúltalo con GET /v1/numbers/available/{number}. Un 404 significa que no está disponible para la venta en ese momento, ya sea porque el operador lo retiró o porque nuestro propio inventario lo tiene reservado. La nueva consulta comparte el mismo límite de numbers_availability que la búsqueda, así que verifica solo el candidato que vas a pedir en lugar de todos los resultados.
Pedir el número
Pasa un número de la búsqueda a POST /v1/numbers/orders. Para protección ante reintentos, consulta Idempotencia.
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);
}order = client.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 completed or failed.
if order.status == "completed":
print("allocated as", order.number_id)
else:
print("still", order.status, "; poll", order.id)order, err := client.Numbers.Orders.Create(context.Background(), bird.NumbersOrdersCreateParams{
Number: "+447700900201",
})
if err != nil {
log.Fatal(err)
}
// An order that has to wait on a carrier comes back without a NumberId.
// Poll it until it is completed or failed.
fmt.Println(order.Status, order.Id)$order = $bird->numbers->orders->create(
(new NumbersOrderCreate())->setNumber('+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->getStatus() === 'completed') {
echo 'allocated as ', $order->getNumberId(), "\n";
} else {
echo 'still ', $order->getStatus(), '; poll ', $order->getId(), "\n";
}curl -X POST "https://us1.platform.bird.com/v1/numbers/orders" \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-d '{"number": "+447700900123"}'La mayoría de los pedidos terminan dentro de la solicitud y responden 201 con el número ya asignado a ti:
{
"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 es el identificador para todo lo que sigue: consultar el número y liberarlo.
Consultar un pedido que no terminó
Un pedido que debe esperar a un operador responde 202 en su lugar, con number_id aún en null. Consúltalo de nuevo hasta que status sea completed o 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 ?? "");order = client.numbers.orders.get("nor_01krdgeqcxet5s7t44vh8rt9mg")
# failure_reason says what went wrong, and only ever on a failed order.
print(order.status, order.failure_reason or "")order, err := client.Numbers.Orders.Get(context.Background(), "nor_01krdgeqcxet5s7t44vh8rt9mg")
if err != nil {
log.Fatal(err)
}
// FailureReason says what went wrong, and only ever on a failed order.
fmt.Println(order.Status)$order = $bird->numbers->orders->get('nor_01krdgeqcxet5s7t44vh8rt9mg');
// failure_reason says what went wrong, and only ever on a failed order.
echo $order->getStatus(), ' ', $order->getFailureReason() ?? '', "\n";curl "https://us1.platform.bird.com/v1/numbers/orders/nor_01m0da22b0e39anhzyhtw3gzdg" \
-H "Authorization: Bearer bk_us1_..."Un pedido pasa por charging, ordering y pending antes de resolverse. En failed, failure_reason indica qué salió mal en términos claros. Una tarifa de activación ya cobrada no se reembolsa, así que un pedido fallido puede dejar un cargo pendiente; contacta a soporte si eso ocurre.
Liberar un número
Liberar un número detiene el cargo recurrente y el número deja de funcionar para ti. Solo un número dedicated se puede liberar, y un número liberado no vuelve a ponerse en venta de inmediato.
// 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");# Releasing stops the recurring charge and the number stops working for you.
# Only a dedicated number can be released; a shared one answers E14002.
client.numbers.release("nda_01krdgeqcxet5s7t44vh8rt9mg")// Only a dedicated number can be released; a shared one answers E14002.
if err := client.Numbers.Release(context.Background(), "nda_01krdgeqcxet5s7t44vh8rt9mg"); err != nil {
log.Fatal(err)
}// Releasing stops the recurring charge and the number stops working for you.
// Only a dedicated number can be released; a shared one answers E14002.
$bird->numbers->release('nda_01krdgeqcxet5s7t44vh8rt9mg');curl -X POST "https://us1.platform.bird.com/v1/numbers/nda_7eqywfwzxwa1za9n8wp7e1xkr8/release" \
-H "Authorization: Bearer bk_us1_..."Una liberación exitosa responde 204 sin cuerpo. Para conservar el número hasta el final del período que ya pagaste, cancélalo en su lugar: Gestión de tus números de teléfono explica ambas opciones.
Cuando un pedido es rechazado
Cuatro motivos de rechazo cubren casi todas las compras fallidas.
402 con E03000 significa que el saldo no alcanza para cubrir el número. Recarga y vuelve a pedir. No se crea ningún pedido, así que no se cobra nada.
412 significa que la organización no ha completado la verificación de identidad que requiere una primera compra. Complétala y reintenta.
409 con E14000 significa que el número se fue mientras lo elegías. Busca de nuevo y elige otro.
409 con E14001 significa que demasiados de tus pedidos ya están en curso. Espera a que uno termine y vuelve a pedir.
Próximos pasos
- Descripción general de números explica qué significan los campos de un número.
- Referencia API de números documenta cada operación y campo.
- Idempotencia explica cómo las claves hacen seguro reintentar un pedido.
Recursos relacionados
Continúa con la documentación, guías y ejemplos de este tema.