Profiles

Profiles let you provision and govern users at scale.

Profiles let you provision and govern users at scale. A profile is a reusable template of settings (license type, permissions, queues, interaction spaces, themes, dialing options, integration bindings) that you apply to users. Each user assigned to a profile inherits the profile's values; the user can then override individual fields, and the API tracks which fields have been overridden. When you update a profile, the platform runs a background job that propagates the updated values to the profile's users while preserving each user's overrides.

This page walks through the full profile lifecycle: designing a profile, finding and reading profiles, updating profiles and understanding the sync that follows, creating and updating users in relation to a profile, inspecting which users have drifted from their profile, and force-syncing users back to profile defaults.

All examples use cURL. All endpoints are hosted at:

https://core.{customerId}.ec.avayacloud.com/api/config/v1

where {customerId} is your organization identifier.

Contents


Overview

A profile sits between your account's licensing and your users. You create a profile with a license type and a baseline configuration; then every user you create from that profile inherits its values. Profiles let you keep hundreds of agents consistent without copying configuration field-by-field.

Three concepts are essential to using these APIs correctly:

  • License-type defaults. When you create a profile, the license type you pick (for example omniChannelAgent) determines the starting permissions, default interaction-space counts, and queue configuration. If you omit a configuration block, the platform applies the license-type defaults for that block. You can override any of them in the same request.

  • User overrides. Once a user has been created from a profile, anything you change on the user is tracked as an override. The API exposes both an aggregate (numUsersWithOverrides on the profile) and a per-user list (overriddenFields for each user). Overrides are how policy meets reality: agents legitimately diverge from the template (different timezone, different queue access, different theme), and the platform remembers what was customized.

  • Sync jobs. Two background jobs propagate profile changes to users:

    • PRFUPD: created automatically when you PATCH /profiles/{profileId}. It pushes the updated fields to assigned users while preserving each user's overrides. Only fields the user has not personally overridden are touched.
    • FSYNC: created explicitly when you call the force-sync endpoints. It clears all overrides for the targeted users and copies the profile's current values back onto them.

The rest of this page treats these three concepts as they come up.

User limit per profile. A profile supports at most 500 assigned users. Attempting to assign a 501st user via POST /users or PATCH /users/USERID (with profileId) is rejected with 422. Profile updates via PATCH /profiles/{profileId} are also blocked while a profile is over the limit. The numUsers field on the profile reflects the current count.

Required role. All profile and user endpoints require an administrator-level token. Profile endpoints require the Account Administrator role. User endpoints require Admin Portal or Admin API Consumer.


Authentication

Every request to the API must include a Bearer access token in the Authorization header. Tokens are obtained through the OAuth 2.0 client credentials grant using the credentials issued during your account's onboarding.

Request an access token

curl -X POST 'https://auth.{customerId}.ec.avayacloud.com/realms/{realm}/protocol/openid-connect/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'client_secret=YOUR_CLIENT_SECRET'

The response contains an access_token:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR...",
  "expires_in": 1800,
  "token_type": "Bearer",
  "scope": "openid profile"
}

Use the token

Pass the token as a Bearer credential on every API request:

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles' \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR...'

Note. Access tokens expire (commonly after 30 minutes; check expires_in in the token response). When a request returns 401 Unauthorized with detail: "Bearer token expired...", request a new token using the same client credentials.

The token URL and realm are issued to you during account onboarding. The customerId is the same value you use in the API base URL.


License Types

The license type assigned to a profile (and inherited by its users) determines the default permission set, the starting interaction-space allocation, and which features are enabled out of the box. You can always override individual fields after the profile is created, but the license type controls the baseline.

License TypeIntended ForDefault SpacesNotable Defaults
nonAgentRead-only users, supervisors who don't take interactions1 task, 1 email, 1 messagingMinimal permissions
voiceOnlyAgentPhone-only agents2 task, 1 phoneVoice-focused permissions
digitalOnlyAgentEmail + messaging agents (no phone)3 task, 2 email, 2 messagingDigital channels enabled, phone disabled
omniChannelAgentAll-channel agents except video3 task, 2 email, 1 phone, 2 messagingAll non-video channels enabled
omniChannelAgentEnhancedSenior all-channel agentsSame as omniChannelAgentEnhanced features and session statistics enabled
hybridVoiceAgentAgents bridging Avaya Infinity and on-premises Aura voiceBalanced voice + digitalAdds Elite/Aura-specific configuration fields

