Skip to content
Voxbi Cockpit APIs
API Guides

Set up user provisioning

User provisioning is an API endpoint that lets your own system keep Cockpit's users in sync: you post the complete list of people who should exist, and Cockpit creates, updates, and removes accounts to match it.

Overview

Provisioning is configured per PBX on the User provisioning tab of the PBX settings. You generate a key, list the IP addresses allowed to use it, and then post your user list to the URL shown on that tab.

Each request describes the complete set of users for the PBX, not a change set. Cockpit compares your list against what it already has and reconciles the difference: new people are created, existing people are updated, and people who are no longer in the list are removed. Every user it creates also gets its extension, twinning numbers, and Tempus badges from the same payload.

Use this when you already hold your staff list somewhere authoritative (an HR system, a directory, a script) and want Cockpit to follow it. If you only want people to be created when they first sign in, use Single Sign-On provisioning instead.

Turn it on

  1. Open PBX settings and go to the User provisioning tab.
  2. Click Generate next to User provisioning key. Copy the key somewhere safe.
  3. Under User provisioning IP addresses, add every public IP address that will send requests. Up to five entries are allowed.
  4. Save.
  5. Copy the User provisioning URL shown at the top of the tab. That is the endpoint you post to.

The endpoint

POST {your-cockpit-url}/admin/user-provisioning
Content-Type: application/json
Accept: application/json
X-USER-PROVISIONING-KEY: {your provisioning key}

The key identifies the PBX, so there is no PBX id anywhere in the payload. Everything the request creates belongs to the PBX that owns the key.

You get 401 when the key is missing, wrong, or the calling IP is not on the allow-list, and 422 when the body has no users array.

What to send

The body is a single object with a users array. Each entry describes one person.

{
  "users": [
    {
      "first_name": "Anna",
      "last_name": "Becker",
      "email": "anna.becker@example.com",
      "active": true,
      "extension": "201",
      "twinnings": ["+352691123456"],
      "badges": ["0004512345"]
    },
    {
      "first_name": "Marc",
      "last_name": "Schmidt",
      "email": "marc.schmidt@example.com",
      "active": true,
      "extension": "202"
    },
    {
      "first_name": "Julie",
      "last_name": "Weber",
      "email": "julie.weber@example.com",
      "active": false
    }
  ]
}
Field Required Rules What it does
email Yes Valid email, max 50 characters The identity key. Cockpit matches people by email, so it must be stable across syncs.
first_name Yes 1 to 64 characters The user's first name.
last_name No Max 64 characters The user's last name. Stored in capitals when the PBX setting Capitalize users last name is on.
active Yes true or false true enables the account and shows it in the address book. false disables it and hides it, keeping the account.
extension No Max 16 characters The extension number to assign. Omit it to leave the person without one.
twinnings No Array of strings, max 16 characters each Numbers that ring together with the extension. Spaces are stripped and each entry is normalized to + followed by digits, so +352 691 123 456 and 352691123456 end up identical.
badges No Array of strings, max 255 characters each Tempus badge numbers for time and attendance.

Within one payload, email and extension must each be unique. A second entry carrying an email or an extension already used earlier in the same list is skipped.

Any other field is ignored: the seven above are the whole contract.

What the sync does

Cockpit reconciles your list in one pass, per PBX:

  1. People in your list that Cockpit does not have are created, with a random password (they sign in through SSO or a password reset, never with a password you send).
  2. People Cockpit already has are updated in place: names, active state, extension, twinnings, and badges are brought in line with your payload. A person whose data already matches is left untouched and does not count as updated.
  3. People Cockpit has that your list does not mention are removed, subject to the ownership rule below.
  4. Previously removed people who reappear in your list are restored rather than duplicated.

Only provisioned users are removed

Every user, extension, twinning, and badge that provisioning creates is stamped as provisioning-owned, and the removal step only deletes users carrying that stamp. A colleague you created by hand in the admin panel is not deleted just because your directory does not know about them. Conversely, anything provisioning created will disappear once you stop sending it, so keep sending the full list on every request.

Two details are worth knowing before you rely on that boundary:

  • Sending someone adopts them. When your payload contains an email that already exists as a hand-created user, Cockpit updates that user and stamps it as provisioning-owned. The same applies to an extension number, a twinning, or a badge that already existed. From then on it behaves like any provisioned record, so leaving it out of a later request removes it. If you want an account to stay yours, keep it out of the payload entirely.
  • Removing a user clears all of their twinnings and badges. When a provisioned user is removed, every twinning and badge attached to them goes with them, including ones you had added by hand. Their extension is unlinked too, though it is only deleted when provisioning created it.

Extensions, twinnings and badges follow the user

  • Dropping the extension field for someone who had one detaches the extension and removes it if provisioning created it. Assigning that number to a different person in the same request hands it over, and any SIP device that pointed at the previous owner is unlinked.
  • An extension name you customized by hand is preserved as long as the extension keeps the same owner. It is only rewritten to the owner's name when the extension changes hands.
  • Removing a number from twinnings, or a badge from badges, removes that record. Sending it again later restores it.
  • Removals are reversible: users, extensions, twinnings and badges are archived rather than erased.

Changes are staged, like any other change

Provisioning writes into the same staged-configuration model as the admin panel. When a request changed anything, the PBX is flagged as having pending changes, and they reach the phones once the configuration push completes. Watch the Push configuration button for the current state.

What you get back

A successful request returns 200 with a summary of what it did:

{
  "status": "success",
  "message": "User provisioning completed successfully",
  "created": 2,
  "updated": 5,
  "deleted": 1
}

created, updated, and deleted count users only, not their extensions, twinnings, or badges. Users whose data was already correct appear in none of the three.

When individual users fail

A user that fails validation does not fail the request. Cockpit skips that entry, carries on with the rest, and still answers 200 with the success summary. The skipped entries are recorded on the PBX instead, as one of:

  • User provisioning failed validation - the entry broke one of the rules in the table above (a malformed email, a name over 64 characters, and so on).
  • User provisioning duplicate email - the same email appeared twice in one payload.
  • User provisioning duplicate extension number - the same extension appeared twice in one payload.

Each record names the user and lists the validation errors. Review them under Events after a sync.

Example: a full sync

curl -X POST https://cockpit.example.com/admin/user-provisioning \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-USER-PROVISIONING-KEY: your-provisioning-key' \
  -d '{
        "users": [
          {
            "first_name": "Anna",
            "last_name": "Becker",
            "email": "anna.becker@example.com",
            "active": true,
            "extension": "201",
            "twinnings": ["+352691123456"]
          },
          {
            "first_name": "Marc",
            "last_name": "Schmidt",
            "email": "marc.schmidt@example.com",
            "active": true,
            "extension": "202"
          }
        ]
      }'

After this request, exactly these two people exist as provisioned users on the PBX. Any other provisioned user is removed.

SCIM as an alternative

If your identity provider speaks SCIM 2.0, you can point it at Cockpit's SCIM endpoints instead of building the payload yourself. They authenticate with the same provisioning key, sent as a bearer token (Authorization: Bearer {key}) rather than in the X-USER-PROVISIONING-KEY header. SCIM works per user rather than by full list, so it has none of the whole-list removal behavior described above.

See also

Updated