Apps API Documentation

All API updates are backwards compatible. We reserve the right to introduce new JSON keys in existing API responses at any time. We recommend handling responses defensively by disregarding any unrecognized keys to ensure continued functionality.

Basic Authentication

Requests use basic authentication. To create API credentials go to Settings-> Developer Settings-> API Credentials

  • The subdomain is used as the username ({{username}} variable)

  • The token is used as the password ({{password}} variable)

Every installation will have their own subdomain. To find the subdomain, locate the url in your browser, it should look like:

https://customer.rest.of.url.com

Take that subdomain, the most left value, and substitute it into the {{subdomain}} variable. The remainder would be substituted into the {{domain}} variable.

In the above example, {{subdomain}} would be “customer” and {{domain}} would be “rest.of.url.com”

Base URL

The API uses the following base URL for all of its API requests

https://{{subdomain}}.{{domain}}/apps/api/v1

where a mention to “/calls” means https://{{subdomain}}.{{domain}}/apps/api/v1/calls

Calls Endpoints 11

A call object is created for every single call that is made into, or out of the system.

  {
    "id": 0,
    "parent_id": 0,
    "lang": "en",
    "call_type": "Voice Scheduled (API)",
    "status": "scheduled",
    "created_at": "2018-06-07T19:49:52.896Z",
    "queued_at": "2018-06-07T19:49:52.896Z",
    "assigned_at": "2018-06-07T19:49:52.896Z",
    "connected_at": "2018-06-07T19:49:52.896Z",
    "ends_at": "2018-06-07T19:49:52.896Z",
    "scheduled_at": "2018-06-07T19:49:52.896Z",
    "wait_duration": 0,
    "call_duration": 0,
    "hold_duration": 0,
    "rating": 0,
    "has_feedback": true,
    "voip_provider": "voip_provider_twilio",
    "out_ticket_id": "string",
    "out_ticket_url": "string",
    "verified": true,
    "recording_url": "string",
    "recording_permission": "not_asked",
    "voicemail_reason": "not_voicemail",
    "deflection": "no_deflection",
    "disconnected_by": "disconnected_by_unknown",
    "finish_reason": "no_reason",
    "fail_details": "string",
    "fail_reason": "nothing",
    "support_number": "string",
    "selected_menu": {
      "id": 0,
      "name": "string",
      "parent_id": 0,
      "position": 0,
      "deleted": true,
      "hidden": "string",
      "menu_type": "ivr_menu",
      "output_msg": "string"
    },
    "menu_path": {
      "items_count": 0,
      "name": "string",
      "materialized_path": "string"
    },
    "agent_info": {
      "id": 0,
      "name": "string",
      "last_name": "string",
      "first_name": "string",
      "agent_number": "string",
      "avatar_url": "string"
    },
    "end_user": {
      "id": 0,
      "identifier": "string",
      "out_contact_id": "string"
    },
    "photos": [
      {
        "id": 0,
        "photo_type": "photo",
        "url": "string"
      }
    ],
    "videos": [
      {
        "id": 0,
        "url": "string"
      }
    ],
    "transfers": [
      {
        "id": 0,
        "status": "transferring",
        "fail_reason": "nothing",
        "created_at": "2018-06-07T19:49:52.896Z",
        "from_menu": {
          "items_count": 0,
          "name": "string",
          "materialized_path": "string"
        },
        "to_menu": {
          "items_count": 0,
          "name": "string",
          "materialized_path": "string"
        },
        "from_agent": {
          "id": 0,
          "name": "string",
          "last_name": "string",
          "first_name": "string",
          "agent_number": "string",
          "avatar_url": "string"
        },
        "to_agent": {
          "id": 0,
          "name": "string",
          "last_name": "string",
          "first_name": "string",
          "agent_number": "string",
          "avatar_url": "string"
        }
      }
    ],
    "participants": [
      {
        "id": 0,
        "type": "end_user",
        "status": "waiting",
        "call_id": 0,
        "user_id": 0,
        "end_user_id": 0,
        "call_duration": 0,
        "hold_duration": 0,
        "connected_at": "2018-06-07T19:49:52.896Z",
        "ended_at": "2018-06-07T19:49:52.896Z",
        "fail_reason": "nothing"
      }
    ]
  }
]

The status field can be in any of the following states

Call StatusDescription
SelectingState that occurs when an end user has called into the contact center, but is still navigating the menu options prior to being placed in a leaf menu.
QueuedState that occurs after the end user has selected a leaf menu node and initiated a call request to be deltcasted or multicasted to an agent.
AssignedState that occurs when an agent is selected to receive the end user call. This occurs when a call is picked up by an agent.
ConnectingState that occurs after an agent is assigned, and a connection is being established between the end user and the agent.
ConnectedState that occurs when the call has established a connection and the agent and end user are both placed into a call.
FinishedState that occurs when a call ends after it has been connected.
FailedState that occurs when a call ends before it was successfully connected. A fail reason will also be provided for additional details.
SwitchingState that occurs when a call fails while trying to connect and the system attempts to connect the call with a different VOIP provider.
RecoveredState that occurs when a failed call is called back. This new call is a child to the original call. Recovered notes that the call back is finished without error.
ScheduledState that occurs when an end user has scheduled a future call via In-Web or In-App.
Action OnlyState that occurs when a call that is handled by our client’s own telephony provider is connected to our iOS or Android SDK.
Action Only FinishedState that occurs when a call that is handled by our client’s own telephony provider is connected to our iOS or Android SDK and finishes
DeflectedState that occurs based on the configuration for overcapacity queues or after hour calls. Deflection options include voicemail, schedule call among others. Deflection will vary based on channel (In-app, IVR, In-web)
VoicemailState that occurs when an end user is deflected to a voicemail option, and opts to leave a voicemail message to listened to later. This state is present when the end user is leaving the voicemail
Voicemail ReceivedState that occurs after an end user has left a voicemail and an agent has not listened to the voicemail
Voicemail ReadState that occurs when an agent has opened the voicemail to listen to.

The call_type field can only be one of the following values

Call TypeDescription
Voice Outbound (API)Call made from Outbound Call API.
Voice Inbound (API)Call made from Incoming Call API.
Voice Scheduled (API)Call made from Scheduled Call API.

The parent_id field links a call to the call it was created from. It holds the id of the call this call is a call back of, for example when the agent used Hang up & Call back, when a failed or very short call was called back, or when a virtual agent callback was placed for the end user. Call backs made by Hang up & Call back, or of a failed or very short call, all carry the original call’s id, even when they are made from a call that was itself a call back. Any other call back, such as a virtual agent callback, carries the id of the call it was placed from, so when that call was itself a call back, follow its parent_id to reach the original call. For every other call, parent_id is null or not present at all, so treat a missing parent_id the same as null. The Scheduled Calls endpoints (/v1/scheduled_calls and /v1/calls/scheduled/...) return neither parent_id nor finish_reason: a scheduled callback links to the call it came from through callback_data.original_call_id.

On its own, a call back looks like any other outbound call, so use parent_id to tell them apart: a call with parent_id set is a call back of the call with that id, and the finish_reason on the original call says why it ended (for example ag_hung_up_to_callback).

The finish_reason field is null when no reason was recorded, and otherwise one of the following values

Finish ReasonDescription
no_reasonNo specific finish reason was recorded. Most calls end with this value; use disconnected_by and fail_reason to see how they ended.
ag_hung_up_to_callbackThe agent hung up in order to call the end user back. The call back is a separate call whose parent_id is the id of the original call: this call’s id, or this call’s own parent_id if this call is itself a call back.
virtual_agent_escalation_failedThe virtual agent tried to escalate the call to a human agent, the escalation failed and the call ended.
ivr_presession_deflection_completeThe end user was deflected from the IVR to another channel (such as SMS) before reaching an agent, and the deflection completed.
internal_call_declined_by_agentThe receiving agent declined an internal (agent to agent) call.
force_ended_by_adminAn admin or manager force-ended the call.
force_ended_call_stuckThe platform ended the call automatically because it had been stuck in progress for too long.
ended_by_emergency_shutdownThe call was ended because emergency shutdown was activated on its queue.
ended_by_dcr_receiver_hold_timeoutDeprecated. No longer recorded; it can still appear on older calls.
call_declined_by_agentThe agent declined a direct inbound call or an extension call.
call_ended_by_blocked_numberThe call was ended because the end user’s phone number is blocked.
scheduled_call_canceled_by_configThe scheduled call was canceled because the linked CRM record is closed.
scheduled_call_canceled_by_unreachable_crmThe scheduled call was canceled because the CRM could not be reached.
va_callback_machine_detectedA virtual agent callback reached an answering machine instead of the end user, so the call ended.
callback_initiatedThe end user accepted a virtual agent callback. This call ended and the callback is a separate call whose parent_id is this call’s id.
scheduled_callback_submittedThe end user was handed to the booking virtual agent and a callback was scheduled.
scheduled_callback_abandonedThe end user was handed to the booking virtual agent and the call ended without a callback being scheduled.

The following are the most common API Responses:

Response CodeMeaning
201The API request has been successful and will create a call
202The API request has been successful, but manual intervention is required inside of the widget to complete the action
400invalid call type - ensure call_type is supported
400Agent is not available to take this call
400Missing parameter - check to ensure that the required parameters have been added
404Resource not found - Please check your subdomain
Description

