Hot Desking
Hot desking lets a user log in on a phone that isn't theirs. For the length of the session the phone rings and dials as that user: their extension, their caller ID, their voicemail indicator, their programmable buttons. When the session ends the phone goes back to how it was.
The feature is built for shared phones: a front desk staffed in shifts, a nursing station, a bank of desks that nobody owns. A user logs in at the start of a shift and out at the end, or the session simply expires.
How a session works
A user rings and dials from one phone at a time: the phone they are logged in on while they have a session, and their own phone otherwise.
A hot-desk session is an overlay on the phone's permanent assignment. Nothing permanent changes:
- The phone keeps the user it is assigned to (if any). While a session is active that user's line is hidden, and the phone serves the logged-in user instead. When the session ends the permanent user is back, with no action required.
- The logged-in user keeps their own phone, if they have one. While they are logged in elsewhere their own phone is logged out: it doesn't ring and can't place ordinary calls. It serves them again as soon as the session ends.
- The logged-out state takes effect when that phone picks up its new configuration, normally within moments of the login. Until it does, the phone still works as the user, and a 911 call placed from it in that window dispatches to the address of the phone the user is logged in on, which can be another office. If you hot-desk across sites, make sure phones stay reachable for configuration updates.
- Call history, call webhooks and recordings attribute the phone's calls to the logged-in user, not to the phone's permanent user.
A user holds at most one session at a time. Logging in on a second phone moves them: the first session ends and the new one starts. Logging a second user in on a phone that already has a session replaces the first user, whose session ends.
Logging a user in on their own permanently assigned phone, while nobody else is logged in on it, starts no session: there is nothing to overlay. If they were logged in somewhere else, that session ends so their phone serves them again. If someone else is logged in on their phone, logging the owner in replaces that session with one of their own, which expires like any other.
What a logged-out phone can do
A phone with no user, whether it never had one or its user is logged in elsewhere, is not dead. It stays registered and can:
- dial 911 and the 933 test line, using the phone's own dispatch address;
- dial
*11to log a user in (and*12, which simply reports that nobody is logged in).
Every other call is refused, and the phone receives no calls.
Session length
Sessions expire after the account's hot-desk session length, counted from login. The default is 480 minutes (eight hours), the maximum 1440, and 0 means sessions never expire. Expiry is checked once a minute, so a session can outlast its length by up to about a minute.
The length is read at login and stored on the session as expires_at, so changing the setting affects the next login, not sessions already running. Logging the same user in again on the same phone refreshes expires_at without starting a new session.
Set it with hot_desk_max_session_minutes in the account's config (Accounts API), or under Hot Desking on the account's Devices tab in the admin portal.
Supported phones
Hot desking works on deskphones and on DECT handsets paired to a base. A DECT base itself can't be hot-desked, and softphones don't take part: a session puts a user on a physical phone.
The login codes work from any provisioned deskphone or paired DECT handset, whether or not it has a user.
Logging in from the phone
Two star codes are provisioned on every phone:
| Code | Action |
|---|---|
*11 | Log in. The phone asks for an extension, then for that user's voicemail PIN. |
*11<ext> | Log in as extension <ext> directly, for example *111042. The phone asks only for the PIN. |
*12 | Log out. Ends the session on this phone. On a phone with no session the phone says so and nothing changes. |
The PIN is the user's voicemail PIN. A user who hasn't set one can't log in from the keypad; the phone says a PIN is required. An admin can set the PIN on the user's page, or log the user in from the portal or the API, which needs no PIN.
Three wrong extensions or PINs end the attempt. Press # to submit an extension or PIN early; the phone otherwise submits a few seconds after the last digit.
On success the phone confirms the extension it is now logged in as, then picks up its new configuration on its own within moments. A DECT handset's base reloads to apply it, which briefly interrupts calls on the base's other handsets.
Logging in through the API
The examples read your secret key from the DIALSTACK_SECRET_KEY environment variable.
A hot-desk session is a singleton sub-resource of the device it is on.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/devices/{device}/hot-desk | The session on a phone; 404 not_hot_desked when there is none |
POST | /v1/devices/{device}/hot-desk | Log a user in |
DELETE | /v1/devices/{device}/hot-desk | Log out; returns the session that ended |
# Log a user in
curl -X POST https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/hot-desk \
-H "Authorization: Bearer $DIALSTACK_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-d '{"user": "YOUR_USER_ID"}'
{
"object": "device_hot_desk",
"device": "dev_01h2xcejqtf2nbrexx3vqjhp50",
"user": "user_01h2xcejqtf2nbrexx3vqjhp42",
"expires_at": "2026-10-19T22:00:00Z"
}
expires_at is null when the account's sessions never expire. When the user is logged in on their own permanently assigned phone and nobody else was logged in on it, no session starts and the response carries user: null and expires_at: null.
# Log out
curl -X DELETE https://api.dialstack.ai/v1/devices/YOUR_DEVICE_ID/hot-desk \
-H "Authorization: Bearer $DIALSTACK_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"
Refusals
Refusals carry a machine-readable code:
| Status | code | Meaning |
|---|---|---|
400 | user_not_found | The user in the body doesn't exist in the account |
404 | device_not_found | The device doesn't exist, was deleted, or is a DECT handset that isn't paired to a base. On DELETE, only a deleted device or an unpaired handset |
404 | not_hot_desked | GET or DELETE on a phone with no active session. DELETE also answers this for a DECT base or an unknown device |
409 | unsupported_device | GET or POST on a DECT base, or on a device that otherwise can't be hot-desked |
409 | conflict | The phone, user or session changed while the request ran. Read the session again, then retry |
Seeing who is logged in where
Expand hot_desk on the devices list or on a single device to get each phone's session inline. It is null on a phone with no session, and the field is omitted entirely when not expanded:
curl "https://api.dialstack.ai/v1/devices?expand[]=hot_desk" \
-H "Authorization: Bearer $DIALSTACK_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"
A DECT base always reports hot_desk: null.
To find where a user is logged in, expand hot_desk on the user, or on the users list. It carries the same object, so device names the phone, and it is null when the user isn't logged in anywhere:
curl "https://api.dialstack.ai/v1/users/YOUR_USER_ID?expand[]=hot_desk" \
-H "Authorization: Bearer $DIALSTACK_SECRET_KEY" \
-H "DialStack-Account: YOUR_ACCOUNT_ID"
Server SDK
import { DialStack } from '@dialstack/sdk-server';
const dialstack = new DialStack(process.env.DIALSTACK_SECRET_KEY);
const acct = { dialstackAccount: accountId };
await dialstack.devices.createHotDesk(deviceId, { user: userId }, acct);
const session = await dialstack.devices.retrieveHotDesk(deviceId, acct);
await dialstack.devices.delHotDesk(deviceId, acct);
Webhooks
Two events follow sessions. Both carry the device_hot_desk object as data:
device.hot_desk.startedwhen a user logs in on a phone.device.hot_desk.endedwhen a session ends, whatever the cause:*12orDELETE, expiry, the user logging in on another phone, another user logging in on this phone, the user or phone being deleted, or a handset being unpaired from its base. Expiry, deletion and unpairing are noticed by a once-a-minute sweep, so theirendedcan arrive up to about a minute later.
A session emits started when it begins and ended when it ends. When a login replaces another user's session, the ended for the old session is emitted before the started for the new one. Logging the same user in again on the same phone emits nothing. Webhooks are delivered at least once, so deduplicate on the event id. If you keep your own view of who is logged in where, reconcile it periodically from GET /v1/devices?expand[]=hot_desk rather than relying on the events alone.
See Webhook Events for payloads.
Admin portal
Account admins see and manage sessions in the admin portal: a Hot Desking card on each deskphone's and handset's page to log a user in or out, a Logged in badge in the devices table, and the session length under the account's Devices tab. See Hot desking in the admin guide.
Limitations
- Deskphones and paired DECT handsets only. DECT bases and softphones can't be hot-desked.
- A user needs a voicemail PIN to log in from the phone keypad. Logins from the admin portal or the API need none.
- The user's own phone is logged out while they are hot-desked elsewhere, and can dial only 911, 933 and the login codes until the session ends.
- A phone's permanent assignment can still be changed while a session is active, from the portal or the API. The change takes effect under the session and is what the phone shows once the session ends.