Skip to main content

Users

List the users of the company — who works here, how to reach them, and which PBX objects they own.

  • Base path: https://api.account.telebroad.com/api/public/v1
  • Auth header: Authorization: Bearer ACCESS_TOKEN
  • Scope: users:read

This is the endpoint that turns an id or an extension into a person. Every user id elsewhere in the API — userIds on an SMS line, the agent on a call in reports — is the id from this list.

:::note Migrating from /api/teleconsole/rest/people Same records, new name. These rows are called users throughout the platform (the portal's Users page, /api/v1/users); "people" was the older word for them. Two behaviour changes are called out below: who is in the list and what is not here. :::

Endpoint

Method & pathScopePurpose
GET /usersusers:readList the account's users

List users

curl https://api.account.telebroad.com/api/public/v1/users \
-H "Authorization: Bearer $ACCESS_TOKEN"

Response

{
"data": [
{
"id": 481920,
"username": "dreyes",
"firstName": "Dana",
"lastName": "Reyes",
"title": "Support Lead",
"email": "dana@acme.example",
"mobile": "13475550188",
"company": "Acme Inc",
"timeZone": "America/New_York",
"extension": "104",
"extensions": ["104"],
"lines": ["acme-104"],
"numbers": ["12125550188"],
"voicemails": ["104"]
}
]
}

Sorted by last name, then first name, then id — stable between calls, so you can diff two responses to find joiners and leavers.

FieldTypeNotes
idnumberThe user id on the phone system. This is the id every other endpoint means.
usernamestringPortal login. Empty for users created without portal access.
firstName, lastNamestring
titlestringFree-text job title from the portal.
emailstring
mobilestringThe user's personal number, not a number on the account. Often blank.
companystringThe per-user company override, falling back to the account name. Never blank.
timeZonestringIANA zone. Every timestamp in this API is UTC — this is what converts one to the time this person saw.
extensionstringThe dial-by-name extension the auto-attendant matches. See the caution below.
extensionsstring[]The PBX extensions a colleague dials to reach them.
linesstring[]SIP lines (devices) the user owns.
numbersstring[]Account DIDs owned by this user. A number with no owner appears on nobody.
voicemailsstring[]Mailboxes the user owns.

:::caution extension and extensions are not the same thing extension (singular) is the dial-by-name value on the user's profile — what the auto-attendant matches when a caller spells a name. It is frequently blank, and it is not guaranteed to be a number anyone can dial.

extensions (plural) is the list of real PBX extensions assigned to the user. To reach someone, use this. :::

All four list fields are always arrays. A user with nothing assigned gets [], never null.

Who is in the list

Whoever your credential is allowed to see in the portal — this endpoint honours the same Users permission the admin center does.

CredentialSees
API keyThe whole account. A key is the account's own credential, so it is not narrowed to any one person's permissions.
OAuth tokenExactly the users the authorizing person sees on the portal's Users page.

A delegated app cannot enumerate staff its own user cannot open. If your OAuth integration gets a shorter list than you expect, the authorizing user's role is restricted to specific users — widen it in the portal under Roles, or use an API key for account-wide reads.

:::info Changed from the teleconsole endpoint The legacy /people showed every colleague to every user, ignoring roles. This endpoint follows the admin center instead, so there is one answer to "who may see this user" across the portal, a delegated app and an API key. :::

The account's internal service login (the pseudo-admin, username [Account Name]) is excluded. It is not a person.

What is not here

Personal contacts. This is the other change from the legacy endpoint, and the bigger one.

The teleconsole /people returned two different things merged into one array:

  1. the company's users — colleagues, extensions, the corporate list; and
  2. the calling user's own address book — contacts that person had typed into their softphone, stored privately against their user id.

You told them apart by the contactType field. This endpoint returns only (1).

The reason is what your credential is. An API key authenticates an account, not a person, so there is no "my contacts" for it to read — the personal half would always come back empty, and you would have no way to tell "this user saved no contacts" from "this credential can never see contacts". Merging two sets with different owners, different lifetimes and different privacy weight behind one type= parameter hides that distinction rather than expressing it.

If you were consuming the personal half, tell us — it would be published as its own resource, where the ownership rules can be stated honestly.

Photos. The portal stores an avatar path, not a URL, and a path is not useful to you. Ask if you need this exposed properly.

Presence and status. Whether someone is on a call is real-time state, not directory data. Use the call webhooks for that.

Errors

StatustypeCause
401unauthenticatedMissing or invalid credential.
403insufficient_scopeThe credential lacks users:read.

A role that permits no users returns 200 with an empty array, not 403 — you are allowed to ask, there is just nobody to show you.

Limits and caveats

  • No paging, no filtering, no search in this version. The response is every user you can see. Accounts are typically tens to hundreds of users; if yours is large enough for this to be a problem, tell us and paging gets added.
  • No writes. Creating a user provisions extensions, voicemail and a switch identity — that is a portal operation, not something a third-party integration should do through a REST POST.
  • The list is read live. There is no caching layer in front of it, so a user added in the portal appears on the next call.