ParameterRequiredData TypeDefinitionPostman Variable
call_typeTRUEStringCall type to create. “Voice Outbound (API)”, “OutboundCall” (deprecated) are available for nowVoice Outbound (API)
menu_idFALSEString / IntegerSelected menu id for outbound call to grab settings from queue instead of global settings
agent_emailTRUEStringEmail address for the agent who will be assigned to the outbound call.{{agent_email}}
ticket_idFALSEStringCRM ticket ID and it will dial to the end user who is tied to the ticket.{{ticket_id}}
end_user_numberFALSEStringEnd user phone number which will be dialing. ticket_id has a higher priority than end_user_number.{{end_user_number}}
outbound_numberFALSEStringWell-formed outbound number which is managed from Settings > Phone Numbers > Phone Number Management. Default outbound number will be used when empty{{outbound_number}}
langFALSEStringLanguage of the call. Uses ISO 639-1 codes. (Default: “en”){{lang}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_type": "Voice Outbound (API)", "menu_id": 11, "agent_email": "agent@somedomain.com", "outbound_number": "+1 760-867-5309", "end_user_number": "123123", "lang": "en" }

Description

ParameterRequiredData TypeDefinitionPostman Variable
call_typeTRUEStringCall type to create. “Voice Outbound (API)”, “OutboundCall” (deprecated) are available for nowVoice Outbound (API)
menu_idFALSEString / IntegerSelected menu id for outbound call to grab settings from queue instead of global settings
agent_emailTRUEStringEmail address for the agent who will be assigned to the outbound call.{{agent_email}}
ticket_idFALSEStringCRM ticket ID and it will dial to the end user who is tied to the ticket.{{ticket_id}}
end_user_numberFALSEStringEnd user phone number which will be dialing. ticket_id has a higher priority than end_user_number.{{end_user_number}}
outbound_numberFALSEStringWell-formed outbound number which is managed from Settings > Phone Numbers > Phone Number Management. Default outbound number will be used when empty{{outbound_number}}
langFALSEStringLanguage of the call. Uses ISO 639-1 codes. (Default: “en”){{lang}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_type": "Voice Outbound (API)", "menu_id": 11, "agent_email": "allen@somedomain.com", "outbound_number": "+1 760-867-5309", "ticket_id": "123123", "lang": "en" }

Description

ParameterRequiredData TypeDefinitionPostman Variable
call_typeTRUEStringCall type to create. Use “Voice Inbound (API)” or “IncomingCall” (deprecated) to create an incoming call.Voice Inbound (API)
menu_idTRUEIntegerThe ID of the menu to attribute the call to. Only IVR and Web menu IDs are accepted.{{menu_id}}
end_user_numberTRUEStringThe end user phone number that will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{end_user_number}}
langFALSEStringLanguage of the call. Uses ISO 639-1 codes. (Default: “en”){{lang}}
ticket_idFALSEStringCRM ticket ID. The end user phone number tied to the ticket will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{ticket_id}}
outbound_numberFALSEStringThe outbound phone number to be used for the call. The default global outbound phone number will be used if input is not passed in or invalid. Outbound numbers are managed from Settings > Queue > EDIT / VIEW > Select a queue > Outbound Phone Numbers.{{outbound_number}}
recording_permissionFALSEStringThe value is only evaluated if the “Call Recording Options” feature is set to “Ask User for Permission to Record”. Configurable at Settings > Queue > EDIT / VIEW > Select a queue > Call Recording Options. If the value is either “recording_permission_not_asked” (default) or “recording_permission_denied”, the call will not be recorded. If the value is “recording_permission_granted”, the call will be recorded.{{recording_permission}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_type": "Voice Inbound (API)", "lang": "en", "menu_id": 9, "ticket_id": "76517", "end_user_number": "+1 859-657-9625", "recording_permission": "recording_permission_granted" }

Description

ParameterRequiredData TypeDefinitionPostman Variable
call_typeTRUEStringCall type to create. Use “Voice Scheduled (API)” or “ScheduledCall” (deprecated) to create a scheduled call.Voice Scheduled (API)
menu_idTRUEIntegerThe ID of the menu to attribute the call to. Only Mobile and Web menu IDs are accepted.{{menu_id}}
call_idFALSEIntegerCall ID of previous call, which will be linked as the parent call of the new created scheduled call. When call ID is being used, menu_id can be optional.{{call_id}}
end_user_numberTRUEStringThe end user phone number that will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{end_user_number}}
langFALSEStringLanguage of the call. Uses ISO 639-1 codes. (Default: “en”){{lang}}
ticket_idFALSEStringCRM ticket ID. The end user phone number tied to the ticket will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{ticket_id}}
scheduled_atTRUEStringScheduled time of the call. Uses ISO 8601 format to a valid future time.{{scheduled_at}}
recording_permissionFALSEStringThe value is only evaluated if the “Call Recording Options” feature is set to “Ask User for Permission to Record”. Configurable at Settings > Queue > EDIT / VIEW > Select a queue > Call Recording Options. If the value is either “recording_permission_not_asked” (default) or “recording_permission_denied”, the call will not be recorded. If the value is “recording_permission_granted”, the call will be recorded.{{recording_permission}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_type": "Voice Scheduled (API)", "lang": "en", "menu_id": 9, "end_user_number": "+1 859-657-9625", "scheduled_at": "2019-09-15T00:19:14.421Z", "recording_permission": "recording_permission_granted" }

Description

ParameterRequiredData TypeDefinitionPostman Variable
call_typeTRUEStringCall type to create. Use “Voice Scheduled (API)” or “ScheduledCall” (deprecated) to create a scheduled call.Voice Scheduled (API)
menu_idTRUEIntegerThe ID of the menu to attribute the call to. Only Mobile and Web menu IDs are accepted.{{menu_id}}
call_idFALSEIntegerCall ID of previous call, which will be linked as the parent call of the new created scheduled call. When call ID is being used, menu_id can be optional.{{call_id}}
end_user_numberTRUEStringThe end user phone number that will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{end_user_number}}
langFALSEStringLanguage of the call. Uses ISO 639-1 codes. (Default: “en”){{lang}}
ticket_idFALSEStringCRM ticket ID. The end user phone number tied to the ticket will be dialed. If both a ticket_id and end_user_number are passed in, the ticket_id will take precedence.{{ticket_id}}
scheduled_atTRUEStringScheduled time of the call. Uses ISO 8601 format to a valid future time.{{scheduled_at}}
recording_permissionFALSEStringThe value is only evaluated if the “Call Recording Options” feature is set to “Ask User for Permission to Record”. Configurable at Settings > Queue > EDIT / VIEW > Select a queue > Call Recording Options. If the value is either “recording_permission_not_asked” (default) or “recording_permission_denied”, the call will not be recorded. If the value is “recording_permission_granted”, the call will be recorded.{{recording_permission}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_type": "Voice Scheduled (API)", "lang": "en", "menu_id": 9, "ticket_id": "76517", "end_user_number": "+1 859-657-9625", "scheduled_at": "2019-09-15T00:19:14.421Z", "recording_permission": "recording_permission_granted" }

Description

Create a new scheduled callback. IVR menus skip the scheduled_call_enabled check since the setting is not yet available in IVR queue settings.

original_call_id is the canonical request-body field for the ID of the original call that triggered this scheduled callback. UJET stores this reference and makes it available to downstream virtual agent and CRM integrations as the original_call_id data parameter. call_id and parent_call_id are kept as deprecated legacy aliases for backwards compatibility — when multiple aliases are sent, resolution order is original_call_id -> call_id -> parent_call_id. Prefer original_call_id for new integrations.


Selected request fields

  • end_user_number (required, string) — E.164; the consumer number to call back.
  • scheduled_at (required, string) — ISO 8601; must be in the future.
  • menu_id (integer) — required unless one of original_call_id / call_id / parent_call_id is supplied.
  • ani (string, optional) — E.164 caller line identity. Honored only when phone-number retention is enabled for the tenant; otherwise ignored. Duplicate detection also matches on ani. Supplying ani inside custom_parameters does NOT populate the ANI field.
  • recording_permission — one of recording_permission_not_asked, recording_permission_granted, recording_permission_denied.
  • user_authenticated — Y or N.

The response includes a callback_data object echoing the callback metadata (including ani, ticket_id, and call_id).

Error responses

  • 400 — invalid menu/language/call reference (menu_id is required, queue {id} does not exist, Only mobile, web, and IVR menu IDs are permitted, Language '{lang}' is not available).
  • 422 — request validation failed, or a booking conflict; body is { "message": "<text>" }. One of:
    • invalid request (invalid E.164 end_user_number / dnis / ani, malformed scheduled_at, invalid enum, Queue ID does not exist)
    • minimum wait time — Scheduled time is before minimum wait time. Minimum scheduled time: {iso8601}
    • outside business hours — Scheduled time is outside business hours
    • duplicate — A scheduled callback already exists for this phone number (matched on end_user_number or ani)
  • 409 — slot at capacity — { "code": "slot_unavailable", "sub_code": "at_capacity", "message": "slot_at_capacity", "display_message": "The selected time slot is no longer available." }

Note: the reschedule (PATCH) endpoint does not re-run the minimum-wait, hours-of-operation, or capacity checks.

Body
{ "scheduled_at": "2021-06-16T01:36:01.442Z", "end_user_number": "+14155551234", "menu_id": 9187, "lang": "en", "original_call_id": 723, "recording_permission": "recording_permission_granted", "ticket_id": "string", "dnis": "+18005551234", "first_name": "John", "last_name": "Doe", "user_authenticated": "Y", "callback_reason": "after_hours", "custom_parameters": { "key1": "value1", "key2": "value2" }, "ani": "+14155559999" }

Description

Used to update the end_user associated with the current active call session. Additionally, it also updates the contact information linked to the CRM ticket. _Identifier is required, while name, email, and phone are optional. Note: If a phone number is already set, providing a phone parameter will not update the phone number.

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
call_id
Body
{ "identifier": "string", "name": "string", "email": "string", "phone": "string" }

URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "verified_customer": "boolean", "bad_actor": "boolean", "repeat_customers": "boolean" }
URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "verified_customer": "boolean", "bad_actor": "boolean", "repeat_customers": "boolean" }
URL Variables
KeyValueDescription
idinteger

(Required)


Description

Adds a third party participant to an existing call. The agent must be connected to the call to initiate the third party dial.

ParameterRequiredData TypeDefinitionPostman Variable
agent_emailTRUEStringEmail address of the agent who is connected to the call and initiating the third party dial{{agent_email}}
phone_numberTRUEStringPhone number of the third party to dial. Can be formatted (e.g., +1 (226) 336-1437) or unformatted (e.g., 12263361437)


Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
id123

Call ID

Body
{ "agent_email": "{{agent_email}}", "phone_number": "+1 (226) 336-1437" }

SMS 1

Description

ParameterRequiredData TypeDefinitionPostman Variable
chat_typeTRUEStringChat type to create. “Messaging (API)”, “SMS” (deprecated) are available for nowMessaging (API)
end_user_numberTRUEStringNumber the text message is to be sent to{{end_user_number}}
outbound_numberTRUEStringOutbound phone number to be used for sending the SMS message{{outbound_number}}
messageTRUEStringSMS message to be sent to consumer{{message}}
ticket_idFALSEStringCRM ticket ID that will be associated with session{{ticket_id}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "chat_type": "Messaging (SMS)", "end_user_number": "+1 415-555-0100", "outbound_number": "+1 628-555-0199", "message": "lorem ipsum", "ticket_id": "5006x00000XXxxxXXX" }

Wait Times 2

Description

ParameterRequiredData TypeDefinitionPostman Variable
langTRUEStringLanguage code of the queue. (e.g. ‘en’){{lang}}
menu_idFALSEIntegerResponse will filter all menus in that menu’s subtree, including that menu.{{menu_id}}
menu_typeFALSEStringReturns menus of specific types. Possible values: ivr_menu, mobile_menu, web_menu).{{menu_type}}
channel_typeFALSEStringReturns menus of a specific channel. Possible values: voice_call, chat).{{channel_type}}
wait[from]FALSEIntegerReturns records if they have a wait greater than the value.{{wait[from]}}
wait[to]FALSEIntegerReturns records if they have a wait less than the value.{{wait[to]}}


Headers
KeyValueDescription
Content-Typeapplication/json

Description

ParameterRequiredData TypeDefinitionPostman Variable
langTRUEStringLanguage code of the queue. (e.g. ‘en’){{lang}}
menu_idFALSEIntegerResponse will filter all menus in that menu’s subtree, including that menu.{{menu_id}}
menu_typeFALSEStringReturns menus of specific types. Possible values: ivr_menu, mobile_menu, web_menu).{{menu_type}}
channel_typeFALSEStringReturns menus of a specific channel. Possible values: voice_call, chat).{{channel_type}}
wait[from]FALSEIntegerReturns records if they have a wait greater than the value.{{wait[from]}}
wait[to]FALSEIntegerReturns records if they have a wait less than the value.{{wait[to]}}


Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "call_id" : "1917", "agent_id" : "1", "lcm_key" : "2922|1|2|39|2|0|1", "dnis" : "8001992999", "org_id" : "tenant1", "contact" : { "first_name" : "Alex", "last_name" : "Phil", "account_no" : "10002-2989", "crm_id" : "220-39307-92", "address" : "", "city" : "", "loan_type" : "", "due_date" : "" }, "pacing_mode" : "Predictive", "call_type" : "OB_Regular" }

Bulk User Management 7

Create/Update a large number of users through the Bulk User Management collection.

Supports JSON files. Sample json data can be obtained through the Template API.

Only api_user authentication is supported. You must enter the api user token in the password variable. Lagacy authentication(using a company secret) is not supported.

When a JSON file is uploaded through the upload API, a job is created and validates the json file scheme.

The JSON file format is shown below and also can be checked through the GET Template API.

Field(s) nameValuesRequiredValidation
emailString(Email)YesMust be a valid email. Must be unique within the file within Email column (no duplicates). so only 1 update per email address per file
new_emailString(Email)NoMust be a valid email. Must be unique within the file within New Email column (no duplicates). so only 1 update per email address per file
agent_numberStringNoA string with no validation
first_nameStringYesNon-empty string
last_nameStringYesNon-empty string
statusActive, Inactive, EmptyNoMust be “Active”, “Inactive”, or empty
locationA string that is a location name, Empty, NullNoMust exactly match one of the existing locations (case-insensitive), or Null, or empty
max_chat_limit1 to X (where X is configured value), EmptyNoMust be 1 to X (inclusively), or empty
max_chat_limit_enabled0, 1, EmptyNoMust be 0, 1 or empty
rolesname: Role name / value: 0, 1, EmptyNoMust be 0, 1 or empty
teamsname: Team name / value: 0, 1, EmptyNoMust be 0, 1 or empty

