Users

About Users

Users represent just that, your users of the system. You can assign multiple devices to a user, put the user in a callflow, and all devices will ring.

Schema

Schema for a user

KeyDescriptionTypeDefaultRequiredSupport Level
addresses.vcard.[].addressstring()true
addresses.vcard.[].types.[]string()false
addresses.vcard.[].typesarray(string())false
addresses.vcardAddresses list to build user’s vcardarray(object())false
addressesUser addressesobject()false
call_failoverThe device call failover parameters, to replace the device with an extension/phone number when device is offline.#/definitions/call_failoverfalse
call_forwardCall forward settings#/definitions/call_forwardfalse
call_limitsSchema for call limits#/definitions/call_limitsfalse
call_recordingendpoint recording settings#/definitions/call_recordingfalse
call_restrictionDevice level call restrictions for each available number classificationobject(){}false
call_waitingParameters for server-side call waiting#/definitions/call_waitingfalse
caller_idThe device caller ID parameters#/definitions/caller_idfalse
caller_id_optionscustom properties for configuring caller_id#/definitions/caller_id_optionsfalse
contact_list.excludeIf set to true the device is excluded from the contact listboolean()falsesupported
contact_listContact List Parametersobject(){}false
dial_planA list of rules used to modify dialed numbers#/definitions/dialplansfalse
directoriesProvides the mappings for what directory the user is a part of (the key), and what callflow (the value) to invoke if the user is selected by the caller.object()false
do_not_disturb.enabledIs do-not-disturb enabled for this user?boolean()false
do_not_disturbDND Parametersobject()false
emailThe email of the userstring(3..254)falsesupported
enabledDetermines if the user is currently enabledboolean()truefalsesupported
feature_levelThe user level for assigning feature setsstring()false
first_nameThe first name of the userstring(1..128)truesupported
flags.[]string()falsesupported
flagsFlags set by external applicationsarray(string())falsesupported
formattersSchema for request formattersobject()false
hotdesk.enabledDetermines if the user has hotdesking enabledboolean()falsefalse
hotdesk.idThe users hotdesk idstring(0..15)false
hotdesk.keep_logged_in_elsewhereDetermines if user should be able to login to multiple phones simultaneouslyboolean()falsefalse
hotdesk.pinThe users hotdesk pin numberstring(4..15)false
hotdesk.require_pinDetermines if user requires a pin to change the hotdesk stateboolean()falsefalse
hotdeskThe user hotdesk parametersobject(){}false
languageThe language for this userstring()falsesupported
last_nameThe last name of the userstring(1..128)truesupported
mediaConfigure audio/video/etc media options for this user#/definitions/endpoint.mediafalse
metaflowsThe device metaflow parameters#/definitions/metaflowsfalse
music_on_hold.media_idThe ID of a media object that should be used as the music on holdstring(0..128)false
music_on_hold.options.[]`string(‘preserve-position''random-start’)`false
music_on_hold.optionsOptions for playing music on hold`array(string(‘preserve-position''random-start’))`false
music_on_holdThe music on hold parameters used if not a property of the device ownerobject(){}false
passwordThe GUI login passwordstring()falsesupported
presence_aliasesPresence Aliases#/definitions/presence_aliasesfalse
presence_idStatic presence ID (used instead of SIP username)string()falsesupported
priv_levelThe privilege level of the user`string(‘user''admin’)`userfalse
profileUser’s profile data#/definitions/profilefalse
pronounced_name.media_idThe ID of a media object that should be used as the music on holdstring(0..128)false
pronounced_nameName pronounced by user to introduce himself to conference membersobject()false
require_password_updateUI flag that the user should update their password.boolean()falsefalse
ringtones.externalThe alert info SIP header added when the call is from internal sourcesstring(0..256)false
ringtones.internalThe alert info SIP header added when the call is from external sourcesstring(0..256)false
ringtonesRingtone Parametersobject(){}false
scope_restrictions.[]string()false
scope_restrictionsScope restrictions applied to this userarray(string())false
timezoneUser’s timezone#/definitions/timezonefalsesupported
usernameThe GUI login username - alpha-numeric, dashes, at symbol, periods, plusses, and underscores allowedstring(1..256)falsesupported
verifiedDetermines if the user has been verifiedboolean()falsefalse
vm_to_email_enabledDetermines if the user would like voicemails emailed to themboolean()truefalse
voicemail.notify.callbackSchema for a callback options#/definitions/notify.callbackfalse
voicemail.notifyobject()false
voicemailobject()false