When you create a profile, you can omit any of permissions, queues, spaces, and attributes. The platform fills in the license-type defaults for whichever you omit. Anything you provide takes precedence and is used as the profile's value.


Creating a Profile

Create a profile with POST /profiles. The only required fields are name (unique within the account) and licType.

Minimal create

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Observer Profile",
    "description": "Profile for users who need read-only access",
    "licType": "nonAgent"
  }'

The platform applies the nonAgent license-type defaults (minimal permissions; 1 task, 1 email, 1 messaging space), the platform-wide defaults (appTheme: light, consoleTheme: light, timeZone: the account's configured default timezone, interactionViewsType: all, modifyInteractionViews: true), and returns the fully realized profile:

{
  "id": "16a7490f-86a6-4a14-8ce2-11682230adb6",
  "accountId": "001d01022054849399088a81ad",
  "name": "Observer Profile",
  "description": "Profile for users who need read-only access",
  "licType": "nonAgent",
  "permissions": { /* license-type defaults */ },
  "queues": { "access": [], "performance": [], "autoLogin": [], "proficiency": [], "logins": [], "defaultOutboundQueue": null, "outboundQueueId": null },
  "spaces": { "task": [], "email": [], "phone": [], "video": [], "messaging": [] },
  "tags": [],
  "attributes": {
    "time": { "tz": "America/New_York" },
    "taskSpaces": 1,
    "emailSpaces": 1,
    "messagingSpaces": 1,
    "phoneSpaces": 0,
    "videoSpaces": 0
  },
  "groups": [],
  "appTheme": "light",
  "consoleTheme": "light",
  "timeZone": "America/New_York",
  "interactionViewsType": "all",
  "modifyInteractionViews": true,
  "syncStatus": "SYNCED",
  "numUsers": 0,
  "numUsersWithOverrides": 0,
  "createdAt": "2026-05-15T10:04:24.181Z",
  "createdBy": "002d010826307dd6630992437b"
}

Richer create

You can override license-type defaults and platform defaults in the same call, place the profile in a folder, and bind it to a location:

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Senior Agent Profile",
    "description": "Profile for experienced agents with all features",
    "licType": "omniChannelAgentEnhanced",
    "profileFolderId": "073d010813b941cf7da111d147",
    "locationId": "022d01091776cc88fe6866b7ce",
    "appTheme": "dark",
    "timeZone": "America/Los_Angeles",
    "commTypeChangeDefaultValue": "callback",
    "infinityElements": ["elem_a1b2c3", "elem_d4e5f6"]
  }'

infinityElements can be set at creation, but only for agent license types. Setting it on a nonAgent profile returns a 422 ("Cannot set fields (infinityElements) for non-agent license type").

Validation rules

  • name must be unique within the account.
  • licType must be one of the values in the License Types table.
  • profileFolderId, if provided, must reference an existing folder.
  • locationId, if provided, must reference an existing location. Location IDs are system-generated and always begin with 022.

Common errors

StatusCondition
400Required field missing or malformed
409A profile with the same name already exists in this account
422Validation failed; see violations[] array in the response body

Listing and Searching Profiles

Use GET /profiles to list profiles. The endpoint supports pagination, filtering, sorting, folder scoping, and date-range filtering.

List all profiles

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles' \
  -H 'Authorization: Bearer ACCESS_TOKEN'
{
  "pagination": { "pageNumber": 1, "pageSize": 10, "total": 2 },
  "links": { "prev": "", "next": "" },
  "profiles": [
    {
      "id": "6d45f30d-dd0e-4546-b932-b6b1f223c9f3",
      "name": "Admin Profile",
      "description": "Profile for customer admin representatives",
      "licType": "hybridVoiceAgent",
      "profileFolderId": "073d01090149abae69f6305afe",
      "createdBy": "002d010826307dd6630992437b",
      "updatedAt": "2026-05-09T10:03:45.883Z"
    },
    {
      "id": "d5cfccf4-0507-49f8-98d9-34fdaeefca5d",
      "name": "Customer Support Profile",
      "description": "Profile for customer support representatives",
      "licType": "hybridVoiceAgent",
      "createdBy": "002d010826307dd6630992437b",
      "updatedAt": "2026-05-09T10:02:53.596Z"
    }
  ]
}

Pagination

ParameterDefaultRangeNotes
pageNumber1≥ 1The page to return
pageSize105–100Profiles per page

The response links.prev and links.next are blank strings when you are on the first or last page respectively.