When the scheme check is successful, the Proceed API can be executed, and user creation/modification work is in progress.

Upload and Proceed are asynchronously performed by the worker, and you can check the status through the Job API with a job_id.

The status field of Job can be in any of the following states.

Job statusDescription
createdA job is created and waiting for validation.
valid_schemeScheme validation is successful and proceed is possible.
invalid_schemeScheme validation failed. Detailed information can be checked through the Scheme error log API.
in_progressPerforming bulk user update/create.
finishedBulk user update/create complete.


Body
KeyValueDescription
file

Body
KeyValueDescription
id{{job_id}}
file

Body
KeyValueDescription
id{{job_id}}



Campaign Endpoints 7

A campaign refers to an outbound auto-dialer feature that sequentially reaches out to a list of contacts, initiates outbound calls, and connects each contact to an available agent. Campaign endpoints provide access to campaign-related data, allowing retrieval of campaign and contact objects.

  • Campaign object: represents a single campaign within the platform.
  • Contact object: represents an individual campaign contact within a specific campaign.

Currently, the campaign endpoints allow users to add, update, and delete contacts of an existing campaign. In future releases, the campaign endpoints will allow users to create, edit and delete campaigns.

[
   {
        "assigned_call_id": 32001,
        "assigned_participant_id": 54321,
        "campaign_id": 240,
        "created_at": "2023-04-01T17:15:38.000Z",
        "id": 16312,
        "name": "string",
        "outbound_number": null,
        "priority": null,
        "status": "Upcoming",
        "unique_id": "string",
        "updated_at": "2023-04-01T17:15:38.000Z"
    },
    {
        "assigned_call_id": 32002,
        "assigned_participant_id": 54330,
        "campaign_id": 240,
        "created_at": "2023-04-01T17:15:38.000Z",
        "id": 16313,
        "name": "string",
        "outbound_number": null,
        "priority": null,
        "status": "Finished",
        "unique_id": "string",
        "updated_at": "2023-04-01T17:25:00.000Z"
    }
]

The status field can be in any of the following states

Campaign Contact StatusDescription
UpcomingContact is next to be dialed.
DialingContact is right now being dialed.
QueuedCall for a given contact is queued.
ConnectedContact is connected with an agent.
FinishedCall has completed.
TransferredCall has been transferred.
Transferred and FinishedCall has been transferred and then completed.
Not Picked UpNo answer from end user or never reached the end user.
Not Reached to ContactCall never reached the contact .
Abandoned by ContactFor preview, end user hangs up before connected to an agent.

For both progessive and predictive, end user hangs up the call within 5 seconds after connecting to the agent.
SkippedContact has been skipped by agent and will be available to be connected to another agent.
Skipped & ClosedOn Preview, agent skips and close a contact. This contact should now be always skipped in this campaign.
Invalid NumberContact with invalid phone number.
Carrier ErrorThis error is driven by carrier.
Abandoned by DialerContact has been abandoned by dialer.
Voicemail Hung UpOn Predictive, the dialer determines the end user is a machine (ie. voicemail).
Dialer General ErrorCall failed due to dialer error.
Redial ScheduledTemporary status. Redial scheduled in the future.
Do Not CallThe number was in Do-Not-Call number list.
Invalid Outbound NumberContact with invalid outbound number.
Blocked Phone NumberContact with invalid/blocked international number.
Body
{ "name": "string", "email": "customer@somedomain.com", "phone_number": "+1 111-111-1111", "outbound_number": "+1 760-867-5309", "external_unique_id": "UID_123456" }
Body
KeyValueDescription
filesome/path/to/multi_contacts.json

Body


Body
{ "contact_id": 16312, "name": "string", "email": "customer@somedomain.com", "phone_number": "+1 111-111-1111", "external_unique_id": "UID_123456" }
Body
{ "contact_id": 16312, "phone_number": "+1 111-111-1111", "external_unique_id": "UID_123456" }

Agent Status Endpoints 4

Agent Status Endpoint
The Agent Status endpoint allows you to modify the status of agents. It enables changes to and from ‘Available’ to any custom status. Transitions to and from system-defined statuses like ‘In-Call’ will trigger an error. Additionally, this endpoint supports bulk updates, allowing status modifications for entire teams or selected groups of agents simultaneously.
Force Logout Agents Endpoint
The Force Logout Agents endpoint provides the functionality to forcibly log out online agents. Agents engaged in active calls or chats will be logged out automatically upon the completion of their current interactions, whereas idle agents are logged out immediately. This endpoint supports forced logouts of specific agents, entire teams, or agents identified by IP addresses with CIDR notation, a list of IPv4/IPv6 addresses, or IP ranges (see the request examples). For a large number of agents, a background job is created to manage the logout process efficiently.

Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "status": "Available", "agent_ids": [11, 12], "team_ids": [] }

Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "agent_ids": [11, 12], "team_ids": [1], "ip_addrs": ["34.211.11.0/24"] }

Headers
KeyValueDescription
Content-Typeapplication/json
Body
{ "agent_ids": [11, 12], "team_ids": [1] }

URL Variables
KeyValueDescription
id

End Users 2

Description

Creates or updates an end user based on a given identifier

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "identifier": "string", "email": "string", "name": "string", "phone": "string" }

Description

Get End User external identifier and internal ID, given one of the fields

Headers
KeyValueDescription
Acceptapplication/json
Query
KeyValueDescription
idinteger

Internal ID for the End User

identifierstring

External identifier for the End User


Chats 24

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "finished_by_user_id": "integer", "chat": { "deflection_channel": "string", "status": "string", "escalation_id": "integer" } }

Description

Send a message in a chat.

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "from_user_id": "integer", "message": { "type": "string", "content": "string", "media_id": "string" } }

Description

Escalate a chat from a Virtual Agent to a Human Agent.

Response fields

  • id — escalation ID. Pass it to PATCH /chats/{chat_id}/escalations/{id} to record a deflection choice, or as chat.escalation_id when ending the chat.
  • chat_id — ID of the chat the escalation belongs to.
  • status — one of escalating, escalated, canceled, deflecting, deflected.
  • deflection — the alternative UJET is offering because the queue is closed or over capacity. no_deflection when the escalation is proceeding to an agent; otherwise one of over_cap, over_cap_email, over_cap_virtual_agent, over_cap_human_agent, after_hours, after_hours_email, after_hours_virtual_agent.


Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required) Chat ID to escalate

Body
{ "reason": "string", "force_escalate": "boolean" }

Description

Records the end user’s deflection choice on an escalation. Used only for selecting a deflection channel currently. PUT is accepted as well as PATCH.

Response fields

  • id — escalation ID.
  • chat_id — ID of the chat the escalation belongs to.
  • status — one of escalating, escalated, canceled, deflecting, deflected.
  • deflection — the recorded outcome. no_deflection when no deflection applies; otherwise one of over_cap, over_cap_email, over_cap_virtual_agent, over_cap_human_agent, after_hours, after_hours_email, after_hours_virtual_agent.


Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required)

idinteger

(Required)

Body
{ "deflection_channel": "string" }

Description

Add a photo that has been uploaded to media storage to a chat

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required)

Body
{ "photo": [ { "s3_path": "string", "photo_type": "string" }, { "s3_path": "string", "photo_type": "string" } ] }

Description

Retrieves media ID’s and storage url’s for all photos attached to the chat

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
chat_id

Description

Used for fetching a presigned upload URL

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required)


Description

Add a video that has been uploaded to media storage to a chat

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required)

Body
{ "video": { "s3_path": "string" } }

Description

Retrieves media ID’s and storage url’s for all videos attached to the chat

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
chat_id

Description

Fetches a single media file (photo, video, audio, document) attached to the chat and returns the raw binary content. The response exposes the file name via the X-File-Name header.

Headers
KeyValueDescription
Acceptapplication/json
Query
KeyValueDescription
media_id{{media_id}}

(Required)

media_type{{media_type}}

(Required) photo / video / audio / document

URL Variables
KeyValueDescription
chat_idinteger

(Required)


Description

Used for fetching a presigned upload URL for the company’s configured cloud storage service

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
chat_idinteger

(Required)


Description

Start a new chat.

ParameterRequiredData TypeDefinition
chat.client_referenceFALSEObjectOpaque correlation reference. Requires the chat-api-client-reference-id feature flag. Echoed on this response and at the top level of every chat webhook envelope. Omitted (not null) when not supplied.
chat.client_reference.idRequired if client_reference presentStringConsumer-supplied correlation key. Max 255 chars. Stored verbatim; non-unique across chats.
chat.client_reference.metadataFALSEObjectFlat string key/value map echoed with id. Values must be strings (nested objects rejected). Serialized size at most 8192 bytes.

Chat DAP and orchestration (optional)

Everything above is unchanged. This section applies only to tenants that have Chat DAP (API Request Direct Access Point for Chat) configured; for everyone else the endpoint behaves exactly as described above and the chat is created in menu_id.

When Chat DAP is configured, this endpoint resolves the DAP before the chat is created: the platform calls your DAP endpoint (API Response mode), matches the returned key-value pairs against the queue Access Points and, on a match, creates the chat directly in the matched queue instead of menu_id. Orchestration actions returned in events (send_response, assign_to_queue, end_chat) are applied to the created chat exactly as for web and mobile chats. When nothing matches, or the DAP request fails or times out, the chat is created in menu_id as usual.

Prerequisites — without all three the section does not apply:

  1. Chat DAP is enabled for your tenant by UJET — contact Support.
  2. An admin has configured Settings → Developer Settings → Manage API Request Direct Access Point → Chat: toggle on, Direct Access Point Type = API Response, and Pass Data Parameters on with at least one parameter (with it off the platform sends an empty request body).
  3. Each target queue has an Access Point of type API Response whose key-value pairs match what your DAP endpoint returns.

See the Support Center article API Request Direct Access Point for Chats for the configuration steps and the DAP request/response contract.

Additional optional fields on the chat object — all are forwarded to your DAP endpoint and have no effect when Chat DAP is not configured:

ParameterRequiredData TypeDefinition
chat.direct_access_keyFALSEStringGeneral Access Point label evaluated by the DAP routing logic’s General Access Point Label step.
chat.initial_messageFALSEStringConsumer’s opening message, forwarded as initial_message. Ignored (not forwarded) when longer than 2000 characters.
chat.custom_data_signedFALSEStringSigned custom data (JWT), forwarded as custom_data_signed. Ignored (not forwarded) when larger than 16 KB.
chat.custom_data_unsignedFALSEObjectUnsigned custom data, forwarded as custom_data_unsigned. Ignored (not forwarded) when larger than 8 KB serialized or nested deeper than 5 levels.

Reading the result. The routed queue is the last entry of menus in the response. send_response and end_chat are applied right after the chat is created; observe them through the chat webhooks (message_received with sender: "system", chat_ended) or GET /chats/:id.

Existing chat in queue. If the end user already has a chat waiting in a queue (created within the last 24 hours), that chat is returned instead of a new one — this is the Resumed chats case of the Chat Types setting. The DAP request is still made and recorded when Resumed chats are enabled, but its result does not move the existing chat.

Scope. Webhook Response mode applies to the web and mobile SDK channels; chats created through this endpoint use API Response mode. When the tenant is configured for Webhook Response, this endpoint skips the DAP and creates the chat in menu_id.

Latency. With Chat DAP active the request includes one round trip to your DAP endpoint, bounded by the tenant’s API Request Timeout (1–10 s). Set your HTTP client timeout above that value so a slow DAP response is not retried as a failed request.

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "chat": { "menu_id": "integer", "end_user_id": "integer", "lang": "string", "email": "string", "context": "object", "transcript": "object", "client_reference": { "id": "string", "metadata": { "key": "value" } }, "direct_access_key": "string", "initial_message": "string", "custom_data_signed": "string", "custom_data_unsigned": "object" }, "end_user": { "phone": "string" } }

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
idinteger