call_failover

The device call failover parameters, to replace the device with an extension/phone number when device is offline.

KeyDescriptionTypeDefaultRequiredSupport Level
direct_calls_onlyDetermines if the calls that are not directly sent to the device should be forwardedboolean()falsefalsesupported
enabledDetermines if the call failover should be used when device is offlineboolean()falsefalse
ignore_early_mediaThe option to determine if early media from the call forwarded number should ignoredboolean()truefalse
keep_caller_idDetermines if the caller id is kept when the call is forwarded, if not the devices caller id is usedboolean()truefalsesupported
numberThe number to forward calls tostring(0..35)falsesupported
require_keypressDetermines if the callee is prompted to press 1 to accept the callboolean()truefalse

call_forward

Call Forward

KeyDescriptionTypeDefaultRequiredSupport Level
busyCall Forward Propertiesobject()false
direct_calls_onlyboolean()falsefalse
enabledboolean()falsetrue
ignore_early_mediaboolean()truefalse
keep_caller_idboolean()truefalse
no_answerCall Forward Propertiesobject()false
numberstring(0..35)false
require_keypressboolean()truefalse
selective.direct_calls_onlyboolean()falsefalse
selective.enabledboolean()falsefalse
selective.ignore_early_mediaboolean()truefalse
selective.keep_caller_idboolean()truefalse
selective.numberstring(0..35)false
selective.require_keypressboolean()truefalse
selective.rules.[].direct_calls_onlyboolean()falsefalse
selective.rules.[].enabledboolean()falsefalse
selective.rules.[].ignore_early_mediaboolean()truefalse
selective.rules.[].keep_caller_idboolean()truefalse
selective.rules.[].match_list_idstring()false
selective.rules.[].numberstring(0..35)false
selective.rules.[].require_keypressboolean()truefalse
selective.rulesMatch list rules to check for call forwardingarray(object())false
selectiveConditionally check match lists to determine if call forwarding should be usedobject()false
substituteDetermines if the call forwarding replaces the deviceboolean()truefalse
unconditionalCall Forward Propertiesobject()false

call_forward_type

Call Forward Properties

KeyDescriptionTypeDefaultRequiredSupport Level
direct_calls_onlyboolean()falsefalse
enabledboolean()falsetrue
ignore_early_mediaboolean()truefalse
keep_caller_idboolean()truefalse
numberstring(0..35)false
require_keypressboolean()truefalse

call_limits

Schema for call limits

KeyDescriptionTypeDefaultRequiredSupport Level
max_concurrentMaximum number of concurrent calls allowed per endpointinteger()false

call_recording

endpoint recording settings

KeyDescriptionTypeDefaultRequiredSupport Level
anysettings for any calls to/from the endpoint#/definitions/call_recording.sourcefalse
inboundsettings for inbound calls to the endpoint#/definitions/call_recording.sourcefalse
outboundsettings for outbound calls from the endpoint#/definitions/call_recording.sourcefalse

call_recording.parameters

KeyDescriptionTypeDefaultRequiredSupport Level
enabledis recording enabledboolean()false
formatWhat format to store the recording on disk`string(‘mp3''wav’)`false
record_min_secThe minimum length, in seconds, the recording must be to be considered successful. Otherwise it is deletedinteger()false
record_on_answerRecording should start on answerboolean()false
record_on_bridgeRecording should start on bridgeboolean()false
record_sample_rateWhat sampling rate to use on the recordinginteger()false
should_announce_when_recordingWhether or not a prompt should be played (after bridge) when the call is being recordedboolean()false
should_record_feature_callsToggles whether to start a recording for calls to feature codesboolean()truefalse
time_limitTime limit, in seconds, for the recordinginteger(5..10800)false
urlThe URL to use when sending the recording for storagestring(6..)false