Folder filtering

The folderId parameter has three modes:

ParameterBehavior
folderId omittedReturns profiles from all folders in the account
folderId= (empty string)Returns only root-folder profiles (profiles not assigned to any folder)
folderId=073d01090149abae69f6305afeReturns profiles in that folder only (does not include subfolders by default)
folderId=...&includeSubfolders=trueReturns profiles in that folder and all its subfolders recursively

Examples:

# Profiles in a specific folder, not including subfolders
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?folderId=073d01090149abae69f6305afe' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Profiles in a specific folder and every subfolder
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?folderId=073d01090149abae69f6305afe&includeSubfolders=true' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Root-folder profiles only
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?folderId=' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Filter syntax

The filter query parameter applies a single-field filter. The syntax distinguishes exact match (=) from pattern match (:):

FormBehaviorExample
field=valueExact matchlicType=hybridVoiceAgent
field:valueSubstring containsname:Customer
field:value*Starts withname:Support*
field:*valueEnds withname:*Agent

Filterable fields: name, description, licType, syncStatus, createdBy, updatedBy, createdAt, updatedAt. Field names are case-sensitive.

# Profiles whose name starts with "Support"
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?filter=name:Support*' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Profiles for a specific license type
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?filter=licType=hybridVoiceAgent' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Sort order

orderBy accepts a field name plus an optional desc suffix. Default is updatedAt desc (most recently updated first).

Sortable fields: name, description, licType, syncStatus, numUsers, createdBy, updatedBy, createdAt, updatedAt.

# Sort alphabetically by name
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?orderBy=name' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Profiles with the most users first
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?orderBy=numUsers%20desc' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Date-range filtering

updatedSince and updatedUntil filter by the profile's updatedAt timestamp. Both accept ISO 8601 with timezone offset. They may be used independently or combined; when combined, updatedSince must be less than updatedUntil.

# Profiles updated in the last 24 hours
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?updatedSince=2026-05-14T00:00:00Z' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Profiles updated in Q1 2026
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles?updatedSince=2026-01-01T00:00:00Z&updatedUntil=2026-03-31T23:59:59Z' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Retrieving a Profile

GET /profiles/{profileId} returns the full profile, including its permissions, queues, spaces, attributes, sync metadata, and resolved CRM configuration.

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/1ac75384-6099-424c-a179-9038a7a44a54' \
  -H 'Authorization: Bearer ACCESS_TOKEN'
{
  "id": "1ac75384-6099-424c-a179-9038a7a44a54",
  "accountId": "001d01022054849399088a81ad",
  "name": "Customer Support Profile",
  "description": "Profile for customer support representatives",
  "licType": "hybridVoiceAgent",
  "locationId": null,
  "permissions": { /* ... */ },
  "queues": {
    "access": [],
    "performance": [],
    "autoLogin": [],
    "proficiency": [],
    "logins": [],
    "defaultOutboundQueue": null,
    "outboundQueueId": null
  },
  "spaces": { "task": [], "email": [], "phone": [], "video": [], "messaging": [] },
  "attributes": {
    "time": { "tz": "America/New_York" },
    "taskSpaces": 3,
    "emailSpaces": 3,
    "phoneSpaces": 1,
    "videoSpaces": 0,
    "messagingSpaces": 3
  },
  "tags": [],
  "groups": ["007d01090301ad8db0f0d4c370"],
  "appTheme": "light",
  "consoleTheme": "light",
  "timeZone": "America/New_York",
  "syncStatus": "SYNCED",
  "numUsers": 12,
  "numUsersWithOverrides": 4,
  "createdAt": "2026-04-08T06:19:21.561Z",
  "createdBy": "002d010826307dd6630992437b",
  "updatedAt": "2026-05-09T10:02:53.596Z",
  "updatedBy": "002d010826307dd6630992437b"
}

The crmConfigId query parameter

When crmConfigId=true (the default), the response inlines the full CRM configuration object under crmConfigurations. Set crmConfigId=false to return just the raw CRM config ID instead, useful for callers that only need the reference:

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/1ac75384-6099-424c-a179-9038a7a44a54?crmConfigId=false' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Reading the response