(Required)


Description

If a chat has been dismissed for inactivity, an end user may resume the same chat. Chat status must be “dismissed” or “va_dismissed”

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
idinteger

(Required)


Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
idinteger

(Required)


URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "verified_customer": "boolean", "bad_actor": "boolean", "repeat_customers": "boolean" }
URL Variables
KeyValueDescription
idinteger

(Required)

Body
{ "verified_customer": "boolean", "bad_actor": "boolean", "repeat_customers": "boolean" }
Description

Send custom data in a chat

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
id

(Required)

Body
// Use unsecured parameter { "signed": false, "data": { // Start customer_flag fields "reserved_verified_customer": { "label": "LABEL 1", "value": true }, "reserved_bad_actor": { "label": "LABEL 2", "value": false }, "reserved_repeat_customer": { "label": "LABEL 3", "value": true }, // End customer_flag fields "field1": { "label": "LABEL 4", "value": "dummy1" }, "field2": { "label": "LABEL 5", "value": "dummy2" } } } // Use secured parameter // { // "signed": true, // "signed_data": "eyJhbGciOiJIUzI1NiJ9.eyJjdXN0b21fZGF0YSI6eyJyZXNlcnZlZF92ZXJpZmllZF9jdXN0b21lciI6eyJ2YWx1ZSI6ZmFsc2V9LCJyZXNlcnZlZF9iYWRfYWN0b3IiOnsidmFsdWUiOnRydWV9LCJyZXNlcnZlZF9yZXBlYXRfY3VzdG9tZXIiOnsidmFsdWUiOmZhbHNlfSwiZmllbGQxIjp7InZhbHVlIjoiZHVtbXkxMTEifSwiZmllbGQyIjp7InZhbHVlIjoiZHVtbXkyMjIifX0sImV4cCI6MTcyOTY4MzU5MywiaWF0IjoxNzI5Njc5OTkzfQ.BMskgKTM3DbgrMLWjI46ZJ1K73H25JRd16SgHK0A1Ts" // } // ======================= How to create <signed_data> ======================= // payload = { // "custom_data": { // // Start customer_flag fields // "reserved_verified_customer": { // "label": "LABEL 1", // "value": true // }, // "reserved_bad_actor": { // "label": "LABEL 2", // "value": false // }, // "reserved_repeat_customer": { // "label": "LABEL 3", // "value": true // }, // // End customer_flag fields // "field1": { // "label": "LABEL 4", // "value": "dummy1" // }, // "field2": { // "label": "LABEL 5", // "value": "dummy2" // } // }, // "exp": 1734567890, // expiration timestamp // "iat": 1734560000 // issue timestamp // } // signed_data = JWT.encode(payload, 'Company secret', 'HS256') // ======================= End how to create <signed_data> =======================

Description

Used to update the end_user associated with the current active chat session. Additionally, it also updates the contact information linked to the CRM ticket. _Identifier is required, while name, email, and phone are optional. Note: If a phone number is already set, providing a phone parameter will not update the phone number.

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
chat_id
Body
{ "identifier": "string", "name": "string", "email": "string", "phone": "string" }

URL Variables
KeyValueDescription
chat_id
Body
{ "ended_by_user_id": "integer" }

Description

Returns CSAT eligibility for a finished chat along with localized survey messages.

Call this after PATCH /apps/api/v1/chats/:chat_id/end. When eligible is true, present the survey using the strings in messages, then submit via PATCH /apps/api/v1/chats/:chat_id/rating.

Eligibility gates (evaluated in order): 1. chat-api-csat feature flag is ON (else 404) 2. Operation Management CSAT is enabled 3. Chat is finished 4. Chat has not already been rated 5. Queue-level chat_api_csat resolves to true (Global > Parent > Queue inheritance)

Optional per-request message overrides:

Callers may supply an optional messages map to override any of the five admin-configured survey strings on a per-request basis. Each override key is independent — omitted keys fall back to the admin-configured Audible value. Unknown keys are silently dropped (forward-compat); empty or whitespace-only values fall back to the admin value rather than blanking the field.

Wire format is deepObject query parameters, e.g. ?messages[form_title]=Rate%20your%20chat&messages[result_subtitle]=Thanks!.

Override validation rules: - Recognized keys: form_title, form_feedback, result_title, result_subtitle, feedback_label - Each value: must be a string, max 300 raw characters - Forbidden characters: Unicode control characters (category Cc) except TAB, LF, CR. Zero-width chars, BIDI controls, joiners, BOM, and emoji ZWJ sequences are accepted. - Override values are HTML-escaped server-side before being returned in messages. Admin-resolved (non-override) values pass through raw. - Validation failures return 400 with validation_errors[] listing each offending field and a wire-format code (invalid_type, too_long, invalid_characters). Partner integrations may parse the code values directly.

Override of a null admin value flips a previously-ineligible chat to eligible — but a per-field override cannot rescue an entirely absent admin config (the 5-field completeness check still ineligibles out if messages cannot be fully resolved).

Response keys: - eligible (boolean): whether to show the CSAT survey - messages (object|null): localized strings keyed by form_title, form_feedback, result_title, result_subtitle, feedback_label. null when ineligible. form_feedback and feedback_label are omitted when feedback_enabled is false. - feedback_enabled (boolean): client-side presentation hint sourced from Operation Management csat_settings.feedback_enabled. Not enforced server-side.

URL Variables
KeyValueDescription
chat_id

Description

Returns the current CSAT rating for a chat.

Response body: - rating (number|null): float between 0 and 5 (e.g. 4.0, 3.7), or null until the consumer submits one via PATCH /apps/api/v1/chats/:chat_id/rating.

Returns 404 when the chat-api-csat feature flag is OFF or the chat is not found.

URL Variables
KeyValueDescription
chat_id

Description

Submits a CSAT rating for a finished chat.

Request body: - rating (number, required): 0 to 5. Float values are accepted (e.g. 3.7). - feedback (string, optional): free-text feedback. Stored regardless of feedback_enabled; the toggle only controls whether the survey UI prompts for it.

Server re-runs the same eligibility checks as GET /apps/api/v1/chats/:chat_id/csat. A stale or hostile client cannot submit a rating to a chat the eligibility endpoint would refuse.

Errors: - 400 — rating is missing or not a number - 404 — feature flag OFF or chat not found - 422 — eligibility check failed; rating out of range; chat became unfinished or was rated between eligibility check and submit; or rating not permitted by company CSAT settings / time window

On success the chat’s chat_csat_submitted event is created and the rating is forwarded to CRM and reporting.

URL Variables
KeyValueDescription
chat_id
Body
{ "rating": 4, "feedback": "Great experience!" }

Description

Customer-side ingress for Chat DAP (Direct Access Point) Webhook Response routing mode.

Scope. This callback serves the web and mobile SDK flow. Chats created through POST /apps/api/v1/chats use API Response mode and never involve this endpoint.

Flow 1. The end-user SDK calls GET /v2/menus and the platform places the chat on hold. 2. The platform sends your configured DAP endpoint the DAP request payload with two extra fields: chat_dap_id (the hold id) and webhook_url (the absolute URL of this endpoint for your tenant). Your endpoint must answer with a 2xx acknowledgment within the API Request Timeout. 3. Your system does its own lookup (CRM, segmentation, business rules) and POSTs the result to webhook_url within the API Callback Timeout. 4. The platform resolves the hold against the tenant’s DAP routing logic order (api_response → general_access_point_label → user_segmentation) and the SDK’s polling on GET /v2/menus?dap_request_id=… unblocks. chat_dap_id on this callback and dap_request_id on the SDK path are the same value.

Available when Chat DAP is enabled for your tenant — contact Support.

Authentication

HTTP Basic, same as the rest of Apps API. - Username: company subdomain ({{username}}) - Password: API token from Settings → Developer Settings → API Credentials ({{password}})

Headers

HeaderRequiredNotes
AuthorizationyesSet automatically by Postman from the Basic auth above.
Content-Type: application/jsonyesBody must be JSON.
Accept: application/jsonnoRecommended.
UJET-SUBDOMAINnoTenant identifier. Normally inferred from the host; only needed when calling through a host that does not carry the tenant subdomain. Disabled by default.

Request body

FieldTypeRequiredNotes
chat_dap_idstringyesThe hold id received in the outbound DAP request. Max 255 chars.
key_value_pairsobjectone of key_value_pairs / eventsRouting payload matched against the queue Access Points of type API Response (dotted paths are supported, e.g. user.tier).
eventsarrayone of key_value_pairs / eventsOrchestration actions — see Orchestration actions below.
errorstring | nullnoOptional customer-side error message recorded on the inbound audit row. Max 1024 chars; non-string values are ignored.

The serialized body must not exceed 65,535 bytes.

Minimal example (routing only):

{
  "chat_dap_id": "a3f8e2c5d9b6f4e2a1c8b3a5d7f9e2b4",
  "key_value_pairs": {
    "region": "us-east"
  }
}

Orchestration actions (events)

events is an ordered array of actions. The same array is accepted at the root of an API Response mode response (next to the key-value pairs) and here, as a sibling of key_value_pairs.

{
  "chat_dap_id": "a3f8e2c5d9b6f4e2a1c8b3a5d7f9e2b4",
  "events": [
    { "type": "send_response", "message": "Thanks for reaching out — one moment." },
    { "type": "assign_to_queue", "key_value_pairs": { "team": "billing" }, "human_agent": true, "skills": ["billing", "en"], "skills_operator": "AND" },
    { "type": "end_chat" }
  ]
}
typeRequiredOptionalBehavior
assign_to_queuekey_value_pairs (object)human_agent (bool), virtual_agent (bool), skills (array of up to 100 strings), skills_operator (AND | OR)Routes to the queue whose API Response Access Point matches key_value_pairs. human_agent bypasses the queue’s virtual agent; virtual_agent sends the chat to the virtual agent even when human agents are available; the two are mutually exclusive. skills narrow the agent choice inside the queue when the Access Point’s Prioritize skills if available is enabled.
send_responsemessage (string, max 2000 chars)—Delivers the message to the consumer as a system message.
end_chat——Ends the chat before it is offered to any agent or virtual agent. Always executes last when combined with other actions.

Rules: - When the root key-value pairs match an Access Point, that routing wins and events are not applied. Key-value pairs that match nothing do not suppress events. - An events array that fails validation (unknown type, both agent flags true, oversized skills or message, non-array value) is ignored as a whole and standard routing applies. The chat is never left in a stuck state.

Response (200)

The success body is intentionally minimal — the webhook caller only needs an ACK:

{
  "ack": "ok"
}

Hold-resolution detail (direct_access_key_id, matched step) is not returned to the customer. It is surfaced to the end-user SDK via its polling on GET /v2/menus?dap_request_id=… and recorded server-side on the inbound audit row and in structured logs for operations visibility.

Errors

CodeWhen
400chat_dap_id missing, empty or over 255 chars; neither key_value_pairs nor events present; serialized body over 65,535 bytes.
401Basic auth credentials missing or invalid.
404Chat DAP is not enabled for this tenant.
422No callback target for chat_dap_id: unknown id, or the hold was already resolved by an earlier callback, timed out, or the outbound request had failed.

Retries and idempotency

A callback rejected with 400 leaves the hold untouched, so a corrected retry inside the API Callback Timeout is still accepted (the last valid callback within the window wins). A retry after a callback was already accepted returns 200 again. A retry after the hold closed (timeout or request failure) returns 422.

Headers
KeyValueDescription
Content-Typeapplication/json

Required. Body must be JSON.

Acceptapplication/json

Recommended.