call_recording.source

KeyDescriptionTypeDefaultRequiredSupport Level
anysettings for calls from any network#/definitions/call_recording.parametersfalse
offnetsettings for calls from offnet networks#/definitions/call_recording.parametersfalse
onnetsettings for calls from onnet networks#/definitions/call_recording.parametersfalse

call_waiting

Parameters for server-side call waiting

KeyDescriptionTypeDefaultRequiredSupport Level
enabledDetermines if server side call waiting is enabled/disabledboolean()false

caller_id

Defines caller ID settings based on the type of call being made

KeyDescriptionTypeDefaultRequiredSupport Level
asserted.nameThe asserted identity name for the object typestring(0..35)false
asserted.numberThe asserted identity number for the object typestring(0..35)false
asserted.realmThe asserted identity realm for the object typestring()false
assertedUsed to convey the proven identity of the originator of a request within a trusted network.object()false
emergency.nameThe caller id name for the object typestring(0..35)false
emergency.numberThe caller id number for the object typestring(0..35)false
emergencyThe caller ID used when a resource is flagged as ‘emergency’object()false
external.nameThe caller id name for the object typestring(0..35)false
external.numberThe caller id number for the object typestring(0..35)false
externalThe default caller ID used when dialing external numbersobject()false
internal.nameThe caller id name for the object typestring(0..35)false
internal.numberThe caller id number for the object typestring(0..35)false
internalThe default caller ID used when dialing internal extensionsobject()false

caller_id_options

Caller ID options for endpoints

KeyDescriptionTypeDefaultRequiredSupport Level
format./.+/.prefixPrefix to add to captured group of regexstring()false
format./.+/.regexRegexp to match normalized CID and use first capture groupstring()false
format./.+/.suffixPrefix to add to captured group of regexstring()false
format./.+/Format to use for the CID classificationobject()false
format.all.prefixPrefix to add to captured group of regexstring()false
format.all.regexRegexp to match normalized CID and use first capture groupstring()false
format.all.suffixPrefix to add to captured group of regexstring()false
format.allFormat to use for all CID formatting needs (vs per-classifier)object()false
formatObject for CID formatters based on number classifiersobject()false
ignore_completed_elsewhereSuppress the completed elsewhere causeboolean()false
outbound_privacyDetermines what appears as caller id for offnet outbound calls. Values: full - hides name and number; name - hides only name; number - hides only number; none - hides nothing`string(‘full''name''number''none’)`
privacy_methodMethod to use for anonymizing CID`string(‘sip''none''kazoo’)`
show_rateWhether to show the rateboolean()false
typeCaller ID on endpoint to choose`string(‘internal''external''emergency’)`

codecs.audio

A list of audio codecs the endpoint supports

KeyDescriptionTypeDefaultRequiredSupport Level

codecs.video

A list of video codecs the endpoint supports

KeyDescriptionTypeDefaultRequiredSupport Level

dialplans

Permit local dialing by converting the dialed number to a routable form

KeyDescriptionTypeDefaultRequiredSupport Level
system.[]string()false
systemList of system dial plansarray(string())false

endpoint.media

Schema for endpoint media options

KeyDescriptionTypeDefaultRequiredSupport Level
audio.codecsA list of audio codecs the endpoint supports#/definitions/codecs.audiofalse
audioThe audio media parametersobject(){}false
bypass_mediaDefault bypass media mode (The string type is deprecated, please use this as a boolean)`boolean()string(‘auto''false''true’)`
encryption.enforce_securityIs Encryption Enabled?boolean()falsefalse
encryption.methods.[]`string(‘zrtp''srtp’)`false
encryption.methodsSupported Encryption Types`array(string(‘zrtp''srtp’))`[]false
encryptionEncryption Parametersobject(){}false
fax_optionIs T.38 Supported?boolean()false
ignore_early_mediaThe option to determine if early media from the endpoint should always be ignoredboolean()false
progress_timeoutThe progress timeout to apply to the endpoint (seconds)integer()false
video.codecsA list of video codecs the endpoint supports#/definitions/codecs.videofalse
videoThe video media parametersobject(){}false
webrtcIf true, forces a WebRTC compatible SDP on the INVITEboolean()false