The response is grouped logically:

  • Identity: id, accountId, name, description, licType, profileFolderId, locationId.
  • Access control: permissions (nested app/console structure), queues, tags, groups.
  • Interaction surface: spaces (task/email/phone/video/messaging), attributes (timezone, space counts, queue settings, WebRTC/WebHID). The same space counts (taskSpaces, emailSpaces, phoneSpaces, videoSpaces, messagingSpaces) also appear at the top level of the response, alongside taskPickupOverMultiplicity, emailPickupOverMultiplicity, phonePickupOverMultiplicity, and messagingPickupOverMultiplicity.
  • UI and locale: appTheme, consoleTheme, timeZone, interactionViewsType, definedInteractionViews, modifyInteractionViews, commTypeChangeDefaultValue.
  • Voice / UC: defaultOutboundCallerId, dialPlanProfileId, enableWebHID, enableErrorTones, allowInternalCalls, previewOutbound, predictiveOutbound, persistentMedia, ucPhoneSpaces, useUCPhoneSpaceOnCCCall, useCCPhoneSpaceOnUCCall, externalUCProviderConnections.
  • Integrations: crmConfigurations (shape depends on the crmConfigId query parameter), infinityElements.
  • Sync metadata: syncStatus, syncJobId (present when a sync is active), numUsers, numUsersWithOverrides.
  • Audit metadata: createdAt, createdBy, updatedAt, updatedBy.

Updating a Profile

PATCH /profiles/{profileId} performs a partial update: only fields included in the request body are modified. Omitted fields keep their current values.

Rename and re-describe

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Updated Observer Profile",
    "description": "Updated profile for users who need read-only access"
  }'

Change the license type

Changing the license type applies that license's new baseline to fields you have not explicitly configured.

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "licType": "voiceOnlyAgent",
    "name": "Voice Agent Profile"
  }'

Move a profile into (or out of) a folder

# Move to a folder
curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileFolderId": "073d01090149abae69f6305afe" }'

# Remove from current folder
curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileFolderId": null }'

What happens to assigned users

Every successful PATCH /profiles/{profileId} queues a background sync job. The job propagates the updated values to all users assigned to this profile while preserving each user's overrides: only fields the user has not personally overridden are touched. The next section explains the sync lifecycle.

The PATCH response includes the new syncJobId and syncStatus:

{
  "id": "16a7490f-86a6-4a14-8ce2-11682230adb6",
  "name": "Voice Agent Profile",
  "licType": "voiceOnlyAgent",
  "syncStatus": "SYNC_QUEUED",
  "syncJobId": "c8c2909d-75e9-484a-94c0-b7e8d30771fe",
  "numUsers": 12,
  "numUsersWithOverrides": 4,
  "updatedAt": "2026-05-15T14:45:00Z",
  "updatedBy": "002d010826307dd6630992437b"
}

Validation rules

  • name, if changed, must remain unique within the account.
  • licType, if changed, must be a valid license type for the account.
  • profileFolderId, if provided, must reference an existing folder. Send null to detach.
  • locationId, if provided, must reference an existing location.

Common errors

StatusCondition
400Request body malformed
404profileId does not exist
409The new name conflicts with an existing profile, or a sync job is already in progress on this profile
422Validation failed (violations[]), or the profile has more than 500 assigned users

The "active sync job" 409 looks like this:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "Profile cannot be updated while a sync job is in progress (jobId: c8c2909d-75e9-484a-94c0-b7e8d30771fe). Please wait for it to complete."
}

When you see it, wait for the current sync to clear (see the next section), then retry the PATCH.

Profile user limit (422)

A profile supports at most 500 assigned users. When numUsers exceeds 500, PATCH /profiles/{profileId} is rejected (updates remain allowed at exactly 500):

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "Profile User limit of 500 reached. Cannot update profile",
  "violations": [
    {
      "field": "profileId",
      "message": "Profile User limit of 500 reached. Cannot update profile",
      "code": 20005
    }
  ]
}

To clear this state, reassign the excess users to a different profile (or detach them) until numUsers is back at or below 500, then retry the PATCH.


Profile Sync Jobs

Two background jobs propagate profile changes to users. Understanding the difference is essential before you write automation against these APIs.

PRFUPD: preserves overrides

A PRFUPD job is created automatically by every successful PATCH /profiles/{profileId}. It walks every user assigned to the profile and copies each updated field onto the user only if the user has not personally overridden that field. Overrides are preserved.

FSYNC: clears overrides

An FSYNC job is created when you explicitly call one of the force-sync endpoints:

  • POST /users/USERID:force-sync-profile (single user)
  • POST /users:bulk-force-sync-profile (bulk)

