Bandwidth Portout Passcode Protection

This walks through how to programmatically add a "Passcode" to protect phone numbers from unauthorized port outs. When a phone number with a Passcode protection receives a port out request, the winning carrier (or customer) must provide a Passcode along with the port request. Bandwidth will then verify the Passcode provided by the winning carrier to the Passcode set on the phone number before allowing the port. Mis-matches will automatically fail to port and alert the winning carrier that the Passcode was incorrect and to please try again with an updated Passcode.

Assumptions

API Authentication

The Numbers API resources are authenticated with your API Credentials for "Number & Account Management".

Setting Portout Passcode on Numbers

Portout PINs are set via the tnoptions API

Endpoint Description
/tnoptions Set the Passcode code for an individual (or group) of phone Numbers

Create tnoptions order

The /tnoptions endpoint is an interface for adding/removing "options/features" from specific (or groups) of phone numbers

TnOption Parameters for Portout Passcode protections

Request URL

POSThttps://dashboard.bandwidth.com/api/accounts/{{accountId}}/tnoptions

Request Authentication

The tnoptions resource is authenticated with your API Credentials for "Number & Account Management"

There are more options unrelated to Portout Passcodes that are detailed in the API Reference

Parameters Mandatory Description
<TnOptionGroups> Yes list of <TnOptionGroup>s
<TnOptionGroup> Yes Container for the option order details
<CustomerOrderId> Yes Customer identifier specified in the request, can be used for later lookups
<PortOutPasscode> Yes The actual passcode to set for the phone numbers in <TelephoneNumbers>
<TelephoneNumbers> Yes list of <TelephoneNumber>s
<TelephoneNumber> Yes The individual number to apply the Passcode

Example 1 of 2: Set PortOutPasscode on a single Telephone Number

POST https://dashboard.bandwidth.com/api/accounts/{{accountId}}/tnoptions HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

<TnOptionOrder>
    <CustomerOrderId>TnOptionOrder1</CustomerOrderId>
    <TnOptionGroups>
        <TnOptionGroup>
            <PortOutPasscode>a1b2c3</PortOutPasscode>
            <TelephoneNumbers>
                <TelephoneNumber>2018551020</TelephoneNumber>
            </TelephoneNumbers>
        </TnOptionGroup>
    </TnOptionGroups>
</TnOptionOrder>

Responds

HTTP/1.1 201 Created
Content-Type: application/xml
Location: https://dashboard.bandwidth.com:443/v1.0/accounts/{{accountId}}/tnoptions/{{order-id}}

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TnOptionOrderResponse>
    <TnOptionOrder>
        <CustomerOrderId>TnOptionOrder1</CustomerOrderId>
        <OrderCreateDate>2020-05-22T18:22:34.391Z</OrderCreateDate>
        <AccountId>{{accountId}}</AccountId>
        <CreatedByUser>{{your-user}}</CreatedByUser>
        <OrderId>68498567-9ef8-4b43-a9a1-f8a507c059fe</OrderId>
        <LastModifiedDate>2020-05-22T18:22:34.391Z</LastModifiedDate>
        <ProcessingStatus>RECEIVED</ProcessingStatus>
        <TnOptionGroups>
            <TnOptionGroup>
                <PortOutPasscode>a1b2c3</PortOutPasscode>
                <TelephoneNumbers>
                    <TelephoneNumber>2018551020</TelephoneNumber>
                </TelephoneNumbers>
            </TnOptionGroup>
        </TnOptionGroups>
        <ErrorList/>
    </TnOptionOrder>
</TnOptionOrderResponse>
$tnoptions = $account->tnoptions();
$data = array(
    "TnOptionGroups" => array(
        "TnOptionGroup" => array(
            "PortOutPasscode" => "a1b2c3",
            "TelephoneNumbers" => array(
                "TelephoneNumber" => "2018551020"
            )
        ),
    )
);
$response = $tnoptions->create($data);
print_r($response->OrderCreateDate);

Output

2020-05-22T18:22:34.391Z
data = {
  :customer_order_id => "custom order",
  :tn_option_groups => {
    :tn_option_group => [
      {
        :port_out_passcode => "a1b2c3",
        :telephone_numbers => {
          :telephone_number => ["2018551020"]
        }
      }
    ]
  }
}

order = BandwidthIris::TnOptions.create_tn_option_order(data)
puts order[:order_create_date]

Output

2020-05-22T18:22:34.391Z
TnOptionOrder order = new TnOptionOrder();
order.setTnOptionGroups(new ArrayList<>());
order.setCustomerOrderId("TnOptionOrder1");

TnOptionGroup optionGroup = new TnOptionGroup();
optionGroup.setPortOutPasscode("a1b2c3");// PortOutPasscode set here
optionGroup.setTelephoneNumbers(new ArrayList<>());
optionGroup.getTelephoneNumbers().add("2018551020");

order.getTnOptionGroups().add(optionGroup);

TnOptionOrderResponse response = TnOptions.create(client, order);

Output

hello world
const order = {
  customerOrderId: 'TnOptionOrder1',
  tnOptionGroups: [
    {
      portOutPasscode: 'a1b2c3',
      telephoneNumbers: ['2018551020']
    }
  ]
}
numbers.TnOption.create(order, (err, res) => {
  if (err) {
    return console.log(err)
  }
  console.log(res.orderId)
  return console.log(res.processingStatus)
});