formatters

Schema for request formatters

KeyDescriptionTypeDefaultRequiredSupport Level
^[[:alnum:]_]+$Key to match in the route request JSON`array(#/definitions/formatters.format_options)#/definitions/formatters.format_options`false

formatters.format_options

Schema for formatter options

KeyDescriptionTypeDefaultRequiredSupport Level
directionOnly apply the formatter on the relevant request direction`string(‘inbound''outbound''both’)`
match_invite_formatApplicable on fields with SIP URIs. Will format the username portion to match the invite format of the outbound request.boolean()false
prefixPrepends value against the result of a successful regex matchstring()false
regexMatches against the value, with optional capture groupstring()false
stripIf set to true, the field will be stripped from the payloadboolean()false
suffixAppends value against the result of a successful regex matchstring()false
valueReplaces the current value with the static value definedstring()false

metaflow

A metaflow node defines a module to execute, data to provide to that module, and one or more children to branch to

KeyDescriptionTypeDefaultRequiredSupport Level
children./.+/A metaflow node defines a module to execute, data to provide to that module, and one or more children to branch to#/definitions/metaflowfalse
childrenChildren metaflowsobject()false
dataThe data/arguments of the metaflow moduleobject(){}false
moduleThe name of the metaflow module to execute at this nodestring(1..64)true

metaflows

Actions applied to a call outside of the normal callflow, initiated by the caller(s)