FSYNC is the opposite of PRFUPD: it copies the profile's current values onto the user regardless of overrides, then clears all override tracking for that user. After an FSYNC, the user is, by definition, fully in sync with the profile.

The syncStatus lifecycle

Each profile exposes a syncStatus field that reflects the state of its most recent (or active) sync job:

       PATCH /profiles/{id}
       or force-sync request
              │
              ▼
       SYNC_QUEUED ──────────► SYNC_IN_PROGRESS
                                     │
                       ┌─────────────┴─────────────┐
                       ▼                           ▼
                    SYNCED                    SYNC_FAILED
              (all users updated)        (job aborted before
                                          all users updated)
StatusMeaning
SYNCEDThe profile and its users are in agreement. Default starting state.
SYNC_QUEUEDA change has been received; the worker has not yet started processing.
SYNC_IN_PROGRESSThe sync worker is currently updating users.
SYNC_FAILEDThe job ended in failure or was aborted before all users could be updated.

Checking sync status

PATCH /profiles/{profileId} returns immediately; the update itself finishes asynchronously as a background sync job. To confirm it's done, poll the profile and check syncStatus:

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

syncStatus moves from SYNC_QUEUED to SYNC_IN_PROGRESS and then to SYNCED once every assigned user has been updated (or SYNC_FAILED if the sync didn't complete). Once it reaches SYNCED, it's safe to issue another PATCH or FSYNC against the same profile.

Tip. A second PATCH or force-sync against a profile while a sync is still in progress returns 409 Conflict. Either poll until syncStatus clears, or design your automation to coalesce changes into a single PATCH.


Inspecting Profile Users and Overrides

GET /profiles/{profileId}/users lists the users assigned to a profile, with a per-user breakdown of which fields have been overridden.

curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6/users?hasOverrides=true&pageNumber=1&pageSize=10' \
  -H 'Authorization: Bearer ACCESS_TOKEN'
{
  "pagination": { "pageNumber": 1, "pageSize": 10, "total": 4 },
  "links": { "prev": "", "next": "" },
  "users": [
    {
      "userId": "002d011003cf7c9d1b469ddc7e",
      "email": "[email protected]",
      "firstName": "Hiten",
      "lastName": "Agent",
      "fullName": "Hiten Agent",
      "hasOverrides": true,
      "overriddenFields": [
        "appTheme",
        "queues.access",
        "permissions.app.agent.read"
      ],
      "folderId": "073d010813b941cf7da111d147"
    }
  ]
}

Query parameters

ParameterTypeNotes
pageNumberintOptional. When omitted with pageSize, the response has no pagination metadata.
pageSizeintOptional, 5–100.
hasOverridesbooleantrue returns only users with at least one override; false returns only fully synced users; omitted returns all.
searchstringCase-insensitive substring match on first name, last name, or email (max 100 chars).

What gets tracked as an override

Override tracking covers profile-managed fields. When an admin (or the user themselves) changes one of these fields on a user, the field path is recorded in overriddenFields:

  • Permissions (nested, e.g., permissions.app.agent.read)
  • Queues (queues.access, queues.performance, queues.autoLogin, queues.proficiency, queues.logins, queues.defaultOutboundQueue, queues.outboundQueueId)
  • Spaces (spaces.task, spaces.email, spaces.phone, spaces.video, spaces.messaging)
  • tags, attributes, groups
  • appTheme, consoleTheme, timeZone
  • interactionViewsType, definedInteractionViews, modifyInteractionViews
  • commTypeChangeDefaultValue, defaultOutboundCallerId, locationId, dialPlanProfileId
  • Feature flags: deferEnabled, enableWebHID, enableErrorTones, allowInternalCalls, allowAgentEditAutoAnswer, allowAgentEditWebHIDHeadsetControl, rejectInteractions, previewOutbound, predictiveOutbound, persistentMedia

User-identity fields (email, firstName, lastName, mobile, extension, title) are not profile-managed and are never tracked as overrides.

What you can do with this data

  • Audit drift. Filter hasOverrides=true to find users who have diverged from policy.
  • Plan a force-sync. Identify high-override users, decide whether to keep their overrides (do nothing; PRFUPD will continue to preserve them) or reset them (force-sync, which clears overrides).
  • Reconcile after a license change. Read the list before and after a PATCH that changes licType to see which users absorbed the change cleanly and which need follow-up.

Creating a User from a Profile

POST /users creates a user. The minimum required fields are email, firstName, lastName, and either licType or profileId. When you provide profileId, the license type is taken from the profile.

Minimal create with a profile

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "firstName": "Jane",
    "lastName": "Doe",
    "profileId": "16a7490f-86a6-4a14-8ce2-11682230adb6"
  }'

