Skip to main content

Migrating from 911 Access Dashboard (DASH)

Moving from the DASH API to the Unified Emergency Services Provisioning API on the Bandwidth App? This guide covers everything you need to make the switch.

For the complete API reference, see the ES Provisioning API Reference and the ES Provisioning API Usage Guide.


Before you start

Before writing any code, you need:

  1. A Bandwidth App account : if you don't have one yet, contact your account manager.
  2. Bandwidth App API credentials : your DASH API credentials will not work on the new API. Create new API credentials on your Bandwidth App account (Account > API Credentials) or the Bandwidth API. The Bandwidth App does not support HTTP Basic authentication; you will need to implement OAuth2.
note

You can develop and test against the ES Provisioning API independently of your endpoints migration.


Overview of Changes

DASH APIES Provisioning API
Production Base URLhttps://service.dashcs.com/https://api.bandwidth.com/
Staging Base URLhttps://staging-service.dashcs.com/https://test.api.bandwidth.com
ProtocolREST, SOAPREST
Content typeXMLJSON
AuthenticationHTTP BasicOAuth2
ProcessingSynchronousAsynchronous (with order tracking)
Phone number format11-digitE.164
Region supportNot applicable (US/Canada only)Mandatory region parameter (NA/ROW)

New workflow

The biggest conceptual change is how addresses and endpoints relate to each other.

In DASH, an address and a phone number (URI) are bound together as a single "location". You add a location, then provision it.

In the ES Provisioning API, addresses and endpoints are decoupled. You create an address first, then create an endpoint that links a phone number to that address. Endpoint operations are asynchronous and return an order you must poll for completion.

DASH workflow

  1. Add a location (binds an address to a URI): POST /addlocation
    • Returns a locationId
  2. Provision that location: POST /provisionlocation

ES Provisioning API workflow

  1. Create an address : POST /accounts/{accountId}/emergency/addresses?region=NA
    • Synchronous. Validates the address and returns the address id immediately.
    • The address exists independently and is not yet linked to any phone number.
  2. Create an endpoint : POST /accounts/{accountId}/emergency/endpoints?region=NA
    • Links a phone number to the address (using the address id from step 1) and provisions it in the background.
    • Asynchronous. Returns an orderId.
  3. Poll the order : GET /accounts/{accountId}/emergency/orders/{orderId}/details?region=NA
    • Check until status is COMPLETED (or PARTIAL / FAILED).

Because addresses are decoupled, you can create many addresses up front and reuse them across endpoints. You can also provide a full inline address when creating an endpoint instead of referencing an address id, but creating addresses separately is the recommended pattern.


API calls migration

This section shows the DASH request/response alongside the ES Provisioning API equivalent for each common operation.

note

All ES Provisioning API paths require the ?region=NA query parameter.

Add an address (formerly: Add a location)

What changed:

  • Response includes the unique address id you will use for endpoints
  • Response includes validationStatus: VALID or INVALID, no separate /validateLocation step
  • Addresses are decoupled from phone numbers (no uri parameter)
  • country is now required
  • <type>ADDRESS</type> is no longer needed
  • Field change: community is now city

Request

POST /accounts/{accountId}/emergency/addresses?region=NA
Authorization: Bearer <token>
Content-Type: application/json

{
"id": "home_office",
"description": "Home office, downstairs",
"addressLine1": "14111 NE 145th St",
"addressLine2": "Apt. 8",
"city": "Woodinville",
"state": "WA",
"postalCode": "98072",
"country": "US"
}

Response

{
"id": "homeoffice",
"validationStatus": "VALID",
"address": "14024 NE 181st St, Apt. 8",
"addressLine1": "14024 NE 181st St",
"addressLine2": "Apt. 8",
"houseNumber": "14024",
"predirectional": "NE",
"postdirectional": "",
"streetName": "181st",
"streetSuffix": "ST",
"city": "Woodinville",
"state": "WA",
"postalCode": "98072",
"country": "US",
"description": "Home office, upstairs",
"latitude": "47.732682",
"longitude": "-122.155174",
"created": "2015-03-11T04:09:25.399Z",
"updated": "2016-03-11T04:09:25.399Z"
}

Create an endpoint (formerly: Provision a location)

What changed:

  • Addresses are decoupled from phone numbers, the uri becomes phoneNumber in E.164 format
  • No separate provision step: creating an endpoint links a phone number to an address and activates it
  • The address is referenced by addressId (you can also include a full inline address object)
  • The response is an order acknowledgement, not the final status. You must poll for completion (see Order tracking)
  • You can provision up to 5000 endpoints in one call

Request

POST /accounts/{accountId}/emergency/endpoints?region=NA
Authorization: Bearer <token>
Content-Type: application/json

{
"endpoints": [
{
"phoneNumber": "+15555555555",
"name": "Caller Name",
"lang": "en",
"country": "USA",
"addressId": "7888993"
}
]
}

Response

{
"orderId": "08e0be9a-52fd-45a0-be2e-86835c534aad",
"updatedBy": "joe@crabshack.com",
"orderStatus": "PROCESSING",
"acceptedCount": 1,
"invalidCount": 0,
"updated": "2022-05-18T08:57:04Z",
"totalNumber": 1,
"orderType": "ADD_ENDPOINTS"
}

Query endpoints and addresses (formerly: Query locations by URI)

What changed:

  • DASH had separate endpoints for listing URIs (GET /uris), getting locations for a URI (GET /locationsbyuri), and getting the provisioned location (GET /provisionedlocationbyuri). The ES Provisioning API consolidates all of this into GET /endpoints with optional filters.
  • Address details are not included in the endpoint response, it contains only the address id
  • Phone numbers (formerly URI) now require E.164 format
  • Supports pagination (limit and offset query parameters)
  • Supports filtering (phoneNumber, addressId, callerId)
  • Field change: callername is now name

Request

GET /accounts/{accountId}/emergency/endpoints/?region=NA&phoneNumber=%2B1303555432
Authorization: Bearer <token>

Response

{
"links": [
{ "href": "/endpoints", "rel": "self", "method": "GET" },
{ "href": "/endpoints", "rel": "first", "method": "GET" },
{ "href": "/endpoints?offset=99000&limit=1000", "rel": "last", "method": "GET" },
{ "href": "/endpoints?offset=1000&limit=1000", "rel": "next", "method": "GET" }
],
"endpoints": [
{
"id": "13035554321",
"accountId": "5001232",
"phoneNumber": "+13035554321",
"name": "Joe's Home",
"lang": "fr",
"created": "2016-06-22T16:33:21.959Z",
"updated": "2016-06-22T16:33:21.959Z",
"country": "US",
"addressId": "7888993",
"provisioningStatus": "PROVISIONED"
},
{
"id": "JDF9223kslemm23432",
"accountId": "5001232",
"phoneNumber": "+13035554322",
"name": "Joe's Office",
"lang": "en",
"created": "2015-03-11T04:09:25.399Z",
"updated": "2016-06-22T16:33:27.980Z",
"country": "US",
"addressId": "cafoffice",
"provisioningStatus": "PROVISIONED"
}
]
}

To get the full address details, use the addressId from the endpoint response:

GET /accounts/{accountId}/emergency/addresses/7888993?region=NA
{
"id": "homeoffice",
"validationStatus": "INVALID",
"address": "14024 NE 181st St, Apt. 8",
"addressLine1": "14024 NE 181st St",
"addressLine2": "Apt. 8",
"houseNumber": "14024",
"predirectional": "NE",
"postdirectional": "",
"streetName": "181st",
"streetSuffix": "ST",
"city": "Woodinville",
"state": "WA",
"postalCode": "98072",
"country": "US",
"description": "Home office, upstairs",
"latitude": "47.732682",
"longitude": "-122.155174",
"created": "2015-03-11T04:09:25.399Z",
"updated": "2016-03-11T04:09:25.399Z"
}

Update an endpoint's address

What changed:

  • In DASH, address and URI are bound within a location. To change the address, you create a new location and provision it.
  • In the ES Provisioning API, addresses are decoupled and can be changed with a PATCH request.
  • Endpoint update is asynchronous, it returns an orderId for order tracking.

Request

PATCH /accounts/{accountId}/emergency/endpoints/{endpointId}?region=NA
Authorization: Bearer <token>
Content-Type: application/json

{
"action": "PROVISION",
"addressId": "7888993"
}

Response

{
"orderId": "08e0be9a-52fd-45a0-be2e-86835c534aad",
"updatedBy": "joe@crabshack.com",
"orderStatus": "COMPLETED",
"acceptedCount": 1,
"invalidCount": 0,
"updated": "2022-05-18T08:57:04Z",
"totalNumber": 1,
"orderType": "UPDATE_ENDPOINTS"
}

Delete an address (formerly: Remove a location)

What changed:

  • POSTDELETE
  • You can only delete an address if no endpoints are currently linked to it. Unlink first if needed

Request

DELETE /accounts/{accountId}/emergency/addresses/{addressId}?region=NA

Response

204 No Content

Delete an endpoint (formerly: Remove a URI)

What changed:

  • Unlike DASH's removeUri, deleting an endpoint does not cascade-delete its associated address
  • Endpoint deletion is asynchronous, it returns an orderId for order tracking
  • Bulk deletion supported by passing an array of endpointIds

Request

DELETE /accounts/{accountId}/emergency/endpoints/{endpointId}?region=NA

Response

{
"orderId": "08e0be9a-52fd-45a0-be2e-86835c534aad",
"updatedBy": "joe@crabshack.com",
"orderStatus": "COMPLETED",
"acceptedCount": 1,
"invalidCount": 0,
"updated": "2022-05-18T08:57:04Z",
"totalNumber": 1,
"orderType": "DELETE_ENDPOINTS"
}

Order tracking

On the ES Provisioning API, every endpoint change (add, update, delete) is asynchronous and returns an order.

How it works

  1. You submit a request: POST /accounts/{accountId}/emergency/endpoints?region=NA
  2. The response is 202 Accepted with an orderId and initial orderStatus
  3. You poll regularly until the order reaches a terminal status: GET /accounts/{accountId}/emergency/orders/{orderId}/details?region=NA

Order statuses

StatusMeaning
RECEIVEDOrder accepted, not yet processing
PROCESSINGOrder is being processed
COMPLETEDAll endpoints in the order succeeded
PARTIALSome endpoints succeeded, some failed. Check individual endpoint statuses
FAILEDThe entire order failed

For more details, see the Emergency Services order documentation.


Error handling

The new API uses structured JSON error responses with HTTP status codes.

Error mapping

DASH APIES Provisioning APIMeaning
ParseException400 Bad RequestInvalid phone number format or parameter
NotFoundException404 Not FoundNo data found matching your criteria
LockedException202 Accepted
Order status: PARTIAL or FAILED
Endpoint creation is accepted but the order failed for this endpoint
ProvisionException202 Accepted
Order status: PARTIAL or FAILED
Endpoint creation is accepted but the order failed for this endpoint

Deprecated endpoints

The following DASH API endpoints have no equivalent on the ES Provisioning API:

DASH API endpointNotes
GET /authenticationcheckNo equivalent. Use any read endpoint to verify credentials.
POST /validatelocationNo standalone validation. Validation happens during address creation (POST /addresses).
GET /provisionedlocationhistorybyuri/{uri}No direct equivalent. Use order history (GET /orders/{orderId}/history) for change tracking.

Additional Resources

We hope this guide helps you transition smoothly to the ES Provisioning API. For further details, please refer to the resources below.