KeyDescriptionTypeDefaultRequiredSupport Level
binding_digitWhat DTMF will trigger the collection and analysis of the subsequent DTMF sequence`string(‘1''2''3''4'
digit_timeoutHow long to wait between DTMF presses before processing the collected sequence (milliseconds)integer(0..)false
listen_onWhich leg(s) of the call to listen for DTMF`string(‘both''self''peer’)`
numbers./^[0-9]+$/A metaflow node defines a module to execute, data to provide to that module, and one or more children to branch to#/definitions/metaflowfalse
numbersA list of static numbers with their flowsobject()false
patterns./.+/A metaflow node defines a module to execute, data to provide to that module, and one or more children to branch to#/definitions/metaflowfalse
patternsA list of patterns with their flowsobject()false

notify.callback

Schema for a callback options

KeyDescriptionTypeDefaultRequiredSupport Level
attemptsHow many attempts without answer will system dointeger()false
disabledDetermines if the system will call to callback numberboolean()false
interval_sHow long will system wait between call back notification attemptsinteger()false
numberNumber for callback notifications about new messagesstring()false
scheduleSchedules interval between callbacksarray(integer())false
timeout_sHow long will system wait for answer to callbackinteger()false

presence_aliases

Endpoint Presence Aliases

KeyDescriptionTypeDefaultRequiredSupport Level

profile

Defines user extended properties

KeyDescriptionTypeDefaultRequiredSupport Level
addresses.[].addressTo specify the addressstring()false
addresses.[].typesTo specify types of the addressarray()false
addressesTo specify the components of the addressesarray(object())false
assistantTo specify the user’s assistantstring()false
birthdayTo specify the birth date of the userstring()false
nicknames.[]string()false
nicknamesTo specify the text corresponding to the nickname of the userarray(string())false
noteTo specify supplemental information or a comment that is associated with the userstring()false
roleTo specify the function or part played in a particular situation by the userstring()false
sort-stringTo specify the family name or given name text to be used for national-language-specific sorting of the FN and N typesstring()false
titleTo specify the position or job of the userstring()false

timezone

The default timezone

KeyDescriptionTypeDefaultRequiredSupport Level

Fetch

GET /v2/accounts/{ACCOUNT_ID}/users

curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN} \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users
{
    "auth_token": "{AUTH_TOKEN}",
    "data": [
        {
            "email": "user1@account_realm.com",
            "features": [
                "caller_id",
                "vm_to_email"
            ],
            "first_name": "User",
            "id": "{USER_ID}",
            "last_name": "One",
            "priv_level": "admin",
            "timezone": "America/Los_Angeles",
            "username": "user1@account_realm.com"
        },
        {
            "email": "user2@account_realm.com",
            "features": [
                "caller_id",
                "vm_to_email"
            ],
            "first_name": "User",
            "id": "{USER_ID}",
            "last_name": "Two",
            "priv_level": "user",
            "timezone": "America/Los_Angeles",
            "username": "user2@account_realm.com"
        }
    ],
    "page_size": 2,
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Create a new user

PUT /v2/accounts/{ACCOUNT_ID}/users

curl -v -X PUT \
    -H "X-Auth-Token: {AUTH_TOKEN} \
    -H "Content-Type: application/json" \
    -d '{"data":{"first_name":"User", "last_name":"Three"}}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": true,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Remove a user

This request will return the current JSON object of the now-deleted user.

DELETE /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

curl -v -X DELETE \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": false,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Enhanced User deletion

Defines DELETE user extended functionality

KeyDescriptionTypeDefaultRequiredSupport Level
object_typesList of object types owned by the user that should also be deleted as part of the user delete process. NOTE: If “phone_numbers” is included in the list, numbers assigned to callflows owned by the user will also be released.`array(string(‘phone_numbers''callflow''vmbox''device'

When deleting a user, a list of object_types could be passed either within the request body or the query string. If object_types are included in the request, along deleting the user, the objects owned by the user that are listed will be deleted as well. See #/definitions/users_delete for more information.

If object_types were included in the request, the API response will include a object_types field in the response with a list with the objects that were tried to be deleted with the response status for each request, something like:

[{"type": {OBJECT_TYPE}, "id": {OBJECT_ID}, "status": {RESPONSE_STATUS}}, ...]

If any of the requests to delete an object failed, the object response will have 2 extra fields: error_code, and error_msg.

{"type": ..., "id": ..., "status": ..., "error_code": {ERROR_CODE}, "error_msg", {ERROR_MSG}}

curl -v -X DELETE \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -d '{"data": {"object_types": ["callflow", "vmbox"]}}'
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": false,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "object_types": [
            {
                "type": "vmbox",
                "id": "{VMBOX_ID}",
                "status": "success"
            },
            {
                "type": "callflow",
                "id": "{CALLFLOW_ID}",
                "status": "success"
            }
        ]
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Fetch a user

GET /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN} \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": true,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Patch a user’s doc

PATCH /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

curl -v -X PATCH \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{"data":{"enabled":false}}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": false,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Change the user doc

This requires posting the full user’s document in the request body

Sync: See the documentation on device sync for more info on check-sync. One can add the field "sync": true to the JSON document in order to attempt a check-sync on every registered device this user has.

POST /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

curl -v -X POST \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{"data":{"first_name":"User","last_name":"Three","call_restriction":{},"caller_id":{},"contact_list":{},"dial_plan":{},"enabled":false,"hotdesk":{"enabled":false,"keep_logged_in_elsewhere":false,"require_pin":false},"media":{"audio":{"codecs":["PCMU"]},"encryption":{"enforce_security":false,"methods":[]},"video":{"codecs":[]}},"music_on_hold":{},"priv_level":"user","profile":{},"require_password_update":false,"ringtones":{},"verified":false,"vm_to_email_enabled":true}}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
        "call_restriction": {},
        "caller_id": {},
        "contact_list": {},
        "dial_plan": {},
        "enabled": false,
        "first_name": "User",
        "hotdesk": {
            "enabled": false,
            "keep_logged_in_elsewhere": false,
            "require_pin": false
        },
        "id": "{USER_ID}",
        "last_name": "Three",
        "media": {
            "audio": {
                "codecs": [
                    "PCMU"
                ]
            },
            "encryption": {
                "enforce_security": false,
                "methods": []
            },
            "video": {
                "codecs": []
            }
        },
        "music_on_hold": {},
        "priv_level": "user",
        "profile": {},
        "require_password_update": false,
        "ringtones": {},
        "verified": false,
        "vm_to_email_enabled": true
    },
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Push payload to user’s devices