Body
{ "chat_dap_id": "a3f8e2c5d9b6f4e2a1c8b3a5d7f9e2b4", "key_value_pairs": { "region": "us-east", "customer_type": "premium", "language": "en" }, "error": null }

Company Do Not Call List 3

The Company DNC (Do Not Call) list will allow blocking direct, manual, outbound calls as well as outbound and scheduled calls created by the Apps API depending on configuration.

Currently, the Company DNC endpoints allow users to:

  • add multiple phone numbers to the DNC list

  • remove phone numbers from the DNC list

  • check whether a phone number is in the DNC list



Query
KeyValueDescription
phone_number{{$randomPhoneNumber}}

Queue Status Endpoints 2

Queue Status Endpoint: Provides the status of a specific queue, allowing you to check the queue’s status before deflection.

Description

Returns comprehensive, real-time status for one or more leaf queues, including the callback time slots a virtual agent can offer for scheduling a callback.

Query parameters

  • menu_id[] (required) — 1–10 leaf menu IDs, e.g. menu_id[]=1&menu_id[]=2.
  • lang (required) — ISO 639-1 language code enabled for the company.
  • menu_type (required) — one of ivr_menu, mobile_menu, web_menu.
  • callback_period_hours (optional, integer 1–24) — length of the future window for which callback slots are returned.
  • callback_start_from (optional, ISO 8601) — start of the callback search window; must be in the future.

Response

Each queue object includes callback_periods[] and a scheduling_config object.

  • callback_periods[]: date (yyyyMMdd), start_time / end_time (HH:mm, queue timezone), scheduled_calls (booked count), max_slots, and available_slots (max_slots - scheduled_calls, floored at 0). When capacity is unlimited, callback_periods is [] and max_slots / available_slots are null.
  • scheduling_config: scheduled_callback_enabled, availability_interval (minutes; null = unlimited), availability_days, capacity_type (calculated | static | unlimited), calculated_capacity_percentage, enforce_minimum_wait_time_ewt, minimum_wait_time_minutes.

Errors: 400 invalid/missing params; 404 menu not found / not a leaf.

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Query
KeyValueDescription
lang{{lang}}

(ISO 639-1 string, required) The language code for the queue, e.g., en, es.

menu_id[]{{menu_id}}

(string, required) A single Queue ID or an array of multiple Queue IDs.

menu_type{{menu_type}}

(string, required) One of ivr_menu, mobile_menu, web_menu.

callback_period_hours

(integer, optional, 1–24) Total future window length in hours for which to return callback-slot periods.

callback_start_from

(ISO 8601 datetime string in queue/company timezone, optional) Start of the callback-slot search window. If omitted, defaults to “now” (server time converted to queue/company timezone). Must not be in the past.


Description

Fetches availability information for a specific queue.

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Query
KeyValueDescription
menu_id{{menu_id}}

(integer, required) The ID of the menu to fetch availability for.

lang{{lang}}

(string, required) The language code (e.g., ‘en’)

channel_type{{channel_type}}

(string, required) The channel type, either call or chat.


Contact Lists 6

The API user is able to:

  • manage Contact lists via API

    • create a Custom Contact List

    • edit a Custom Contact List

    • delete a Custom Contact List

  • manage custom and global Contact List entries

    • add entries

    • edit entries

    • delete entries

Queue destinations

A contact list entry can route to a queue. Set type to queue and send the queue settings in the nested queue_destination_attributes object.

FieldTypeNotes
menu_idintegerRequired when first creating the queue destination. The queue this contact routes to. Must be a queue in your tenant.
langstringRequired when first creating the queue destination. Language code, for example en. Must be a language the target queue is configured for.
greeting_messagestringText greeting played before the queue is joined. Up to 450 characters. Must not contain control characters or markup.
use_voice_filebooleanDefaults to false. When true, an audio greeting must already be stored or be uploaded in the same request.
voice_filefileAudio greeting, mp3 or wav, up to 15 MB. Can only be sent with multipart/form-data.
remove_voice_filebooleanSend true to delete the stored audio greeting.
bypass_queue_permissionsbooleanDefaults to false. Lets agents transfer to this queue even when they do not hold the usual permission for it.

When creating or updating, type accepts sip_uri, phone_number, and queue. Agent contacts are managed by UJET and are not supported on this endpoint; existing ones are returned with type: agent.

Uploading an audio greeting

Send the request as multipart/form-data and bracket the nested keys, for example queue_destination_attributes[menu_id] and queue_destination_attributes[voice_file]. application/json stays valid for every request that does not carry a file.

Queue fields on the response

Queue contacts are returned with menu_id, lang, greeting_message, use_voice_file, voice_file_url, and bypass_queue_permissions.

Those six keys are absent from the response for every other contact type — they are not returned as null, so test for the key rather than for a null value. The older type-specific fields (sip_uri, phone_number, extension_number, extension_digits_length, user_id) behave the other way round: they are always present and carry null when they do not apply. use_refer is always present and defaults to false; sip_params is always present and is an object, with every option off when no SIP parameters were configured.

Treat a missing key and a null value as the same thing (“not set”).

Validation errors

A queue contact that fails validation is rejected with 400, for example: type: queue without queue_destination_attributes; queue_destination_attributes on a contact whose type is not queue; a duplicate queue contact (same name, queue and language already in the list); an unknown menu_id; a lang the queue is not configured for; a greeting_message over 450 characters; or a voice_file that is not mp3/wav or is over 15 MB.

When queue destinations are not enabled

If queue destinations are not enabled for your tenant, creating or updating a contact with type: queue (or with queue_destination_attributes) is rejected with 422:

{
    "errors": [
        {
            "reason": "feature_disabled",
            "message": "Queue contacts are not enabled for this tenant."
        }
    ]
}

Updating a contact that already is a queue contact is rejected the same way. Deleting one is always allowed. Match on reason; the message wording can change.


URL Variables
KeyValueDescription
idinteger

The ID of updating contact list


URL Variables
KeyValueDescription
idinteger

The ID of deleting contact list


URL Variables
KeyValueDescription
contact_list_idinteger

The ID of selected contact list

Body
{ "name": "string", "type": "string", "phone_number": "string", "sip_uri": "string", "sip_params": { "data_parameters_enabled": "boolean", "map_all_sip_headers": "boolean", "data_parameters": [ { "type": "string", "field": "string", "value": "string", "source": "string", "source_field": "string" } ], "data_records": { "in_metadata": "boolean", "in_crm_record": "boolean" } }, "use_refer": "boolean", "contact_list_id": "string", "queue_destination_attributes": { "menu_id": "integer", "lang": "string", "greeting_message": "string", "use_voice_file": "boolean", "bypass_queue_permissions": "boolean" } }

URL Variables
KeyValueDescription
contact_list_idinteger

The ID of contact list

idinteger

The ID of updating contact record

Body
{ "id": "integer", "name": "string", "type": "string", "phone_number": "string", "sip_uri": "string", "sip_params": { "data_parameters_enabled": "boolean", "map_all_sip_headers": "boolean", "data_parameters": [ { "field": "string", "type": "string", "value": "string", "source": "string", "source_field": "string", "required": "boolean" } ], "data_records": { "in_metadata": "boolean", "in_crm_record": "boolean" } }, "use_refer": "boolean", "queue_destination_attributes": { "menu_id": "integer", "lang": "string", "greeting_message": "string", "use_voice_file": "boolean", "remove_voice_file": "boolean", "bypass_queue_permissions": "boolean" } }

URL Variables
KeyValueDescription
contact_list_idinteger

The ID of contact list

idinteger

The ID of deleting contact record


Queue Operation Statuses 1

Query
KeyValueDescription
menu_idInterger

(Required) The ID of the menu to fetch availability for

langstring

(Required) The language code (e.g., “en”)

channel_typestring

(Required) The channel type, either call or chat


Users 1

Users Endpoints provide a means to get user objects. Each user object represents a single user inside of our platform. Please review the model below to see which fields may be considered PII.

Default page size is 100 if no page parameters are sent.

{
      "id": 1,
      "email": "string", //This may be considered PII
      "first_name": "string", //This may be considered PII
      "last_name": "string", //This may be considered PII
      "agent_number": "string",
      "location": "string",
      "max_chat_limit": 5,
      "max_chat_limit_enabled": false,
      "unrestricted_international_calling": true,
      "deactivated_at": "2018-05-30T20:46:31.333Z",
      "ucaas_user_name": "string",
      "ucaas_sip_uri": "string",
      "external_user": false,
      "phone_numbers": ["string"],
      "extension_numbers": [
          0
      ],
      "teams": [
          {
              "name": "string"
          }
      ],
      "roles": [
          {
              "name": "string"
          }
      ]
  }

Response CodeMeaning
200The API request has been successful
400Invalid page size request - check to ensure the max page size is a valid integer less than 1000
400Cannot paginate filtered results - ensure that you are not using a filter and pagination parameters
400Only one filter should be configured at a time
400Ensure you are not filtering more than 1000 values at a time
Description

ParameterRequiredData TypeDefinitionPostman Variable
pageFALSEStringPairs with per to note what page of records. For instance if per is made to be 200 and page is 2, the response would contain record 201-400, as page 1 would contain 1-200.{{page}}
perFALSEStringPairs with page to note how many records would be included in a page of records. For instance if per is made to be 200 and page is 2, the response would contain record 201-400, as page 1 would contain 1-200.{{per}}
id[]FALSEArray[String]Array[Strings]. Id of records to search and return{{id[]}}
agent_number[]FALSEArray[String]Agent numbers as assigned by the admin at the time of creating an agent{{agent_number[]}}
status_id[]FALSEArray[String]Filters by agent status{{status_id[]}}
online[]FALSEBooleanFilter by if agents are online or not{{online[]}}
wrap_up[]FALSEBooleanFilter by if agents are in wrap up status{{wrap_up[]}}
location[]FALSEArray[String]Filters by agent location{{location[]}}
last_login_time[from]FALSETime in UTCcreates a lower bound of the last login time field. All records returned will be after the inputted value.{{last_login_time[from]}}
last_login_time[to]FALSETime in UTCcreates a upper bound of the last login time field. All records returned will be before the inputted value.{{last_login_time[to]}}
status_updated_at[from]FALSETime in UTCcreates a lower bound of the status updated at field. All records returned will be after the inputted value.{{status_updated_at[from]}}
status_updated_at[to]FALSETime in UTCcreates a upper bound of the status updated at field. All records returned will be before the inputted value.{{status_updated_at[to]}}



Calls 11

Description

Send a custom data in a call.

Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
id

(Required)

Body
// Use unsecured parameter { "signed": false, "data": { // Start customer_flag fields "reserved_verified_customer": { "label": "LABEL 1", "value": true }, "reserved_bad_actor": { "label": "LABEL 2", "value": false }, "reserved_repeat_customer": { "label": "LABEL 3", "value": true }, // End customer_flag fields "field1": { "label": "LABEL 4", "value": "dummy1" }, "field2": { "label": "LABEL 5", "value": "dummy2" } } } // Use secured parameter // { // "signed": true, // "signed_data": "eyJhbGciOiJIUzI1NiJ9.eyJjdXN0b21fZGF0YSI6eyJyZXNlcnZlZF92ZXJpZmllZF9jdXN0b21lciI6eyJ2YWx1ZSI6ZmFsc2V9LCJyZXNlcnZlZF9iYWRfYWN0b3IiOnsidmFsdWUiOnRydWV9LCJyZXNlcnZlZF9yZXBlYXRfY3VzdG9tZXIiOnsidmFsdWUiOmZhbHNlfSwiZmllbGQxIjp7InZhbHVlIjoiZHVtbXkxMTEifSwiZmllbGQyIjp7InZhbHVlIjoiZHVtbXkyMjIifX0sImV4cCI6MTcyOTY4MzU5MywiaWF0IjoxNzI5Njc5OTkzfQ.BMskgKTM3DbgrMLWjI46ZJ1K73H25JRd16SgHK0A1Ts" // } // ======================= How to create <signed_data> ======================= // payload = { // "custom_data": { // // Start customer_flag fields // "reserved_verified_customer": { // "label": "LABEL 1", // "value": true // }, // "reserved_bad_actor": { // "label": "LABEL 2", // "value": false // }, // "reserved_repeat_customer": { // "label": "LABEL 3", // "value": true // }, // // End customer_flag fields // "field1": { // "label": "LABEL 4", // "value": "dummy1" // }, // "field2": { // "label": "LABEL 5", // "value": "dummy2" // } // }, // "exp": 1734567890, // expiration timestamp // "iat": 1734560000 // issue timestamp // } // signed_data = JWT.encode(payload, 'Company secret', 'HS256') // ======================= End how to create <signed_data> =======================

