# Manage Phone Numbers

Phone numbers are a central part of the **Telephony SDK**. Phone numbers from different countries around the world can be provisioned and used to to communicate with other phone numbers.

Provisioning a phone number is a two-step process. First, a search must be performed for an available phone number using a specific country code. After the desired phone number is selected, the phone number can be provisioned to a Sudo.

## Get Supported Countries

To get the list of supported countries, use the `getSupportedCountries()` method. The country code format currently supported is the two-letter format described in [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).

In sandbox mode, the "ZZ" country code is included to allow provisioning simulated phone numbers. Refer to the [Telephony Simulator](https://docs.sudoplatform.com/guides/telephony/simulator-and-the-zz-country-code) page for details.

{% tabs %}
{% tab title="Swift" %}

```swift
try! telephonyClient.getSupportedCountries { result in
    switch result {
    case .success(let countries):
        // countries: list of strings containing the country ISO codes
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
telephonyClient.getSupportedCountries { result ->
    when (result) {
        is Result.Success -> {
            // result.value.countries: list of strings containing 
            // the country ISO codes
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Each project in your Sudo Platform account can be configured to support a specific set of country codes. Your solutions engineer can assist you in selecting the desired country codes.
{% endhint %}

## Search Available Phone Numbers

A search for a phone number can be performed using either a country code, a country code plus phone number prefix (e.g., in the United States the prefix is called an "area code") or a latitude and longitude. A limit can be provided to ensure a maximum number of results are returned.

### By Country Only

To search for a phone number by country code, use the `searchAvailablePhoneNumbers()` method and provide the two-character ISO country code.

{% tabs %}
{% tab title="Swift" %}

```swift
// By country code
try! telephonyClient.searchAvailablePhoneNumbers(countryCode: "US", 
                                                 limit: 5) { (result) in
    switch result {
    case .success(let searchResult):
        // searchResult: AvailablePhoneNumberResult (see below for details) 
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// By country code 

// val countryCode = "US"
telephonyClient.searchAvailablePhoneNumbers(countryCode) { result ->
    when (result) {
        is Result.Success -> {
            // result.value.numbers: PhoneNumberSearchResult
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

### By Country and Prefix

To search for a phone number by country code and prefix, use the `searchAvailablePhoneNumbers()` method and provide the two-character country code and prefix digits.

{% tabs %}
{% tab title="Swift" %}

```swift
//By area code
try! telephonyClient.searchAvailablePhoneNumbers(countryCode: "US", 
                                                 prefix: "385",
                                                 limit: nil) { (result) in
    switch result {
    case .success(let searchResult):
        // searchResult: AvailablePhoneNumberResult (see below for details) 
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// By area code 

// val countryCode = "US"
// val areaCode = "385"
telephonyClient.searchAvailablePhoneNumbers(countryCode, areaCode) { result ->
    when (result) {
        is Result.Success -> {
            // result.value.numbers: PhoneNumberSearchResult (see below for details) 
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

### By Latitude and Longitude

To search for a phone number by country code and latitude/longitude, use the `searchAvailablePhoneNumbers()` method and provide the two-character country code and latitude/longitude. This function finds geographically close numbers within miles. Applies to only phone numbers in the US and Canada.

{% tabs %}
{% tab title="Swift" %}

```swift
// By lat/lng

// let country: String = "US"
// let lat: Double = 37.234332396
// let lng: Double = -115.80666344
try! client.searchAvailablePhoneNumbers(countryCode: country,
                                        latitude: lat,
                                        longitude: lng,
                                        limit: 5) { result in
    switch result {
    case .success(let searchResult):
        // searchResult: AvailablePhoneNumberResult (see below for details) 
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// By lat/lng

// val countryCode = "US"
// val latitude = "37.234332396"
// val longitude = "-115.80666344"
telephony.searchAvailablePhoneNumbers(countryCode, 
                                      latitude, 
                                      longitude) { result ->
    when (result) {
        is Result.Success -> {
            // result.value.numbers: PhoneNumberSearchResult (see below for details) 
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }

    this.latch.countDown()
}
```

{% endtab %}
{% endtabs %}

### Search Result

Both calls to `searchAvailablePhoneNumbers()` return a `AvailablePhoneNumberResult` (iOS) / `PhoneNumberSearchResult` (Android) on success. The result contains a list of available numbers and the country code / prefix used in the search.

The Telephony SDK uses the [E.164 phone number format](https://en.wikipedia.org/wiki/E.164) for all string representations of phone numbers.

{% tabs %}
{% tab title="Swift" %}

```swift
struct AvailablePhoneNumberResult {
    let numbers: [String] // List of numbers available in E.164 format
    let countryCode: String // Country code used for search
    let prefix: String? // Prefix used for search
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
data class PhoneNumberSearchResult (val id: String,
                                    val numbers: List<String>,
                                    val countryCode: String,
                                    val gps: AvailablePhoneNumberResult.Gps?,
                                    val prefix: String?,
                                    val state: PhoneNumberSearchState)
```

{% endtab %}
{% endtabs %}

## Provision Phone Number

After an available phone number is found, it can be provisioned to a Sudo using the `provisionPhoneNumber()` method. Provisioning a phone number to a Sudo makes it available to communicate with other phone numbers, such as sending and receiving SMS and MMS messages.

The Telephony SDK uses the [E.164 phone number format](https://en.wikipedia.org/wiki/E.164) for all string representations of phone numbers and this format is expected when provisioning a number.

{% tabs %}
{% tab title="Swift" %}

```swift
try! telephonyClient.provisionPhoneNumber(countryCode: "US", 
                                          phoneNumber: "+442071838750", 
                                          sudoId: "abc123") { result in
    switch result {
    case .success(let number):
        // number: PhoneNumber (see below for details)
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// val countryCode = "US"
// val phoneNumber = "+442071838750"
// val sudoID = "abc123"
telephonyClient.provisionPhoneNumber(countryCode, phoneNumber, sudoID) { result ->
    when (result) {
        is Result.Success -> {
            // result.value: PhoneNumber (see below for details)
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

### Phone Number

The `PhoneNumber` type is returned when a phone number is provisioned. This type is expected in other places where a phone number is used, such as sending an SMS/MMS message.

{% tabs %}
{% tab title="Swift" %}

```swift
public struct PhoneNumber {
    public enum State: Equatable {
        case complete
        case provisioning
        case deprovisioning
        case failed
        case unknown
    }

    public let id: String
    public let phoneNumber: String
    public let state: State
    public let version: Int
    public let created: Date
    public let updated: Date
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
data class PhoneNumber(
    val id: String,
    val phoneNumber: String,
    val state: PhoneNumberState,
    val version: Int,
    val created: Date,
    val updated: Date
)

public enum PhoneNumberState {
  PROVISIONING,
  FAILED,
  COMPLETE,
  DEPROVISIONING
}
```

{% endtab %}
{% endtabs %}

### Entitlements

Each user is allocated a limited number of phone numbers per Sudo. The current limit is 1 number per Sudo. In the future this value will be configurable from the Admin Console. If an attempt is made to provision a number in excess of the entitlements, and error will be returned from the SDK.

## De-Provision Phone Number

A previously provisioned phone number can be de-provisioned by using the `deletePhoneNumber()` method. This method expects an [E.164 phone number format](https://en.wikipedia.org/wiki/E.164) formatted phone number string. The phone number must have already been provisioned for this to succeed.

{% tabs %}
{% tab title="Swift" %}

```swift
try! telephonyClient.deletePhoneNumber(phoneNumber: "+442071838750") { result in
    switch result {
    case .success(let phoneNumber):
        // phoneNumber: E.164 formatted number
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// val phoneNumber: PhoneNumber
telephonyClient.deletePhoneNumber(phoneNumber.number) { result ->
    when (result) {
        is Result.Success -> {
            // result.value: PhoneNumber
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

## Retrieving Existing Phone Numbers

Previously provisioned numbers can be retrieved using a phone number identifier or by retrieving all provisioned numbers.

### Using Phone Number ID

You can retrieve a previously provisioned phone numbers by using the `getPhoneNumber()` method.

{% tabs %}
{% tab title="Swift" %}

```swift
// let phoneNumber: PhoneNumber
try! telephonyClient.getPhoneNumber(id: phoneNumber.id) { (result) in
    switch result {
    case .success(let number):
        // number: PhoneNumber
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// val phoneNumber: PhoneNumber
telephonyClient.getPhoneNumber(phoneNumber.id) { result ->
    when (result) {
        is Result.Success -> {
            // result.value: PhoneNumber
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

### All Provisioned Phone Numbers

To retrieve all provisioned phone numbers, use the `listPhoneNumbers()` method. This method supports paging using the `limit` and `nextToken` parameters, and optionally filters by sudo id.

{% tabs %}
{% tab title="Swift" %}

```swift
let sudoID: String
try! telephonyClient.listPhoneNumbers(sudoId: sudoId, limit: nil, nextToken: nil) { (result) in
    switch result {
    case .success(let listToken):
        // listToken: TelephonyListToken (see below for details)
    case .failure(let error):
        // error: SudoTelephonyClientError
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// val sudoID = "abc123"
telephonyClient.listPhoneNumbers(sudoId, null, null) { result ->
    when(result) {
        is Result.Success -> {
            // result.value: TelephonyListToken<PhoneNumber>
        }
        is Result.Error -> {
            // result.throwable: telephonysdk.Result.Error
        }
    }
}
```

{% endtab %}
{% endtabs %}

The result of the `listPhoneNumbers()` call is a TelephonyListToken as described below.

### Retrieve Multiple Phone Numbers Result

When multiple phone numbers are retrieved, for example through the `getPhoneNumbers()` method, a list token object is returned which includes a list of phone numbers and a paging token used to retrieve the next set of results.

{% tabs %}
{% tab title="Swift" %}

```swift
struct TelephonyListToken {
    let items: [PhoneNumber] // Phone numbers
    let nextToken: String? // Reference for next page

}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
data class TelephonyListToken<PhoneNumber>(
    val items: List<PhoneNumber>,
    val nextToken: String?
)
```

{% endtab %}
{% endtabs %}