The platform copies every profile-managed field from the profile onto the new user. The user starts life fully in sync with the profile (hasOverrides: false, empty overriddenFields).

Richer create

You can add user-specific fields that don't live on a profile (mobile, extension, title), assign the user to a folder, and override profile-managed fields at creation time:

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "firstName": "Jane",
    "lastName": "Doe",
    "title": "Senior Support Agent",
    "mobile": "+16479308804",
    "extension": "1001",
    "profileId": "16a7490f-86a6-4a14-8ce2-11682230adb6",
    "folderId": "073d010813b941cf7da111d147",
    "locationId": "022d01091776cc88fe6866b7ce",
    "appTheme": "dark",
    "timeZone": "America/Los_Angeles",
    "queues": {
      "access": ["00301090301ad8db0f0d4c370"]
    }
  }'

Important. Any profile-managed field included in the create request becomes an override on the user from day one. In the example above, appTheme, timeZone, and queues.access will appear in the user's overriddenFields. Later PRFUPD jobs will preserve them; an FSYNC will clear them.

What gets pulled from the profile

When you create a user with a profileId and omit a field, the profile's value is used:

  • licType (always inherited)
  • permissions, queues, spaces, attributes, tags, groups
  • appTheme, consoleTheme, timeZone
  • interactionViewsType, definedInteractionViews, modifyInteractionViews
  • commTypeChangeDefaultValue, defaultOutboundCallerId, locationId, dialPlanProfileId
  • Feature flags from the profile (enableWebHID, allowInternalCalls, rejectInteractions, previewOutbound, predictiveOutbound, persistentMedia, etc.)
  • crmConfigId, externalUCProviderConnections, infinityElements

Validation rules

  • email must be unique within the account.
  • licType must be valid for the account (resolved via the profile when profileId is provided).
  • profileId must reference an existing profile.
  • folderId must reference an existing folder.
  • locationId must reference an existing location.
  • The target profile must have fewer than 500 assigned users. Assigning to a profile already at the cap is rejected with 422.

Common errors

StatusCondition
400Request body malformed or required field missing
409A user with the same email already exists in this account
422Validation failed (violations[]), or the target profile is already at the 500-user cap

The duplicate-email 409 response:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "A resource with the same unique constraint values already exists.",
  "violations": [
    { "field": "email", "message": "A user with this email already exists" }
  ]
}

The profile-user-limit 422 response (when assigning to a profile that already has 500 users):

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "Profile User limit of 500 reached. Cannot add user to the profile",
  "violations": [
    {
      "field": "profileId",
      "message": "Profile User limit of 500 reached. Cannot add user to the profile",
      "code": 20005
    }
  ]
}

Reassigning a User to a Different Profile

You reassign a user by PATCH /users/USERID with a new profileId.

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileId": "d5cfccf4-0507-49f8-98d9-34fdaeefca5d" }'

Important: reassignment does not re-apply the new profile's defaults. The user's existing field values are preserved as-is. The association on the user record is updated, but the values on the user are not. If you want the user to actually pick up the new profile's settings, call POST /users/USERID:force-sync-profile immediately after reassigning.

500-user cap on the target profile. Reassigning to a profile that already has 500 assigned users returns 422 with detail: "Profile User limit of 500 reached. Cannot add user to the profile" (violation code 20005). Move existing users off the target profile first, or pick a different profile.

Detaching a user from any profile

Send "profileId": null to clear the association. The user keeps its current field values, but override tracking against the previous profile is dropped.

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileId": null }'

Common recipe: reassign and immediately re-sync

# 1. Reassign
curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileId": "d5cfccf4-0507-49f8-98d9-34fdaeefca5d" }'

# 2. Force-sync the user to the new profile's values
curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e:force-sync-profile' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Editing User Fields and How Overrides Work

PATCH /users/USERID updates one or more user fields. All fields are optional; at least one must be present.

The merge behavior depends on the field type:

FieldMerge Behavior
Scalar fieldsReplaced with the provided value
attributesDeep-merged. Nested keys queue, time, webRTC, recording, signatures, sessionStats are deep-merged; other top-level keys are replaced
permissionsMerged per section (app, console). Keys within each section are replaced with what's sent; keys not included are preserved
queuesOnly sub-properties included in the request are updated; omitted sub-properties are left unchanged. The user's personal queue is always preserved in access and autoLogin
tagsReplaced with the provided array (empty array clears all tags)
groupsReplaced with the provided array (empty array clears all memberships)
spacesReplaced

Override a single field

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "appTheme": "dark" }'

Result: appTheme is added to the user's overriddenFields. The profile's appTheme value no longer applies to this user.

Update a queue assignment without disturbing others

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "queues": {
      "access": ["00301090301ad8db0f0d4c370", "00301090301ad8db0f0d4c371"]
    }
  }'

Only queues.access is replaced. queues.performance, queues.autoLogin, queues.proficiency, etc. are left as they were.

Deep-merge into attributes

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "attributes": {
      "time": { "tz": "Europe/London" }
    }
  }'

Only attributes.time.tz is changed. The rest of attributes (including the other keys inside attributes.time) is preserved.

Clear a field

For fields that accept null, send null to revert to the default or detach the value:

curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "extension": null,
    "mobile": null,
    "commTypeChangeDefaultValue": null
  }'

Agent self-edit restrictions

When an agent edits their own user record (the caller and the target are the same user, and the caller is not an administrator), the server blocks changes to administrator-managed identity fields:

firstName, lastName, namePrefix, nameSuffix, title, email, mobile.

Any self-edit that attempts to change one or more of these fields to a different value returns 403 Forbidden:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "You are not permitted to modify firstName, email. These fields are managed by your administrator."
}

The detail lists the specific fields that were rejected. Sending one of these fields with its current value (e.g. a UI that submits the whole user object on save) is allowed; only attempted changes are blocked.

Administrators (users with console account access) editing other users are not subject to this restriction.

Note on the allowAgentEditAutoAnswer and allowAgentEditWebHIDHeadsetControl flags. These flags exist on both users and profiles. They control whether the Admin Console exposes the Auto Answer and WebHID Headset Control settings as editable in the agent's own profile UI. They do not gate the API: administrators (and the agent themselves) can change attributes.webRTC.autoAnswer.interaction and attributes.webHID.status directly via the API regardless of the flag values.

Agents can freely edit unrestricted fields on themselves: appTheme, consoleTheme, timeZone, queue selections, defined interaction views, attribute settings, and so on.


Force-Syncing Users to a Profile

Force-syncing copies the profile's current values onto a user (or set of users) and clears all overrides for them. After force-sync, the user is fully in sync with their profile.

Feature gate. The force-sync endpoints return 403 Forbidden if the Profile Sync feature is not available for your account. Contact your Avaya representative if you need it enabled.

Single user: synchronous

POST /users/USERID:force-sync-profile performs an immediate, synchronous sync and returns the updated user.

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e:force-sync-profile' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

The response is the full UserDetail after the sync has been applied. The user's overriddenFields list will be empty.

StatusCondition
200Success; body is the updated user
400The user has no associated profile
403The Profile Sync feature is not available for this account
404The user does not exist

Bulk: asynchronous

POST /users:bulk-force-sync-profile operates over many users. It returns immediately with 202 Accepted and a jobId for internal tracking.

The request body uses a oneOf between two modes:

Mode A: explicit user list. Pass up to 50 user IDs. Each user is synced to its own profile (the users may belong to different profiles).

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users:bulk-force-sync-profile?jobName=Quarterly%20Sync' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "userIds": [
      "0024ffcec98220644b194e3e25",
      "0024a83190db2884efeb3bf96d"
    ]
  }'

Mode B: by profile. Pass a profileId. The platform auto-resolves all users that currently have overrides on that profile and force-syncs them. Use this to mass-reset drift after a policy change.

curl -X POST 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users:bulk-force-sync-profile?jobName=Reset%20Overrides' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "profileId": "16a7490f-86a6-4a14-8ce2-11682230adb6"
  }'

Response (202 Accepted):

{
  "jobId": "c8c2909d-75e9-484a-94c0-b7e8d30771fe",
  "url": "/api/config/v1/jobs/c8c2909d-75e9-484a-94c0-b7e8d30771fe"
}

jobId identifies the background job for internal tracking, but polling it directly isn't available in this release. To confirm the sync completed, check back after a short delay with GET /profiles/{profileId}/users?hasOverrides=false; the users you targeted should no longer appear in the overrides list once the force-sync has finished. The job records a per-user error against any user that does not have an associated profile, but those errors do not fail the job as a whole.

StatusCondition
202Accepted; body contains the jobId
400Malformed request
403The Profile Sync feature is not enabled for this account
409A sync job is already pending or running for one of the targeted profiles

Deleting a Profile

DELETE /profiles/{profileId} permanently removes a profile. There is no soft-delete and no undo.

curl -X DELETE 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN'
StatusBody
204Success, no body
404Profile does not exist
409The profile has users assigned to it (see below)

You cannot delete a profile that has users assigned to it. Reassign or detach those users first.

The 409 response:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "Cannot delete profile that is assigned to users"
}

Recipe: delete a profile cleanly

# 1. Find users on this profile
curl -X GET 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6/users' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# 2. Move each user to a different profile (or detach)
curl -X PATCH 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/users/002d011003cf7c9d1b469ddc7e' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "profileId": "d5cfccf4-0507-49f8-98d9-34fdaeefca5d" }'

# 3. Delete the now-empty profile
curl -X DELETE 'https://core.{customerId}.ec.avayacloud.com/api/config/v1/profiles/16a7490f-86a6-4a14-8ce2-11682230adb6' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Errors and Conflicts

All error responses use the application/problem+json content type and follow RFC 7807:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#constraint-violation",
  "title": "Constraint Violation",
  "status": 400,
  "detail": "Request contains invalid or missing fields",
  "violations": [
    { "field": "name", "message": "must not be null", "code": 20002 }
  ]
}

Status codes used by these endpoints

StatusMeaning
400 Bad RequestRequest is malformed or required fields are missing
401 UnauthorizedBearer token is missing, malformed, or expired
403 ForbiddenThe token lacks a required scope, or an agent self-edit hit a restriction, or a feature gate is closed
404 Not FoundThe targeted profile, user, folder, or location does not exist
409 ConflictA uniqueness or state invariant was violated; see the dedicated subsections below
422 Unprocessable EntityThe request is syntactically correct but semantically invalid (violations[] enumerates the offending fields)
429 Too Many RequestsRate limit exceeded; see Retry-After header
500 Internal Server ErrorUnexpected server error; requestId in the body can be quoted to support

Profile-side 409 conflicts

OperationConditiondetail
POST /profilesProfile name already exists in the accountProfile name already exists in this account
PATCH /profiles/{id}New name conflicts with another profileProfile name already exists in this account
PATCH /profiles/{id}A sync job (PRFUPD or FSYNC) is already running for this profileProfile cannot be updated while a sync job is in progress (jobId: ...). Please wait for it to complete.
DELETE /profiles/{id}The profile has users assigned to itCannot delete profile that is assigned to users

User-side 409 conflicts

OperationConditiondetail
POST /usersEmail already in use by another userA resource with the same unique constraint values already exists (with violations[].field = "email")
POST /users:bulk-force-sync-profileA sync job is already pending or running for one of the targeted profilesProfile cannot be updated while a sync job is in progress (jobId: ...). Please wait for it to complete.

Profile-user-limit 422

A profile supports at most 500 assigned users. Two operations enforce this limit:

OperationConditiondetail
PATCH /profiles/{profileId}Profile already has more than 500 users; updates are blocked until the count drops to 500 or belowProfile User limit of 500 reached. Cannot update profile
POST /users or PATCH /users/USERID (with profileId)Target profile is already at the 500-user capProfile User limit of 500 reached. Cannot add user to the profile

Both responses carry violations[].code: 20005. Example:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "Profile User limit of 500 reached. Cannot add user to the profile",
  "violations": [
    {
      "field": "profileId",
      "message": "Profile User limit of 500 reached. Cannot add user to the profile",
      "code": 20005
    }
  ]
}

Agent self-edit 403

Returned when an agent attempts to change one of the administrator-managed identity fields (firstName, lastName, namePrefix, nameSuffix, title, email, mobile) on their own user record:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "You are not permitted to modify firstName, email. These fields are managed by your administrator."
}

The detail lists the specific fields the request attempted to change.

Feature-not-enabled 403

Returned by POST /users/USERID:force-sync-profile and POST /users:bulk-force-sync-profile when the Profile Sync feature is not enabled for the account:

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "Profile sync is not enabled for this account."
}

Token expired 401

{
  "type": "https://developers.avayacloud.com/avaya-infinity/docs/errors#unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Bearer token expired at 2026-05-15T10:15:00Z. Request a new token."
}

Re-request a token using your client credentials (see Authentication) and retry the request.


Did this page help you?