Description

Get Call List.

Introduced in version 3.39.


Description

Get a Call

Introduced in version 3.39.

URL Variables
KeyValueDescription
call_idinteger

call_id to search


Description

Cancel a Scheduled Call

Introduced in version 3.39.

URL Variables
KeyValueDescription
call_idinteger

call_id to cancel

Body
{ "user_type": "string" }

Description

Cancel Multi Scheduled Call

Introduced in version 3.39.

Body
{ "call_ids": "array integer", "user_type": "string" }

Description

Update an existing scheduled callback. Allows modifying the scheduled time, end user number, recording permission, and other IVR-specific parameters. Requires the Scheduled Callback API to be enabled for your account.

ani (optional, E.164) is only validated and stored when phone-number retention is enabled for your account; otherwise it is ignored. The reschedule endpoint does not re-run the minimum-wait, hours-of-operation, or capacity checks that apply on create.

URL Variables
KeyValueDescription
call_id8788

Scheduled call ID to update

Body
{ "end_user_number": "+14155551234", "ani": "+14155559999", "scheduled_at": "2000-04-10T01:09:47.186Z", "ticket_id": "string", "lang": "en", "recording_permission": "recording_permission_denied", "first_name": "string", "last_name": "string", "user_authenticated": "N", "callback_reason": "string", "accepted_sms_notification": "N", "custom_parameters": { "key_0": "string", "key_1": "string" } }

Description

Retrieve details of an existing scheduled callback by ID. Requires the Scheduled Callback API to be enabled for your account.

URL Variables
KeyValueDescription
call_id8788

Scheduled call ID


Description

List scheduled callbacks with optional filters. Requires the Scheduled Callback API to be enabled for your account.

Query
KeyValueDescription
end_user_numberstring

End user phone number to filter scheduled calls

call_id8788

Filter by parent call ID

id8788

Filter by call ID

scheduled_from1977-03-22T23:59:59.670Z

Filter scheduled calls from this time (ISO8601 timestamp, inclusive)

scheduled_to1977-03-22T23:59:59.670Z

Filter scheduled calls up to this time (ISO8601 timestamp, inclusive). Time window between scheduled_from and scheduled_to must be at least 1 minute and at most 24 hours.

menu_id8788

Filter by menu ID

langstring

Filter by language code (e.g., en, es, fr)

ticket_idstring

Filter by ticket ID

page8788

Page number for pagination (default: 1)

per_page8788

Number of results per page (default: 100)

statusfailed

Filter by callback status. Values: scheduled, completed, attempted (callback has remaining retries), failed (system attempted maximum number of retries), cancelled


Description

Get a Job state of Cancel Multi Scheduled Call

Introduced in version 3.39.

URL Variables
KeyValueDescription
job_idinteger

job_id to search


Description

Get Call Status in Queue

Retrieves the real-time status of a specific call in a queue, including its position and estimated wait time.

Introduced in version 3.42.

fielddescription
position_in_queueThe current position of the call in the queue. The call at the front of the queue has a value of 1 (1-based).
ewtThe estimated wait time in seconds until the call is expected to be picked up from its current queue.
wait_duration_in_queueThe total time in seconds the call has been waiting in the queue since it was added.


Headers
KeyValueDescription
Content-Typeapplication/json
URL Variables
KeyValueDescription
call_id

The ID of the call used to get its current state in the queue.


Description

Get Call Status in Queue

Retrieves the real-time status of a specific call in a queue, including its position and estimated wait time.

Introduced in version 3.42.

fielddescription
position_in_queueThe current position of the call in the queue. The call at the front of the queue has a value of 1 (1-based).
ewtThe estimated wait time in seconds until the call is expected to be picked up from its current queue.
wait_duration_in_queueThe total time in seconds the call has been waiting in the queue since it was added.


Headers
KeyValueDescription
Content-Typeapplication/json
Query
KeyValueDescription
call_id:id

Emergency Shutdown 1

Description

Enable or disable emergency shutdown on one or more queues. This API allows external systems to remotely control queue availability during emergency situations.

ParameterRequiredData TypeDefinition
menu_idTRUEArrayArray of Queue IDs to update
languageTRUEStringISO 639-1 language code (e.g., “en”, “es”)
emergency_shutdown.enabledTRUEBooleanEnable (true) or disable (false) emergency shutdown
emergency_shutdown.message.typeFALSEStringMessage type: “tts” (text-to-speech) or “audio” (audio URL)
emergency_shutdown.message.contentFALSEStringTTS text or audio file URL. Required if message.type is provided
emergency_shutdown.in_progress_callsFALSEStringHow to handle in-progress calls: “allow_finish”, “end_and_redirect_to_after_hours”, “end_and_redirect_to_overcapacity”
emergency_shutdown.queued_callsFALSEStringHow to handle queued calls: “disconnect”, “redirect_to_after_hours”, “redirect_to_overcapacity”

Notes: - If no message is provided when enabling, the global default emergency shutdown message will be used. - The in_progress_calls and queued_calls parameters are optional; if not provided, global settings are inherited. - The API requires the Emergency Shutdown feature to be enabled and Remote Shutdown API access to be enabled for the company.

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "menu_id": [123, 456], "language": "en", "emergency_shutdown": { "enabled": true, "message": { "type": "tts", "content": "We are currently experiencing an emergency. Please call back later." }, "in_progress_calls": "allow_finish", "queued_calls": "disconnect" } }

Disposition Endpoints 4

Description

Returns the full forest of all active root-level disposition lists for the tenant and their descendants. Callers can identify roots by parent_path == "/" (or level == 1); root_list is null because no single list is selected.

Feature flag: Gated behind update-previous-acw. Returns 404 when the flag is off.

ParameterRequiredData TypeDefinition
channelFALSEString“voice_call” or “chat”. Default: “voice_call”
call_directionFALSEString“inbound” or “outbound”. Default: “inbound”. Ignored for chat
langFALSEStringISO 639-1 language code. Default: “en”
pageFALSEIntegerPagination page (default 1)
per_pageFALSEIntegerItems per page (default 100, max 100)

Notes: - The name field returned per code/list is the stored admin-authored string. lang selects the per-language assignment but does NOT translate names. - Pagination is exposed via standard headers (Total, Per-Page, Link).

Headers
KeyValueDescription
Acceptapplication/json
Query
KeyValueDescription
channelvoice_call

Channel for the tree. One of “voice_call” or “chat”. Defaults to “voice_call”.

call_directioninbound

Call direction for voice_call. One of “inbound” or “outbound”. Defaults to “inbound”. Ignored when channel is “chat” but must still be a valid value if provided.

langen

Language code used to select the language-specific queue assignment. Defaults to “en”. Does NOT translate the returned code or list names — values are the admin-authored strings regardless of lang.

page1

Page number for the disposition_codes array (default 1).

per_page100

Items per page (default 100, max 100). Pagination metadata is returned via RFC-5988 response headers (Total, Per-Page, Link).


Description

Returns the disposition tree for a specific queue (menu). Resolves the most-specific enabled Menu::CodeMenuAssignment up the menu hierarchy and falls back to the tenant’s channel-scoped global list (voice-inbound / voice-outbound / chat) when no assignment is found.

Feature flag: Gated behind update-previous-acw. Returns 404 when the flag is off OR when the menu doesn’t exist.

ParameterInRequiredData TypeDefinition
menu_idpathTRUEIntegerQueue (menu) ID
channelqueryFALSEString“voice_call” or “chat”. Default “voice_call”
call_directionqueryFALSEString“inbound” or “outbound”. Default “inbound”. Ignored for chat
langqueryFALSEStringISO 639-1. Default “en”
pagequeryFALSEIntegerPagination page (default 1)
per_pagequeryFALSEIntegerItems per page (default 100, max 100)


Headers
KeyValueDescription
Acceptapplication/json
Query
KeyValueDescription
channelvoice_call

“voice_call” or “chat”. Default: “voice_call”.

call_directioninbound

“inbound” or “outbound”. Default: “inbound”. Ignored for chat.

langen

ISO 639-1. Default: “en”. Selects the per-language queue assignment; does NOT translate names.

page1
per_page100
URL Variables
KeyValueDescription
menu_id123

Queue (menu) ID


Description

Returns the disposition tree that applies to a specific session, resolved from the session’s comm via the same logic the agent UI uses. The response channel, call_direction, and lang are derived from the resolved comm; query-param overrides for those fields are NOT honored on this endpoint.

Feature flag: Gated behind update-previous-acw. Returns 404 when the flag is off, when the session doesn’t exist, or when the session has no resolvable comm.

ParameterInRequiredData TypeDefinition
session_idpathTRUEIntegerSession ID
comm_typequeryFALSE*String“call” or “chat”. *Required when the session has both a call and a chat.
pagequeryFALSEIntegerPagination page (default 1)
per_pagequeryFALSEIntegerItems per page (default 100, max 100)


Headers
KeyValueDescription
Acceptapplication/json
Query
KeyValueDescription
comm_typecall

“call” or “chat”. Required when the session is omnichannel (has both a call and a chat); otherwise auto-resolves.

page1
per_page100
URL Variables
KeyValueDescription
session_id9876

Session ID


Description

Updates the disposition code and/or notes of a previously completed session. At least one of disposition_code or notes must be present in the request body.

Writes: - CRM: a new note record is attached on every call (additive, never an overwrite of prior notes). - External Storage: the existing session-metadata file is overwritten with the latest disposition state.

Feature flag: Gated behind update-previous-acw. Returns 404 when the flag is off.

FieldInRequiredData TypeDefinition
session_idpathTRUEIntegerSession ID
comm_typequeryFALSE*String“call” or “chat”. *Required when the session is omnichannel.
disposition_code.idbodyconditionalIntegerDisposition code id from the read API. Use -1 for the synthetic Do-Not-Call sentinel (only valid when the tenant has DNC + DNC-disposition enabled).
disposition_code.full_pathbodyconditionalStringparent_path of the membership (e.g. “/100/200”). Required when disposition_code is provided.
notesbodyconditionalStringNote text. Empty string is treated as an explicit clear; an omitted field leaves the prior note unchanged.

Notes: - Either disposition_code or notes must be present (or both). - The resolved code’s canonical name is returned in the response; callers do NOT need to send a name field. - The id == -1 sentinel triggers DNC list processing in addition to persisting the disposition row. - Returns 422 if the resolved comm is still active (the CRM/storage writes only run after the comm has ended).

Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Query
KeyValueDescription
comm_typecall

“call” or “chat”. Required when the session is omnichannel (has both a call and a chat); otherwise auto-resolves.

URL Variables
KeyValueDescription
session_id9876

Session ID

Body
{ "disposition_code": { "id": 12345, "full_path": "/100" }, "notes": "Customer agreed to upgrade plan." }

Email Parsed Data 2

Read-only Apps API for retrieving parsed email data. Two endpoints:

  1. GET /apps/api/v1/email/sessions/:email_support_id — session metadata + its email_threads list.
  2. GET /apps/api/v1/email/messages/:email_thread_id — a single parsed message + email_attachments metadata.

HTTP Basic auth.

Description

Returns metadata for a single email support session plus its (non-draft) threads, ordered by received_at ascending.

Authentication: HTTP Basic — username = Apps API user name, password = API token.