Output

ddbdc72e-dc27-490c-904e-d0c11291b095
RECEIVED
var order = new TnOptionOrder
{
    CustomerOrderId = "TnOptionOrder1",
    TnOptionGroups = new List<TnOptionGroup>
    {
        new TnOptionGroup {
            PortOutPasscode = "a1b2c3",
            TelephoneNumbers = new List<string>
            {
                "2018551020"
            }
        }
    }
};

var response = await TnOptions.Create(client, order);

Console.WriteLine(response.TnOptionOrder.OrderCreateDate);//"2016-01-15T12:01:14.324Z"

Output

hello world

Example 2 of 2: Set same PortOutPasscode on a group of Telephone Numbers

POST https://dashboard.bandwidth.com/api/accounts/{{accountId}}/tnoptions HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

<TnOptionOrder>
    <CustomerOrderId>TnOptionOrder1</CustomerOrderId>
    <TnOptionGroups>
        <TnOptionGroup>
            <PortOutPasscode>a1b2c3</PortOutPasscode>
            <TelephoneNumbers>
                <TelephoneNumber>2018551020</TelephoneNumber>
                <TelephoneNumber>2018551022</TelephoneNumber>
                <TelephoneNumber>2018551023</TelephoneNumber>
            </TelephoneNumbers>
        </TnOptionGroup>
    </TnOptionGroups>
</TnOptionOrder>

Responds

HTTP/1.1 201 Created
Content-Type: application/xml
Location: https://dashboard.bandwidth.com:443/v1.0/accounts/{{accountId}}/tnoptions/{{order-id}}

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TnOptionOrderResponse>
    <TnOptionOrder>
        <CustomerOrderId>TnOptionOrder1</CustomerOrderId>
        <OrderCreateDate>2020-05-22T18:22:34.391Z</OrderCreateDate>
        <AccountId>{{accountId}}</AccountId>
        <CreatedByUser>{{your-user}}</CreatedByUser>
        <OrderId>553b1243-8ab2-412e-a4eb-eedd76b6a183</OrderId>
        <LastModifiedDate>2020-05-22T18:22:34.391Z</LastModifiedDate>
        <ProcessingStatus>RECEIVED</ProcessingStatus>
        <TnOptionGroups>
            <TnOptionGroup>
                <PortOutPasscode>a1b2c3</PortOutPasscode>
                <TelephoneNumbers>
                  <TelephoneNumber>2018551020</TelephoneNumber>
                  <TelephoneNumber>2018551022</TelephoneNumber>
                  <TelephoneNumber>2018551023</TelephoneNumber>
                </TelephoneNumbers>
            </TnOptionGroup>
        </TnOptionGroups>
        <ErrorList/>
    </TnOptionOrder>
</TnOptionOrderResponse>
$tnoptions = $account->tnoptions();
$data = array(
    "TnOptionGroups" => array(
        "TnOptionGroup" => array(
            "PortOutPasscode" => "a1b2c3",
            "TelephoneNumbers" => array(
                "TelephoneNumber" => array(
                    "2018551020",
                    "2018551022",
                    "2018551023"
                )
            )
        ),
    )
);
$response = $tnoptions->create($data);
print_r($response->OrderCreateDate);

Output

2020-05-22T18:22:34.391Z
data = {
  :customer_order_id => "custom order",
  :tn_option_groups => {
    :tn_option_group => [
      {
        :port_out_passcode => "a1b2c3",
        :telephone_numbers => {
          :telephone_number => ["2018551020", "2018551022", "2018551023"]
        }
      }
    ]
  }
}

order = BandwidthIris::TnOptions.create_tn_option_order(data)
puts order[:order_create_date]

Output

2020-05-22T18:22:34.391Z
TnOptionOrder order = new TnOptionOrder();
order.setTnOptionGroups(new ArrayList<>());
order.setCustomerOrderId("TnOptionOrder1");

TnOptionGroup optionGroup = new TnOptionGroup();
optionGroup.setPortOutPasscode("a1b2c3");// PortOutPasscode set here
optionGroup.setTelephoneNumbers(new ArrayList<>());
optionGroup.getTelephoneNumbers().add("2018551020");
optionGroup.getTelephoneNumbers().add("2018551022");
optionGroup.getTelephoneNumbers().add("2018551023");

order.getTnOptionGroups().add(optionGroup);

TnOptionOrderResponse response = TnOptions.create(client, order);

Output

hello world
var order = new TnOptionOrder
{
    CustomerOrderId = "TnOptionOrder1",
    TnOptionGroups = new List<TnOptionGroup>
    {
        new TnOptionGroup {
            PortOutPasscode = "a1b2c3",
            TelephoneNumbers = new List<string>
            {
                "2018551020",
                "2018551022",
                "2018551023"
            }
        }
    }
};

var response = await TnOptions.Create(client, order);

Console.WriteLine(response.TnOptionOrder.OrderCreateDate);//"2016-01-15T12:01:14.324Z"

Output

hello world

results matching ""

    No results matching ""