curl --request POST \
--url https://api.withallo.com/v2/api/partner/accounts/{id}/numbers \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"country": "FR",
"prefix": "7",
"esim": true
}
'import requests
url = "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers"
payload = {
"country": "FR",
"prefix": "7",
"esim": True
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({country: 'FR', prefix: '7', esim: true})
};
fetch('https://api.withallo.com/v2/api/partner/accounts/{id}/numbers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'country' => 'FR',
'prefix' => '7',
'esim' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers"
payload := strings.NewReader("{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.withallo.com/v2/api/partner/accounts/{id}/numbers")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.withallo.com/v2/api/partner/accounts/{id}/numbers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"phone_number": "+33745805222",
"country": "FR",
"charged": true
}
}{
"error": {}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"retry_after_seconds": 123
}
}{
"error": {}
}{
"error": {}
}{
"error": {}
}{
"error": {}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"retry_after_seconds": 123
}
}{
"error": {}
}Add number
Adds a phone number to one of your accounts. The number is billed on the account’s subscription, which you pay: Allo draws on your prepaid credit first, then charges your card on file for the rest. When the account already pays for a number slot that no number uses, the new number takes that slot and nothing is charged (charged: false). Allo checks that a number is available before charging anything. Requires the PARTNER scope.
curl --request POST \
--url https://api.withallo.com/v2/api/partner/accounts/{id}/numbers \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"country": "FR",
"prefix": "7",
"esim": true
}
'import requests
url = "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers"
payload = {
"country": "FR",
"prefix": "7",
"esim": True
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({country: 'FR', prefix: '7', esim: true})
};
fetch('https://api.withallo.com/v2/api/partner/accounts/{id}/numbers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'country' => 'FR',
'prefix' => '7',
'esim' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.withallo.com/v2/api/partner/accounts/{id}/numbers"
payload := strings.NewReader("{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.withallo.com/v2/api/partner/accounts/{id}/numbers")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.withallo.com/v2/api/partner/accounts/{id}/numbers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"country\": \"FR\",\n \"prefix\": \"7\",\n \"esim\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"phone_number": "+33745805222",
"country": "FR",
"charged": true
}
}{
"error": {}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"retry_after_seconds": 123
}
}{
"error": {}
}{
"error": {}
}{
"error": {}
}{
"error": {}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"retry_after_seconds": 123
}
}{
"error": {}
}PARTNERRequest
The body is a number preference, the same asnumber_preference on Create account:
countryis required (ISO country code, for exampleFR). An unknown country fails withINVALID_NUMBER_PREFERENCE.prefixis optional: the digits the number should start with, for example7or+337.esimis optional,falseby default. Set it totrueto get a French mobile number that can carry an eSIM, which you then order with Order eSIM. With anycountryother thanFR, the request fails withESIM_NOT_AVAILABLE_IN_COUNTRY.
{id} is the account id returned by Create account. An account your API key did not create, or one already deactivated, returns 404 PARTNER_ACCOUNT_NOT_FOUND.
Billing
- The number is billed on the account’s subscription, which you pay. Allo draws on your prepaid credit first, then charges your card on file for the rest. Allo never charges your customer.
- Allo charges the rest of the account’s current billing period now, with the subscription’s discount applied. The number then renews with the subscription.
- If the account already pays for a number slot that no number uses, the new number takes that slot and nothing is charged. The response then has
charged: false. - Allo checks that a number is available before charging anything. If none matches the country and prefix, the request fails with
409 NO_NUMBER_AVAILABLEand nothing is charged. A country that needs the account’s regulatory verification first fails with409 REGULATORY_VERIFICATION_REQUIRED, also before any charge. - If your prepaid credit does not cover the charge and you have no card on file, the request fails with
402 PARTNER_CREDIT_INSUFFICIENTand nothing is created. Top up your credit or add a card, then retry with a newIdempotency-Key. - A declined card fails with
402 PARTNER_BILLING_FAILED, and nothing is created. - If the number cannot be set up after the charge, Allo takes the charge back off the subscription and credits the unused period to your balance.
Retries
Send anIdempotency-Key header (8 to 100 letters, digits, - or _, for example a UUID) and reuse it when you retry the same request. Retrying with the same key does not charge you twice. A key in another format fails with INVALID_IDEMPOTENCY_KEY.
If you are not sure an earlier attempt went through, check the account’s phone_numbers with Get account before you retry.
Errors
| Code | What it means |
|---|---|
PARTNER_ACCOUNT_BUSY | Another number or member is being added to this account right now. Always retryable: true: retry in a few seconds. |
IDEMPOTENCY_KEY_ALREADY_USED | An earlier attempt already used this Idempotency-Key. Check the account’s numbers with Get account before you retry with a new key. |
PARTNER_ACCOUNT_DEACTIVATING | The account is being deactivated at the end of its billing period, so it takes no more numbers. |
PARTNER_ACCOUNT_SUBSCRIPTION_CONFLICT | The account’s subscription cannot be billed right now. When retryable is true, retry in a few minutes. Otherwise write to [email protected]. |
PARTNER_SUBSCRIPTION_NOT_BILLABLE | The account has no subscription Allo can bill (402). |
PARTNER_BILLING_UNAVAILABLE | Billing is temporarily unavailable (500). Retry with the same Idempotency-Key, which resumes the same charge. |
PARTNER_NUMBER_SETUP_FAILED | The number could not be set up (500), and the charge was taken back. Do not retry: write to [email protected]. |
PARTNER_NUMBER_KEPT | The number was assigned but its setup did not complete (500). It stays on the account and on its billing. Do not retry, since a retry would add another number: write to [email protected] with the number. |
Response
phone_numberis the new number, in E.164 format. It also appears in the account’sphone_numberson Get account.countryis the country as Allo names it:GBcomes back asUK.chargedistruewhen a new slot was charged,falsewhen the number took a slot the account already paid for.
Authorizations
Headers
Optional. 8 to 100 letters, digits, - or _, for example a UUID. Retrying with the same key does not charge you twice.
^[A-Za-z0-9_-]{8,100}$Path Parameters
The account id returned by Create account (usr-*).
Body
ISO country code.
"FR"
Optional. Digits the number should start with, after the country code, for example +337 or 7.
"7"
Optional, default false. Set to true to get a French mobile number that can carry an eSIM, which you can then order with POST /v2/api/partner/accounts/{account_id}/esims. eSIM numbers are only available with country set to FR, otherwise the request fails with ESIM_NOT_AVAILABLE_IN_COUNTRY.
true
Response
Number added
Show child attributes
Show child attributes
Was this page helpful?