Path parameters

NameTypeRequiredDescription
email_support_idintegerYesNumeric email session id.

Hiding

hidden and hidden_at are always present. A visible session renders hidden: false, hidden_at: null, so a consumer never has to branch on absence. hidden_at is one field over two internal mechanisms (an API hide and an orchestration delete); which one hid the row is not part of this contract.

Orchestration

The session’s orchestration run: your external workflow was asked what to do with the email — reply, close, delete, or move it to another queue — and UJET carried out the answer or fell back to regular routing.

The key is absent — not null — when the session has no orchestration run, or when orchestration reporting is not enabled for your tenant; read it with a presence check rather than a null check. Only runs made while reporting is enabled are reported, and turning reporting off hides runs already reported, so an absent key does not by itself mean that your workflow did not handle the email. When it is present, every field below is present, and a field with no value is null. A field the table does not describe as always having a value can be null.

  • The latest run. A later run of the same session can replace the one reported here.
  • A read at a moment. status, exit_at and duration_ms are null until UJET records the run’s end, which may never happen. A run that ended completed and whose move to another queue is then refused or fails renders as status: failed, with fallback.applied: true and fallback.reason: delivery_failed — so a run’s status can differ on a later read.
  • On the destination of a move the workflow made, the object describes the source session’s run until the destination session has a run of its own: routing.forwarded_from_email_support_id names the source session, and the routing.original_* fields are the source session’s.
  • Values your workflow supplied expire. custom_params, routing.match_params and flow_id become null 7 days after they were recorded — a fixed period, not your email storage period — and also after the end user’s data has been removed.
FieldTypeNotes
statusstringOne of completed, timed_out, failed, invalid_response, fallback_default. How the run ended; null until UJET records the run’s end, which may never happen. completed — UJET carried out the run, though a step can settle without effect; see outcome.applied_types. Every other value means regular routing took over: timed_out — the workflow did not answer in time; invalid_response — its answer could not be used; failed — calling the workflow, processing its answer or carrying it out failed, which can include a move to another queue that was refused or failed; fallback_default — UJET applied regular routing by default, for example because the answer planned nothing. fallback.reason says why. A run that moves the session to another queue can report a different status on a later read.
entry_atstring (date-time)When the run started (UTC).
response_received_atstring (date-time)When UJET received the workflow’s answer (UTC) — its API response, or its callback in webhook_response mode; null when UJET has recorded no answer — for example while it is still waiting for one, or after an HTTP error or a timeout.
exit_atstring (date-time)When the run ended (UTC); null until UJET records the run’s end, which may never happen.
duration_msintegerMilliseconds from entry_at to exit_at; null until UJET records the run’s end, which may never happen. In webhook_response mode it includes the wait for your callback.
providerstringThe kind of workflow integration. Currently always google_workflows; it does not identify the endpoint that answered.
flow_idstringThe execution_id your workflow returned at the root of its answer, kept only when it is an identifier: 1 to 1,024 characters, each an ASCII letter, a digit or one of ., _, :, /, -. null when the answer carried none or one of any other shape, or UJET could not use or process the answer, and 7 days after it was recorded or after the end user’s data has been removed.
modestringHow your workflow is configured to answer: api_response — in its API response; webhook_response — later, through the Email DAP Webhook Callback.
outcome.typesarray of stringEach one of send_email_response, end_email, transfer_to_queue, delete_email, no_action. The steps UJET planned from the workflow’s answer, in execution order — replies first. Events in your answer map to steps as follows: send_response → send_email_response; end_email → end_email, plus delete_email when it carries delete: true; assign_to_queue → transfer_to_queue, which a move made by top-level key-value routing also plans. This can differ from what the answer asked for: for example, a close supersedes a move to another queue. ["no_action"] when nothing was planned, including when the answer could not be used (status: invalid_response). null when UJET has recorded no plan — for example before the workflow answers, or when the run ended before an answer could be read, such as after an HTTP error, a timeout or refused authentication.
outcome.applied_typesarray of stringThe planned steps that took effect, in the same order and vocabulary: ["no_action"] when nothing was planned (including when the answer could not be used), [] when none took effect, null when UJET has recorded no plan. transfer_to_queue means the move to the destination queue was handed off, not that it arrived, and may be removed later, for example when that move failed or went to another queue.
outcome.destination_queue_idintegerThe queue the workflow’s answer routed the session to; null when it routed to none. Kept when the move later failed.
outcome.destination_queue_langstringThe language of that queue.
outcome.destination_queue_namestringThe name of that queue in that language, as it is when you read it; null when there is no destination queue or it no longer exists.
routing.original_email_account_idintegerThe inbound email account the run’s session arrived on (the source session’s, on a move’s destination).
routing.original_queue_idintegerThe queue the run’s session was in when the run started (the source session’s, on a move’s destination).
routing.match_resultstringOne of matched, no_match, not_applicable. Whether the workflow’s answer matched a configured queue routing rule: matched when it did; no_match when an assign_to_queue event matched no rule; not_applicable otherwise, for example when the answer’s top-level key-value pairs matched no rule or the answer closed the case. Can be null when UJET did not evaluate an answer.
routing.match_paramsobjectThe key-value pairs that matched a routing rule: each path of the rule, with the value your answer held there as text (object and array values are left out). Empty or null when there are none to show, and 7 days after it was recorded or after the end user’s data has been removed.
routing.forwarded_from_email_support_idintegerOn the destination session of a move the workflow made, the source session’s email_support_id; null otherwise.
custom_paramsobjectThe custom_params object your workflow returned at the root of its answer, within its bounds (see Email DAP Webhook Callback): string, number, boolean or null values. null when the answer carried none, or UJET could not use or process the answer, and 7 days after it was recorded or after the end user’s data has been removed.
fallback.appliedbooleanTrue when regular routing took over, which can include a move to another queue that was refused or failed; false while the run is in progress and when status is completed.
fallback.reasonstringOne of callback_timeout, timeout, http_4xx, http_5xx, network_error, configuration_error, malformed_response, no_matching_queue, no_action, auth_error, system_error, delivery_failed. Why regular routing took over: always set when applied is true, and null when it is false. callback_timeout and timeout — the workflow did not answer in time; http_4xx, http_5xx, network_error — the request to the workflow failed; auth_error — authentication with the workflow failed (no token could be obtained, or the token was rejected); configuration_error — the tenant’s workflow settings need attention; malformed_response — the answer could not be used; no_matching_queue — the answer asked for a queue that matched none; no_action — the answer asked for nothing UJET acts on; delivery_failed — a planned step could not be carried out; system_error — a failure or decision on UJET’s side.

Fan-out

Call this, then for each email_threads[].email_thread_id call GET /apps/api/v1/email/messages/:email_thread_id.

Errors

StatusBodyWhen
400{ "error": "invalid_email_support_id" }email_support_id ≤ 0
401—Missing/invalid credentials
404{ "error": "not_found" }Not found in tenant


Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
email_support_id12345

(Required) Numeric email session id.


Description

Returns a single parsed email message — headers, body, and attachment metadata.

Authentication: HTTP Basic — username = Apps API user name, password = API token.

Path parameters

NameTypeRequiredDescription
email_thread_idintegerYesNumeric email message id (the email_thread_id from the sessions endpoint’s email_threads[]). The RFC 5322 Message-ID is returned separately as message_id.

Notes

  • email_attachments[].url is null until the attachment-URL prerequisite ships.
  • No email_attachments[].data (base64) or body_formatted field.
  • to/cc/bcc are always arrays.

Errors

StatusBodyWhen
400{ "error": "invalid_email_thread_id" }email_thread_id ≤ 0
401—Missing/invalid credentials
404{ "error": "not_found" }Not found in tenant, a draft, or its content could not be retrieved


Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
email_thread_id9001

(Required) Numeric email message id (from sessions’ email_threads[].email_thread_id). Not the RFC 5322 Message-ID — that is message_id.


Email DAP 1

Description

Customer-side ingress for Email DAP (Direct Access Point) Webhook Response routing mode — the email twin of Chat DAP Webhook Callback.

Scope. This callback serves inbound email sessions invoked asynchronously. Tenants on API Response mode answer the outbound request directly and never involve this endpoint.

Flow 1. An inbound email arrives and is held in the workflow window (status In Analysis); the agent adapter shows it read-only. 2. The platform POSTs the DAP request to your configured endpoint with callback_url — the absolute URL of this endpoint for your tenant, with the correlation id already in the path. Your endpoint must answer with a 2xx acknowledgment within the API Request Timeout. 3. Your system does its own lookup (CRM, segmentation, business rules) and POSTs the verdict to callback_url before the webhook deadline. 4. The platform records the verdict, acknowledges, and applies it off the request thread. Your POST never waits on mail delivery.

The correlation id in the path is minted by UJET and published only in callback_url. It is a lookup key, not a secret — the request is authenticated by Basic auth, exactly as every other Apps API call.

Available when Email DAP is enabled for your tenant — contact Support.

Authentication

HTTP Basic, same as the rest of Apps API. - Username / Password — the tenant’s Apps API credential. No per-call token is issued for this endpoint.

HeaderRequiredNotes
Authorization: Basic …yesApps API credential, as above.
Content-Type: application/jsonyesBody must be JSON.
Accept: application/jsonnoRecommended.
UJETSUBDOMAINnoTenant identifier. Normally inferred from the host; only needed when calling through a host that does not carry the tenant subdomain. Disabled by default.

Path parameters

ParameterTypeNotes
webhook_request_idstringThe correlation id UJET minted for this invocation. Already present in callback_url; do not construct it yourself. Max 255 chars, A-Z a-z 0-9 _ - only.

Request body

Any JSON object. The body is stored verbatim and interpreted after the acknowledgment, so this endpoint validates only what storage cannot survive: a body that is not a JSON object or is nested too deeply to be read, and a serialized size over 65,535 bytes.

FieldTypeRequiredNotes
eventsarraynoOrchestration actions — see Orchestration actions below.
errorstring | nullnoOptional customer-side error message recorded by UJET. Truncated at 1024 chars; non-string values are ignored.
custom_paramsobjectnoBusiness context to record with the run; returned as orchestration.custom_params by the Email Parsed Data API. Values must be strings, numbers, booleans or null: object and array values are dropped, as are keys longer than 100 characters, and at most 50 keys are kept; string values are cut to 1,000 characters; keys are dropped from the end until the object fits in 64 KB. Any value that is not an object is not recorded. Expires 7 days after it is recorded, or earlier when the end user’s data is removed.
execution_idstringnoAn identifier for your workflow’s execution; returned as orchestration.flow_id by the Email Parsed Data API. Recorded only when it is 1 to 1,024 characters, each an ASCII letter, a digit or one of ., _, :, /, - — a UUID, for example; any other value is not recorded. Expires 7 days after it is recorded, or earlier when the end user’s data is removed.

Neither custom_params nor execution_id is recorded from a verdict that fails validation (see Rules below) or that UJET could not process, or while orchestration reporting is not enabled for your tenant.

The body is read at its root, the same as an API Response mode response: put events, custom_params, execution_id and any routing keys at the top level, not inside a wrapper object.

Every top-level key is routing input. All of the body’s top-level keys — events, error, custom_params and execution_id included — form the plain key-value routing input matched against the queue Access Points of type API Response. Those four names are reserved: do not write a routing rule that targets any of them. A misspelled events therefore becomes a routing field rather than an error, and the verdict applies no actions — check the spelling before assuming the platform dropped your events.

Minimal example (routing only):

{
  "region": "us-east"
}

Orchestration actions (events)

events is an ordered array of actions, applied in the order given. The same array is accepted at the root of an API Response mode response.

{
  "events": [
    { "type": "send_response", "message": "Thanks for reaching out — a specialist will follow up shortly." },
    { "type": "assign_to_queue", "key_value_pairs": { "team": "billing" }, "skills": ["billing", "en"], "skills_operator": "AND" }
  ]
}
typeRequiredOptionalBehavior
assign_to_queuekey_value_pairs (object)skills (array of up to 100 strings), skills_operator (AND | OR)Forwards the email to the queue whose API Response Access Point matches key_value_pairs. In email a queue owns its own mailbox, so this is a queue-to-queue forward, not a relabel. skills narrow the agent choice inside the destination queue when the Access Point’s Prioritize skills if available is enabled. No agent-targeting flags: email has no virtual agent.
send_responsemessage (string, max 2000 chars)subject (string)Sends the message to the consumer as a reply on the thread. An empty message is honoured as “ran, sent nothing” and cancels every end_email in the verdict as well as any later send_response, so the email is handed to an agent instead of being resolved. Omit subject to keep the thread’s own.
end_email—delete (bool)Resolves the email before it is offered to any agent. Planned last, and it supersedes routing entirely: when end_email is present no queue is resolved at all, so a sibling assign_to_queue and any root key-value routing are silently not applied. Do not combine them expecting both.

Rules: - end_email in the array cancels routing before any match is attempted — neither the event nor the root key-value pairs route the email. - When the root key-value pairs match an Access Point, that routing wins and the assign_to_queue event is not used for the match. Key-value pairs that match nothing do not suppress events. - A verdict that fails validation (unknown type, missing key_value_pairs or message, oversized skills or message, non-array events) is discarded whole — including any plain key-value routing sent alongside it, so a malformed action can never misroute the email. The email is released to the inbox unchanged and is never left in a stuck state. This differs from Chat DAP, where a rejected events array still leaves the key-value routing in effect. - A body nested deeper than 32 levels cannot be used either: it is still acknowledged, and the run falls back to regular routing as for a verdict that fails validation. A body nested too deeply to be read at all is answered 400. - Validation runs after the acknowledgment, so it is not visible in the HTTP response. A verdict that fails validation is still answered 200 {"ack":"ok"} and consumed; only the 400 cases in the table below are reported to you. Resending a corrected verdict for the same correlation id is treated as a duplicate and ignored, so a validation failure cannot be repaired by retrying — check orchestration.status (invalid_response) on the session instead, when orchestration reporting is enabled for your tenant.

Response (200)

The success body is intentionally minimal — the webhook caller only needs an ACK:

{
  "ack": "ok"
}

What the verdict actually did is not returned. It is applied asynchronously; when orchestration reporting is enabled for your tenant, read the session’s orchestration object through the Email Parsed Data API to see how the run ended.

Errors

CodeWhenRetry?
400Body is not a JSON object, is nested too deeply to be read, or the serialized body is over 65,535 bytes.Not unchanged — fix the body first.
401Basic auth credentials missing or invalid.No.
404Unknown correlation id, or Email DAP is not enabled for this tenant. Also returned — not 400 — when the id is over 255 characters or outside the route charset, and when it belongs to an invocation whose outbound call never succeeded.No.
410The callback arrived after the webhook deadline. Expiry is checked before delivery state, so a duplicate sent after the deadline is answered 410 even when your first callback was accepted and applied — a 410 is not evidence that the verdict was lost. It also does not mean the email has been released yet; release is done afterwards by the deadline worker or the reaper.No.
500The verdict was not durably recorded, or was recorded but could not be handed to a worker.Yes — this is the one outcome you must retry.

Retries and idempotency

The webhook deadline is currently a fixed 10 minutes, measured from when the platform issues the outbound request. It is not tenant-configurable today — no setting is wired to it — so do not design a longer callback window.

A duplicate callback inside the window is accepted and ignored — it returns 200 {"ack":"ok"} like the first one, so an at-least-once caller is safe. A callback rejected with 400 leaves the pending hold untouched, so a corrected retry before the deadline is still accepted. After the deadline the answer is 410; see the note on that row for what it does and does not tell you.

Headers
KeyValueDescription
Content-Typeapplication/json

Required. Body must be JSON.

Acceptapplication/json

Recommended.

URL Variables
KeyValueDescription
webhook_request_idb7c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5

Correlation id UJET minted for this invocation, already present in callback_url.

Body
{ "events": [ { "type": "send_response", "message": "Thanks for reaching out — a specialist will follow up shortly." }, { "type": "assign_to_queue", "key_value_pairs": { "team": "billing" } } ], "custom_params": { "intent": "billing_question", "priority": "high" }, "execution_id": "7c1e4b2a-5d3f-4a8e-b9c6-1f2e3d4c5b6a", "error": null }

Skills 5

Agent Skills API — the tenant skills roster: create, list, update, and delete skills. Per-agent assignments are under User Skills; per-queue requirements are under Menu Skill Requirements.

Description

Returns the tenant skills roster with per-skill aggregates (agent count, average proficiency, in-queue usage).

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json

Description

Creates a skill in the tenant roster. Returns 409 when the skill name already exists.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
Content-Typeapplication/json
Body
{ "skill": { "name": "Billing" } }

Description

Updates an existing skill. Returns 404 when the skill does not exist.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
Content-Typeapplication/json
URL Variables
KeyValueDescription
id5

(Required) Skill ID

Body
{ "skill": { "name": "Billing (renamed)" } }

Description

Replaces an existing skill (PUT equivalent of the PATCH update).

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
Content-Typeapplication/json
URL Variables
KeyValueDescription
id5

(Required) Skill ID

Body
{ "skill": { "name": "Billing (renamed)" } }

Description

Deletes a skill from the tenant roster. Returns 409 when the skill is still used by a queue requirement.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
id5

(Required) Skill ID


User Skills 2

Agent Skills API — per-agent skill assignments: upsert (assign) or remove a skill for a user.

Description

Creates or updates one skill assignment for the agent. Returns 404 if the user or skill is not found, 422 if the level is out of range.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
Content-Typeapplication/json
URL Variables
KeyValueDescription
user_id42

(Required) Agent (user) ID

Body
{ "skill_id": 5, "level": 7, "is_learning": false }

Description

Removes a single skill assignment from the agent.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
user_id42

(Required) Agent (user) ID

skill_id5

(Required) Skill ID


Agent Skills API — per-queue skill requirements: upsert (set) or remove a skill requirement on a menu cascade queue group.

Description

Creates or updates a skill requirement term on a queue cascade group.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
Content-Typeapplication/json
URL Variables
KeyValueDescription
menu_id12

(Required) Menu (queue) ID

Body
{ "cascade_group_id": 101, "skill_id": 5, "operator": "equal_to", "level": 5, "logic_operator": "and" }

Description

Removes a skill requirement term from a queue cascade group.

Authentication: HTTP Basic — username = Apps API user key, password = Apps API token.

Headers
KeyValueDescription
Acceptapplication/json
URL Variables
KeyValueDescription
menu_id12

(Required) Menu (queue) ID

cascade_group_id101

(Required) Cascade group ID

skill_id5

(Required) Skill ID


Bulk Email Status 1

Bulk email status management Apps API. Transition one or more email sessions to a target status in a single call, with per-session results.

Description

Bulk-transition one or more email sessions to a single target status. Returns a per-session result array (one entry per input id, in request order). HTTP 200 is returned even when some items fail, so inspect each result.

Authentication: HTTP Basic — username = Apps API user name, password = API token.

Body parameters

NameTypeRequiredDescription
session_idsstring or string[]YesOne or more email session ids (numeric EmailSupport ids as strings, e.g. “12345”). Max 100 per request.
new_email_statusstringYesTarget status: active, paused, resolved, or closed.
existing_email_statusstringNoOptional expected current status. If it does not match the session’s actual status, that item is reported stale_state and left unchanged.

Allowed transitions

active → paused, resolved · paused → active, closed · resolved → closed · unopened → active · reopened → active. Any other pair is reported invalid_transition.

Per-session result

Each results[] entry has a result of:

  • success — transitioned (from_status, to_status).
  • noop — already at the target status (current_status).
  • failure — not applied, with reason: not_found, invalid_transition (current_status), stale_state (current_status), or hidden (current_status) — the session is hidden, so its status cannot change until it is un-hidden. A hidden session reports hidden rather than noop, invalid_transition or stale_state.

Errors

StatusBodyWhen
400{ "message": "..." }Missing/invalid session_ids, invalid new_email_status / existing_email_status, or more than 100 ids
401{ "message": "Not Authorized" }Missing/invalid credentials


Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "session_ids": ["12345", "12346"], "new_email_status": "paused", "existing_email_status": "active" }

Email Session Hiding 2

Email session hiding Apps API. Hide email sessions from every agent surface, and make them visible again, by email session id, with per-session results. Hiding never changes a session’s status. Hide and un-hide are available only through this API.

Description

Hide one or more email sessions. A hidden session leaves every agent surface (lists, counts, search and drafts), is no longer auto-assigned, auto-paused or auto-closed, and refuses agent actions. Its status does not change. Returns a per-session result array (one entry per input id, in request order). HTTP 200 is returned even when some items fail, so inspect each result.

Authentication: HTTP Basic — username = Apps API user name, password = API token. Company-key credentials are rejected.

Availability: until email session hiding is enabled for the tenant, this endpoint returns 404.

Body parameters

NameTypeRequiredDescription
session_idsstring or string[]YesOne or more email session ids: the numeric EmailSupport id as a string (e.g. “12345”), the same id GET /apps/api/v1/email/sessions/:email_support_id takes. A JSON number is rejected. Max 100 per request.

Per-session result

Each results[] entry has a result of:

  • success — hidden now (status, hidden_at).
  • noop — already hidden by an earlier call (status, hidden_at).
  • failure — not hidden, with reason:
    • not_found — no such session.
    • orchestration_in_progress (status) — an email workflow is still processing the session. Retry later.
    • forward_in_progress (status) — a transfer to another queue is still in flight. Retry later.
    • internal_error — retry.

A hidden session stays readable through GET /apps/api/v1/email/sessions/:email_support_id, which reports hidden: true. A customer reply to a hidden session un-hides it automatically.

Errors

StatusBodyWhen
400{ "message": "..." }Missing or empty session_ids, an id that is not a 1–64 character string (A–Z, a–z, 0–9, _, -), or more than 100 ids
401{ "message": "..." }Missing or invalid credentials, or company-key credentials
404{ "error": "not_found" }Email session hiding is not enabled for the tenant


Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "session_ids": ["12345", "12346"] }

Description

Make one or more hidden email sessions visible again, with the status they already have. Un-hide clears either kind of hide: one made through POST /apps/api/v1/email/hide, and one made by an email workflow’s end_email event with delete: true. Returns a per-session result array (one entry per input id, in request order). HTTP 200 is returned even when some items fail, so inspect each result.

Authentication: HTTP Basic — username = Apps API user name, password = API token. Company-key credentials are rejected.

Availability: until email session hiding is enabled for the tenant, this endpoint returns 404.

Body parameters

NameTypeRequiredDescription
session_idsstring or string[]YesOne or more email session ids: the numeric EmailSupport id as a string (e.g. “12345”), the same id GET /apps/api/v1/email/sessions/:email_support_id takes. A JSON number is rejected. Max 100 per request.

Per-session result

Each results[] entry has a result of:

  • success — visible now (status, hidden_at: null).
  • noop — was not hidden (status, hidden_at: null).
  • failure — with reason not_found (no such session) or internal_error (retry).

Errors

StatusBodyWhen
400{ "message": "..." }Missing or empty session_ids, an id that is not a 1–64 character string (A–Z, a–z, 0–9, _, -), or more than 100 ids
401{ "message": "..." }Missing or invalid credentials, or company-key credentials
404{ "error": "not_found" }Email session hiding is not enabled for the tenant


Headers
KeyValueDescription
Content-Typeapplication/json
Acceptapplication/json
Body
{ "session_ids": ["12345", "12346"] }

Available Variables 17

KeyValueType
subdomain
domainstring
username
password
call_type
agent_email
ticket_id
end_user_number
outbound_number
lang
menu_id
wait[from]
wait[to]
channel_type
menu_type
recording_permission
job_id