Acheter et libérer un numéro
L'achat d'un numéro nécessite deux appels : recherchez dans un pays ce qui est en vente, puis commandez celui que vous voulez. Tout ici requiert une clé API avec le scope numbers, et le premier achat dans une organisation nécessite une vérification d'identité.
Rechercher dans un pays
La recherche porte toujours sur un seul pays, donc country_code est obligatoire. Affinez-la avec number_type, capabilities, ou un prefix de chiffres nationaux.
// 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_..."Utilisez l'hôte régional correspondant au préfixe bk_{region}_ de votre clé : https://us1.platform.bird.com ou https://eu1.platform.bird.com.
Chaque résultat décrit le numéro :
{
"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
}Chaque résultat porte aussi un objet pricing avec le prix pour votre organisation, hors taxes et dans votre devise de facturation :
setup_priceest facturé une fois lorsque vous commandez le numéro. Des frais publiés de zéro ont unamountde"0". Le champ lui-même vautnulllorsqu'aucuns frais de mise en service ne s'appliquent, ainsi que chaque fois querecurring_pricevautnull, car ce numéro ne peut pas être commandé.recurring_priceest le tarif parrecurring_period.intervals_per_chargeest le nombre derecurring_periodcouverts par une facturation. Le montant récurrent hors taxes estrecurring_pricemultiplié parintervals_per_charge, prélevé lorsque le numéro est attribué à votre espace de travail, puis à chaque renouvellement. Pour une commande qui attend un opérateur, l'attribution a lieu lorsque la commande aboutit. Unerecurring_periodd'un mois avecintervals_per_charge: 12facture 12 mois à la fois.
La référence API montre un exemple de résultat avec les prix. Un résultat de recherche avec pricing.recurring_price: null ne fournit pas de tarif récurrent. Contactez l'équipe commerciale pour obtenir un tarif pour ce pays et ce type de numéro avant de commander.
Le tableau de bord et API utilisent le même prix d'organisation, y compris la conversion dans votre devise de facturation. La lecture d'un prix ne verrouille pas un devis : un changement de tarif ou de taux de change avant une facturation ultérieure peut en modifier le montant. Si la recherche de prix échoue, la recherche renvoie 503 avec E14009. Réessayez la lecture avec un délai exponentiel ; un échec de recherche de prix ne signifie jamais que le numéro ne coûte rien.
Notre propre inventaire est renvoyé en premier et paginé normalement. La dernière page peut inclure des numéros qu'un opérateur propose en temps réel ; un numéro listé il y a un instant peut donc déjà être pris au moment où vous le commandez.
Pour vérifier qu'un numéro est encore disponible avant de le commander, relisez-le avec GET /v1/numbers/available/{number}. Un 404 signifie qu'il n'est pas actuellement en vente, que l'opérateur l'ait retiré ou que notre propre inventaire l'ait réservé. La revérification utilise la même limite de débit numbers_availability que la recherche : ne revérifiez donc que le candidat que vous êtes sur le point de commander, pas chaque résultat.
Commander le numéro
Transmettez un numéro issu de la recherche à POST /v1/numbers/orders. Pour la protection contre les nouvelles tentatives, voir Idempotence.
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 plupart des commandes aboutissent dans la requête et répondent 201 avec le numéro déjà à vous :
{
"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 est l'identifiant pour tout ce qui suit : lire le numéro et le libérer.
Interroger une commande qui n'a pas abouti
Une commande qui doit attendre un opérateur répond 202 à la place, avec number_id encore à null. Relisez-la jusqu'à ce que status soit completed ou 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_..."Une commande passe par charging, ordering et pending avant de se stabiliser. En cas de failed, failure_reason indique ce qui a échoué en termes clairs. Des frais de mise en service déjà prélevés ne sont pas remboursés : une commande échouée peut donc laisser un montant facturé ; contactez le support si cela se produit.
Libérer un numéro
La libération arrête la facturation récurrente et le numéro cesse de fonctionner pour vous. Seul un numéro dedicated peut être libéré, et un numéro libéré ne repart pas directement en vente.
// 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_..."Une libération réussie répond 204 sans corps de réponse. Pour conserver le numéro jusqu'à la fin de la période déjà payée, annulez-le à la place : Gérer vos numéros de téléphone explique les deux options.
Quand une commande est refusée
Quatre motifs de refus couvrent presque tous les achats qui échouent.
402 avec E03000 signifie que le portefeuille ne peut pas couvrir le numéro. Rechargez-le et commandez à nouveau. Aucune commande n'est créée, donc rien n'est facturé.
412 signifie que l'organisation n'a pas complété la vérification d'identité requise pour un premier achat. Complétez-la, puis réessayez.
409 avec E14000 signifie que le numéro a disparu pendant que vous le choisissiez. Relancez une recherche et choisissez-en un autre.
409 avec E14001 signifie que trop de vos commandes sont déjà en cours. Attendez qu'une aboutisse, puis commandez à nouveau.
Étapes suivantes
- Vue d'ensemble des numéros explique la signification des champs d'un numéro.
- Référence API des numéros documente chaque opération et chaque champ.
- Idempotence explique comment les clés sécurisent une commande réessayée.
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet.