Skip to main content

Device Provisioning

Manage physical phones through the API — add devices by MAC address, assign users, customize settings, and monitor provisioning status.

Device Types

Two categories of devices can be provisioned:

  • Deskphones — standalone desk phones with programmable keys, assigned directly to users
  • DECT systems — a base station with paired wireless handsets, where each handset is assigned to a user

Both types follow the same provisioning flow: add the device, assign users, and the phone retrieves its configuration from the provisioning server.

Billing is per user, not per device

The typical deployment is 1:1 user-to-device, but you can assign multiple users to a single device (shared reception phone, multi-line executive desk setup, etc.) or the same user to multiple devices. DialStack bills for each user provisioned on the system, regardless of how users and devices are paired.

How Provisioning Works

  1. Add the device — create a device via the API with its MAC address and type. The vendor is automatically detected from the MAC.
  2. Assign users — assign users to the device so it can make and receive calls.
  3. Device fetches config — when the phone powers on (or is triggered via check-sync), it contacts the provisioning server and receives its configuration.
  4. Status updates — the device status transitions from pending-sync to provisioned after its first successful configuration fetch.

Settings Inheritance

Device configuration follows a layered inheritance model:

Global defaults → Platform config → Account config → Device overrides

Each layer can override settings from the layer above. Omitted fields inherit from the parent, so you only need to specify what you want to change.

Prerequisites

  • An API key with account access
  • The MAC address of the physical device
  • At least one user to assign to the device

Provisioning a Deskphone

Step 1: Create the deskphone

Register the device with its MAC address:

curl -X POST https://api.dialstack.ai/v1/devices \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "deskphone",
"mac_address": "00:04:13:aa:bb:cc"
}'
{
"id": "YOUR_DEVICE_ID",
"type": "deskphone"
}

The vendor is detected automatically based on the MAC address prefix (OUI). The model is detected when the device first contacts the provisioning server. Use GET /v1/devices/YOUR_DEVICE_ID to retrieve the full device details.

Step 2: Assign a user

curl -X POST https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/users \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"user_id": "YOUR_USER_ID"
}'
{
"user_id": "YOUR_USER_ID",
"device_id": "YOUR_DEVICE_ID",
"created_at": "2025-10-18T10:01:00Z"
}

Each user assignment consumes one line appearance on the phone — an individually-registered SIP account, shown as a distinct "line" on the phone's display. DialStack caps deskphones at 24 line appearances, but the practical limit is what the phone model itself supports (ranges from 2 lines on entry-level handsets to 16+ on high-end executive phones). Assignments beyond the phone's hardware capacity will be accepted by the API but not all will appear on the device. Consult the phone vendor's datasheet for the supported line count.

Step 3: Trigger configuration reload

If the phone is already powered on, send a check-sync to have it reload its configuration:

curl -X POST https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/status/check-sync \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"
{
"success": true,
"lines_notified": 1,
"lines": [
{
"line_number": 1,
"status": "delivered"
}
]
}

A 200 response means at least one line accepted the request. Each entry in lines carries a 1-indexed line_number and a status — one of delivered, not_registered, unreachable, or error.

What check-sync does (and doesn't do)

Trigger check-sync when you actually change configuration, not on every admin-UI interaction. A 200 OK only means the phone accepted the request — what happens next depends on the phone, the firmware, and sometimes the call state at that exact moment.

With reboot: false (the default), the typical behavior is:

  • The phone reloads configuration in place and stays registered, with a brief (usually under 5 seconds) re-registration if the SIP server or credentials changed.
  • Some phones defer applying new configuration while a call is in progress, so the change may not take effect until the call ends.
  • Some settings (firmware, certain network parameters) still require a reboot, which the phone performs on its next idle window.
  • For DECT, the request reaches the base no matter which ID you target (base or handset), and every handset paired with the base reloads.

reboot: false is not a guarantee that the phone keeps its calls. Some models — particularly certain DECT bases — reboot on every check-sync regardless of the flag, drop active calls, and take 30–90 seconds to come back. Treat any check-sync as potentially disruptive, and only send it when configuration actually changed.

With reboot: true:

  • The phone reboots immediately, dropping any active call.
  • Roughly 30–90 seconds offline.
  • Only use for recovery or for changes that explicitly require a reboot.

If the device could not be reached, the API returns 409 Conflict with a reason field:

  • not_registered — the device has no active registration. It may be powered off, unable to reach the SIP server, or has never registered.
  • unreachable — the device didn't respond in time. It is likely offline or has lost its connection.

Step 4: Verify provisioning

curl https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"

After the device fetches its configuration, status changes to provisioned and last_provisioned_at is populated.

Provisioning a DECT System

DECT systems have a two-level hierarchy: base stationhandsets. Each handset is then assigned to one or more users.

Step 1: Create the DECT base

curl -X POST https://api.dialstack.ai/v1/devices \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "dect_base",
"mac_address": "00:04:13:bb:cc:dd"
}'
{
"id": "YOUR_BASE_ID",
"type": "dect_base"
}

Step 2: Add a handset

Each handset is identified by its IPEI (a unique hardware identifier for wireless handsets, formatted as a hexadecimal string). Handsets are created as devices linked to their parent base.

curl -X POST https://api.dialstack.ai/v1/devices \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "dect_handset",
"base_id": "YOUR_BASE_ID",
"ipei": "0328A0000F",
"display_name": "Front Desk"
}'
{
"id": "YOUR_HANDSET_ID",
"type": "dect_handset"
}

Step 3: Assign a user to the handset

Users are assigned to individual handsets, not to the base station directly.

curl -X POST https://api.dialstack.ai/v1/devices/YOUR_HANDSET_ID/users \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"user_id": "YOUR_USER_ID"
}'
{
"user_id": "YOUR_USER_ID",
"device_id": "YOUR_HANDSET_ID",
"created_at": "2025-10-18T10:03:00Z"
}

Customizing Device Settings

Use the overrides field to customize device behavior. Settings use a two-tier structure:

  • abstractions — vendor-agnostic settings that are translated to vendor-specific parameters automatically
  • vendor_overrides — raw vendor-specific key-value pairs for parameters not covered by abstractions
curl -X POST https://api.dialstack.ai/v1/deskphones/YOUR_DEVICE_ID \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"overrides": {
"abstractions": {
"audio": {
"codecs": ["PCMU", "PCMA"],
"echo_cancellation": true
},
"display": {
"time_format": "24h",
"backlight_level": "medium"
}
}
}
}'
note

The abstractions schema is actively expanding as new hardware capabilities are added. Use vendor_overrides for vendor-specific parameters not yet available as abstractions.

Multicell DECT Deployments

For larger spaces requiring multiple base stations, use multicell roles to coordinate them:

  • data_master — the primary base that distributes configuration to other bases
  • secondary — subordinate bases that receive configuration from the data master
curl -X POST https://api.dialstack.ai/v1/devices \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{
"type": "dect_base",
"mac_address": "00:04:13:bb:cc:ee",
"multicell_role": "secondary"
}'

Managing Devices

Unified Device View

List all devices (deskphones and DECT bases) in a single request:

curl "https://api.dialstack.ai/v1/devices?type=deskphone" \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"

The type parameter is optional — omit it to list all device types.

Listing Users on a Device

curl https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/users \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"

Removing a User from a Device

curl -X DELETE https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/users/YOUR_USER_ID \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"

Deleting a Device

curl -X DELETE https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"

Deleting a device removes all associated user assignments. Deleting a DECT base also removes all its handsets.