Bandwidth Customer Service Records (CSR) Lookup API
This walks through how to programmatically lookup Customer Service Records (CSRs for short) for Phone Numbers before porting into your Bandwidth account.
Assumptions
- Familiarity with Account API Credentials
- Created an API Credential Pair within the UI
- Account enabled for CSR Lookup (please contact support)
API Authentication
The Numbers API resources are authenticated with your API Credentials for "Number & Account Management".
Table of Contents
- Create Subscription for CSR Order Updates
- Create a CSR Order
- Receive callback for the CSR Order
- Fetch Order Status
Next Steps
Once the CSR record have been pulled, phone numbers are ready to create a port order with the validated CSR information.
Importing Phone Numbers Overview
There are 3 different APIs that you will use to manage csr lookup orders:
Endpoint | Description |
---|---|
/subscriptions |
Setup Bandwidth to send HTTP Callbacks to your server as the status updates |
/csrs |
Create the CSR lookup order. |
/csrs/{orderId} |
Fetch information about the CSR lookup and order status |
Create Subscription for csrs
The Subscription contains the HTTP URL to receive HTTP Callbacks/webhooks anytime there is an update to the csrs
status.
Creating the subscription should generally only be needed once per account depending on the <Expiry>
time set when creating the subscription. Bandwidth allows very large integer values such as (99 years = 3122064000
) seconds to essentially allow for the subscription to persist.
Learn more about subscriptions in the documentation.
Subscription Parameters
Request URL
POST
https://dashboard.bandwidth.com/api/accounts/{{accountId}}/subscriptions
Request Authentication
The Subscriptions resource is authenticated with your API Credentials for "Number & Account Management"
Parameters | Mandatory | Description |
---|---|---|
<OrderType> |
Yes, set to csrs |
The type of Order of the subscription, set to csrs for this guide. |
<CallbackSubscription> |
Yes | Container for the callback details |
<Expiry> |
Yes | The time in seconds to persist the subscription. Bandwidth recommends setting the <Expiry> value to a very large integer to prevent the subscription from expiring in the next decade or so. Example Times
|
<URL> |
Yes | Url to receive callbacks for the specified orderId or orderType |
<CallbackCredentials> |
No, but highly recommended | Container for the Auth |
<BasicAuthentication> |
- | Basic auth credentials to apply to your message & voice events |
Username |
No, but highly recommended | Basic auth Username |
Password |
No, but highly recommended | Basic auth Password |
<PublicKey> |
No | BASE64 encoded public key matching the notification receiving server |
Create Subscription
POST https://dashboard.bandwidth.com/api/accounts/{{accountId}}/subscriptions HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
<Subscription>
<OrderType>csrs</OrderType>
<CallbackSubscription>
<URL>{your-callback-url}</URL>
<Expiry>3153600000</Expiry>
<CallbackCredentials>
<BasicAuthentication>
<Username>User15</Username>
<Password>Hunter15</Password>
</BasicAuthentication>
</CallbackCredentials>
</CallbackSubscription>
</Subscription>
Response
HTTP/1.1 201 Created
Content-Type: application/xml
Location: https://dashboard.bandwidth.com/api/accounts/{{accountId}}/subscriptions/{{applicationID}}
$subscription = $account->subscriptions()->create([
"OrderType" => "csrs",
"CallbackSubscription" => [
"URL" => "{your-callback-url}"
]
]);
print_r($subscription->SubscriptionId);
Output
390-f-42-89-40
subscription = {
:order_type => "csrs",
:callback_subscription => {
:URL => "https://test4.com"
}
}
response = BandwidthIris::Subscription.create(subscription)
puts response.to_data()[:subscription_id]
Output
390-f-42-89-40
CallbackSubscription callbackSubscription = new CallbackSubscription();
callbackSubscription.setURL("http://example.com");
Subscription subscription = new Subscription();
subscription.setOrderType("csrs");
subscription.setCallbackSubscription(callbackSubscription);
Subscription newSubscription = Subscription.create(client, subscription);
System.out.println(newSubscription.getSubscriptionId());
Output
390-f-42-89-40
var subscription = new Subscription
{
CallbackSubscription = new CallbackSubscription
{
Url = "https://test4.com"
},
OrderType = "csrs"
};
var response = await Subscription.Create(subscription);
Console.WriteLine(response.SubscriptionId);
Output
390-f-42-89-40
const subscriptionData = {
orderType:"csrs",
callbackSubscription: {
URL:"http://mycallbackurl.com",
user:"userid",
expiry: 12000
}
};
try {
const subscription = await numbers.Subscription.createAsync(subscriptionData);
console.log(subscription.id);
}
catch (e) {
console.log(e)
}
Output
390-f-42-89-40
Create a CSR Order
Before creating the order, be sure to collect any information from the end user to submit to the CSR API. Generally speaking, the more information provided, the better.
- Address
- AccountNumber
- PIN Numbers
- More (see table below for options)
CSR Request Parameters
Request URL
POST
https://dashboard.bandwidth.com/api/accounts/{{accountId}}/csrs
Parameter | Mandatory | Description |
---|---|---|
accountId (URL Parameter) | Yes | The account ID for creating csr order. |
CustomerOrderId | No | Internal customer order id for tracking the order. Only alphanumeric values, dashes and spaces are allowed. Max length is 40 characters. |
WorkingOrBillingTelephoneNumber (WTN) | Yes | Working or Billing telephone number in 10-digits format NPANXXXXXX. |
AccountNumber | No | Identifies the main account number on your bill, assigned by the current service provider. Alphanumeric characters are supported with a max length of 20 characters. |
AccountTelephoneNumber | No | Identifies the account telephone number assigned by the current service provider. Alphanumeric characters are supported with a max length of 10 characters. |
EndUserName | No | Identifies the name of the end user associated with the telephone number being queried. Alphanumeric characters are supported with a max length of 100 characters. |
AuthorizingUserName | No | Identifies the name of the end user who signed the authorization. Alphanumeric characters are supported with a max length of 100 characters. |
CustomerCode | No | Identifies the customer code associated with the service provider. Must be numeric characters only with a max length of 3 characters. |
EndUserPIN | No | Identifies the end user’s personal identification number (PIN). Alphanumeric characters are supported with a max length of 50 characters. |
EndUserPassword | No | Identifies the end user’s password to access the CSR, if applicable. Alphanumeric characters are supported with a max length of 100 characters. |
AddressLine1 | No | Identifies the address line 1 portion of the service address. Alphanumeric characters are supported with a max length of 200 characters. |
City | No | Identifies the city of the end user where the telephone number is being serviced. Alphanumeric characters are supported with a max length of 100 characters. |
State | No | Identifies the abbreviation for the state or province of the end user where the telephone number is being serviced. Must be alpha characters only in the format XX with a max length of 2 characters, where XX is the state or province abbreviation. |
ZIPCode | No | Identifies the ZIP code, ZIP Code + extension, or postal code or the end user where the telephone number is being serviced. Alphanumeric characters are supported with a max length of 10 characters (including the dash if using ZIP Code with extension). |
TypeOfService | No | The type of service identifying the end user account. Must be alphabetic characters only with a max length of 50 characters. |
Create CSR Order
POST https://dashboard.bandwidth.com/api/accounts/{{accountId}}/csrs HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
<Csr>
<CustomerOrderId>CustomerOrderId</CustomerOrderId>
<WorkingOrBillingTelephoneNumber>9198675309</WorkingOrBillingTelephoneNumber>
<EndUserPIN>1234</EndUserPIN>
</Csr>
Response
HTTP/1.1 200 OK
Content-Type: application/xml
Location: https://dashboard.bandwidth.com/api/accounts/{{accountId}}/csrs/{{orderId}}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CsrResponse>
<OrderId>18cee9d0-a5c5-4322-9a47-d04176bc924c</OrderId>
<Status>RECEIVED</Status>
</CsrResponse>
$csrOrder = new \Iris\Csr(array(
"CustomerOrderId" => "order id",
"WorkingOrBillingTelephoneNumber" => "5554443333"
));
$response = $account->createCsrOrder($csrOrder);
print_r($response->OrderId);
Output
18cee9d0-a5c5-4322-9a47-d04176bc924c
csr_data = {
:customer_order_id => "order id",
:working_or_billing_telephone_number => "5554443333"
}
response = BandwidthIris::Csr.create(csr_data)
puts response[0][:order_id]
Output
18cee9d0-a5c5-4322-9a47-d04176bc924c
Csr csr = new Csr();
csr.setCustomerOrderId("order id");
csr.setWorkingOrBillingTelephoneNumber("5554443333");
CsrResponse response = Csr.Create(client, csr);
System.out.println(response.getOrderId())
Output
18cee9d0-a5c5-4322-9a47-d04176bc924c
var csr = new Csr
{
CustomerOrderId = "order id",
WorkingOrBillingTelephoneNumber = "5554443333",
};
var response = await Csr.Create(csr);
Console.WriteLine(response.OrderId);
Output
18cee9d0-a5c5-4322-9a47-d04176bc924c
const data = {
customerOrderId: "MyId5",
WorkingOrBillingTelephoneNumber:"9198675309",
accountNumber:"123463",
endUserPIN:"1231"
};
try {
const csrOrderResponse = await numbers.CsrOrder.createAsync(data);
console.log(csrOrderResponse.orderId);
//31e0b16b-4720-4f2e-bb99-1399eeb2ff9e
}
catch (e) {
console.log(e);
}
Output
18cee9d0-a5c5-4322-9a47-d04176bc924c
Receive callback for the CSR Order
Anytime the status of the order is updated (COMPLETE
, FAILED
, ACTION_REQUIRED
etc...) Bandwidth will send an HTTP callback/webhook to the URL specified in the subscription.
Bandwidth expects an HTTP-2xx response to any callbacks.
Callback Parameters
Request URL
POST
{{your-callback-url_as-defined-in-the-subscription}}
Parameter | Description |
---|---|
<SubscriptionId> |
Subscription ID that the notification is in response to. |
<OrderType> |
Will be importtnorders |
<OrderId> |
ID of the importTNOrder |
<CustomerOrderId> |
Custom Order Id defined when creating the importTnOrder |
<Status> |
The newly updated status reflecting the state of the importTnOrder |
<Message> |
Description about the status |
<Note> |
Custom note added when updating or creating the importTnOrder |
A small example leveraging express & body-parser-xml to handle callbacks
Express setup
const express = require("express");
const app = express();
const http = require("http").Server(app);
app.set('port', (process.env.PORT || 3000));
const bodyParser = require("body-parser");
require('body-parser-xml')(bodyParser);
app.use(bodyParser.xml());
Example 1 of 2: Receive Successful Callback to your server
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>COMPLETE</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request is complete.</Message>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<OrderType>csrs</OrderType>
</Notification>
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>COMPLETE</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request is complete.</Message>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>COMPLETE</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request is complete.</Message>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>COMPLETE</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request is complete.</Message>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>COMPLETE</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request is complete.</Message>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
app.post('/csrUpdate', (req, res) => {
console.log(req.body);
// {
// Notification: {
// Status: [ 'COMPLETE' ],
// SubscriptionId: [ '4a7e2ee1-224e-4ee9-8edf-97a149d23dd4' ],
// Message: [ '26500: CSR is not available for this TN' ],
// OrderId: [ '7182a3b7-0f16-444a-8d2f-a1220f5b00a5' ],
// OrderType: [ 'csrs' ],
// CustomerOrderId: [ 'MyId5' ]
// }
// }
res.sendStatus(200);
});
Response as generated by your server
HTTP/1.1 200 OK
Example 2 of 2: Receive Failed Callback to your server
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>FAILED</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request has failed.</Message>
<OrderId>91e7298a-0942-47e4-996b-788da5544b6b</OrderId>
<OrderType>csrs</OrderType>
</Notification>
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>FAILED</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request has failed.</Message>
<OrderId>91e7298a-0942-47e4-996b-788da5544b6b</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>FAILED</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request has failed.</Message>
<OrderId>91e7298a-0942-47e4-996b-788da5544b6b</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>FAILED</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request has failed.</Message>
<OrderId>91e7298a-0942-47e4-996b-788da5544b6b</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
POST https://your-callback-url_as-defined-in-the-subscription HTTP/1.1
Content-Type: application/xml; charset=utf-8
Authorization: {subscription_user:subscription_password}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification>
<Status>FAILED</Status>
<SubscriptionId>bfdf89f4-8d0c-4415-a203-ceb7afe00f88</SubscriptionId>
<Message>The CSR request has failed.</Message>
<OrderId>91e7298a-0942-47e4-996b-788da5544b6b</OrderId>
<OrderType>csrs</OrderType>
</Notification>
Your Server should respond with a 200-OK message
app.post('/csrUpdate', (req, res) => {
console.log(req.body);
// {
// Notification: {
// Status: [ 'FAILED' ],
// SubscriptionId: [ '4a7e2ee1-224e-4ee9-8edf-97a149d23dd4' ],
// Message: [ '26500: CSR is not available for this TN' ],
// OrderId: [ '7182a3b7-0f16-444a-8d2f-a1220f5b00a5' ],
// OrderType: [ 'csrs' ],
// CustomerOrderId: [ 'MyId5' ]
// }
// }
res.sendStatus(200);
});
Response as generated by your server
HTTP/1.1 200 OK
Fetch Order Status
At anytime, you're able to get the order status by creating a GET request to the order-id returned when creating the CSR order.
You'll need to fetch the order status for both FAILED
and COMPLETE
CSR order statuses for more detail on the CSR request.
Request URL
GET
https://dashboard.bandwidth.com/api/accounts/{{accountId}}/csrs/{{orderId}}
Response Parameters
Parameters | Description |
---|---|
<CustomerOrderId> |
Custom OrderId provided when creating the order |
<OrderCreateDate> |
Date order was created |
<AccountId> |
AccountId for the import TN order |
<CreatedByUser> |
User that created the import TN Order |
<OrderId> |
Id of import TN order |
<LastModifiedDate> |
The last time the import TN order was updated |
<Status> |
The current status of the import TN order. The LastModifiedDate indicates when the status was updated |
<CsrData> |
The complete CSR data from the lookup request. The element will contain sub-elements such as:
|
<Errors> |
Any errors that occured during the request |
Example 1 of 2: Fetch Successful CSR Order Status
GET https://dashboard.../{{accountId}}/csrs/{{orderId}} HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Response
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CsrResponse>
<LastModifiedBy>{api-userName}</LastModifiedBy>
<OrderCreateDate>2020-02-25T15:39:22.079Z</OrderCreateDate>
<AccountId>{accountId}</AccountId>
<OrderId>20ba7d26-7fa0-4716-ab45-6c8e07d37862</OrderId>
<LastModifiedDate>2020-02-25T15:39:41.166Z</LastModifiedDate>
<Status>COMPLETE</Status>
<CsrData>
<CustomerName>House of Mouse</CustomerName>
<ServiceAddress>
<UnparsedAddress>1234 Main ST Durham NC 27707</UnparsedAddress>
<HouseNumber>1234</HouseNumber>
<StreetName>Main</StreetName>
<StreetSuffix>ST</StreetSuffix>
<City>Durham</City>
<State>NC</State>
<Zip>27707</Zip>
</ServiceAddress>
<WorkingTelephoneNumber>9198675309</WorkingTelephoneNumber>
<WorkingTelephoneNumbersOnAccount>
<TelephoneNumber>9198675309</TelephoneNumber>
</WorkingTelephoneNumbersOnAccount>
</CsrData>
</CsrResponse>
$response = $account->getCsrOrder("csr_id");
print_r($response->CsrData->CustomerName);
Output
House of Mouse
response = BandwidthIris::Csr.get("csr_id")
puts response[0][:csr_data][:customer_name]
Output
House of Mouse
CsrResponse response = Csr.Get(orderId);
System.out.println(response.getCustomerName());
Output
House of Mouse
var response = await Csr.Get(client, orderId);
Console.WriteLine(response.CustomerName);
Output
House of Mouse
const csrId = "csr_id"
try {
const csrOrderData = await numbers.CsrOrder.getAsync(client, csrId);
console.log(csrOrderData.csrData.customerName);
}
catch (e) {
console.log(e);
}
Output
House of Mouse
Example 2 of 2: Fetch Failed CSR Order Status
GET https://dashboard.../{{accountId}}/csrs/{{orderId}} HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Response
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CsrResponse>
<Errors>
<Error>
<Code>26500</Code>
<Description>CSR is not available for this TN</Description>
</Error>
</Errors>
<LastModifiedBy>{api-userName}</LastModifiedBy>
<OrderCreateDate>2020-02-25T15:16:42.196Z</OrderCreateDate>
<AccountId>{accoundId}</AccountId>
<OrderId>2c61ed2d-a8d7-4b78-8b5a-dcded8390ec8</OrderId>
<LastModifiedDate>2020-02-25T15:16:42.841Z</LastModifiedDate>
<Status>FAILED</Status>
<CsrData>
<WorkingTelephoneNumber>9198675309</WorkingTelephoneNumber>
</CsrData>
</CsrResponse>
$response = $account->getCsrOrder($bad_order_id);
print_r($response->Errors->Error->Description);
Output
CSR is not available for this TN
begin
response = BandwidthIris::Csr.get(bad_order_id)
puts response
rescue => e
puts e
end
Output
CSR is not available for this TN
CsrResponse response = Csr.Get(client, badOrderId);
System.out.println(response.getErrors()[0].getDescription());
Output
CSR is not available for this TN
CsrResponse result = null;
try {
result = Csr.Get(client, orderId).Result;
} catch(Exception e)
{
Console.WriteLine(e.InnerException.Message);
}
Output
CSR is not available for this TN
const csrOrderId = "1234-abc"
try {
const csrOrderData = await CsrOrder.getAsync(csrOrderId);
console.log(csrOrderData.status);
//Won't fire, as request is failed
}
catch (e) {
console.log(e);
}
Output
[BandwidthError: CSR is not available for this TN] {
code: 26500,
message: 'CSR is not available for this TN',
httpStatus: 200
}