See pushes.md for information about this action.

Fetch (or create) a vCard

vCard is a file format typically used in emails as a form of business card. Kazoo currently generates a 3.0 compatible vCard.

GET /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/vcard

curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN} \
    -H "Accept: text/x-vcard"
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/vcard

BEGIN:VCARD VERSION:3.0 FN:User Three N:Three;User END:VCARD


## Remove the photo from the user

> DELETE /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo

```shell
curl -v -X DELETE \
    -H "X-Auth-Token: {AUTH_TOKEN} \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo

Fetch the user’s photo, if any

Set the Accept header to either application/base64 or application/octet-stream to retrieve the picture’s contents.

If the result is successful, you will want to pipe the response into a file.

GET /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo

curl -v -X GET \
    -H "Accept: application/base64" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo
[binary data]

Create or change the user’s photo

Use application/octet-stream as the content type.

POST /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo

curl -v -X POST \
    -H "Content-Type: application/octet-stream" \
    --data-binary @/path/to/image.jpg \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/photo
{
    "auth_token": "{AUTH_TOKEN}",
    "data": {},
    "request_id": "{REQUEST_ID}",
    "revision": "{REVISION}",
    "status": "success"
}

Quickcalls

See the quickcall docs for how to perform this action.

QR Codes

When an account is configured to use multi-factor authentication, and uses the included TOTP/HOTP provider, a user can generate their QR code for scanning into TOTP/HOTP applications like Google Authenticator.

GET /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/qrcode

curl -v -X GET \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H "Accept: image/png" \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}/qrcode

User Password Strength Compliance

By default Kazoo is not enforcing a secure password. This can be change per system configuration or per account.

The enforce is implemented as a list of regular expressions. Each regular expression should return a match. Non match means the regex is rejecting the password as it is not secure.

Password strength configuration

There are a couple of configurations to control this password strength enforcer:

  • Enabling password strength enforcer:
    • Enabling globally:
      • sup kapps_config set_boolean auth.password should_enforce_strength true
    • Enabling per reseller/account:
      • sup kapps_account_config set {RESELLER_OR_ACCOUNT_ID} auth.password should_enforce_strength true
    • To disable use same command but set it to false
  • Preventing setting the same old password:
    • If you need to force users to not use the same password again
    • Enabling globally:
      • sup kapps_config set_boolean auth.password should_prevent_reuse true
    • Enabling per reseller/account:
      • sup kapps_account_config set {RESELLER_OR_ACCOUNT_ID} auth.password should_prevent_reuse true
    • To disable use same command but set it to false
  • Password strength regular expressions
    • This setting is JSON object you need to set this setting directly in CouchDB or use Erlang shell. - Config key: strength_regexes
    • Config doc id:
      • For global: database system_config and doc id is auth.password
      • For per reseller/account: database is the reseller/account database and doc id is configs_auth.password

If you change the CouchDB doc directly don’t forget to flush the cache or if you changed an account directly:

sup kapps_config flush auth.password
sup kapps_account_config flush {ACCOUNT_ID} auth.password

For more info please refer to Kazoo Auth Password documentation.

Example of password enforcement API rejects insecure password

POST /v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

curl -v -X PATCH \
    -H "X-Auth-Token: {AUTH_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{"data":{"password":"bad"}}' \
    http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/users/{USER_ID}

Failed response:

{
    "auth_token": "{AUTH_TOKEN}",
    "data": {
      "password": {
        "insecure": {
          "message": "The provided password is non-compliant with your account's security level",
          "cause": "password",
          "details": [
             "at least one special character is required",
             "at least one digit is required",
             "at least one upper case character is required",
             "minimum password length is 10 characters"
                                                                          ]
        }
      }
    },
    "error": "validation failed",
    "status": "failed"
}