Salted CX sends conversation-related data with each request to give context to Your Logic for making decisions. In many cases this enables you to make.
Salted CX ensures that all requests related to the same conversation are sent sequentially and Salted CX waits for Your Logic response before sending another request related to the same conversation.
Request Headers
Each request has the following headers:
Header | Type | Description |
---|---|---|
Authorization | String | The token you can use to verify that this event was sent by Salted CX. This is a shared secret and you have to ensure you protect the token on your side so a bad actor cannot use it to pretend they are Salted CX.
Value is in format Bearer <shared secret> |
Request Structure
Requests have a common structure as described below.
Property | Type | Description |
---|---|---|
requestId | UUID | Unique identifier of this request. This identifier is important when responding back so Salted CX knows that the request is resolved. |
expires | Time | The time until which Your Logic has time to respond to this request. Salted CX may or may not provide additional grace period that you should not rely on and may change based on different conditions. |
trigger | Object | Describes the event that caused this request to be sent to Your Logic. You can filter by trigger type and other properties whether you want to process the request. |
account | UUID | Unique identifier of the account in Salted CX. (SHOULD NOT BE NECESSARY) |
domain | String | The domain of the customer within Salted CX. |
region | String | The region in which the account has all the data. |
customer | Object | Structured information about the customer including custom data. |
conversation | Object | Structured information about the conversation including custom data. |
engagements | Array | Engagements related to this conversation. |
turns | Array | Chronologically ordered turns. |
See example request JSON that you would receive.
{
"requestId": "3c99280a-9871-4656-a472-5da68d30c01f",
"accountId": "{{account_id}}",
"time": "2025-07-31T05:10:08.263515641Z",
"expires": "2025-07-31T05:10:28.263515641Z",
"trigger": {
"time": "2025-07-31T05:10:07Z",
"type": "MESSAGE",
"participantType": "CUSTOMER",
"content": "Order is still not delivered",
"contentCustomer": "Order is still not delivered",
"languageCustomer": "en",
"contentAgent": "Order is still not delivered",
"languageAgent": "en"
},
"domain": "demo-development",
"region": "eu",
"customer": {
"pid": "e00609f4-1fa5-44b1-ad43-84c59a3450ca",
"displayName": "Adam Novak",
"contacts": [
{
"contact": "+420123456789",
"type": "Phone"
}
]
},
"conversation": {
"pid": "005ea483-5151-479d-842e-f5ef0a1fa5cc",
"startConversationTime": "2025-07-31T05:09:24Z",
"needsHelp": false,
"status": "IN_PROGRESS",
"platform": "WHATSAPP",
"direction": "INBOUND",
"languageCustomer": "en"
},
"engagements": [
{
"pid": "615ea483-5151-479d-842e-f5ef0a1fa5cc",
"time": "2025-07-31T05:09:24Z",
"type": "QUEUE",
"status": "COMPLETED"
},
{
"pid": "a142fb87-c5b7-4e9f-b047-34ab7c480ae6",
"time": "2025-07-31T05:09:31.995513Z",
"agent": "732e8047-73ab-5ada-bd8e-b11b764f8b08",
"type": "AGENT",
"status": "IN_PROGRESS"
}
],
"turns": [
{
"time": "2025-07-31T05:09:24Z",
"engagementPid": "615ea483-5151-479d-842e-f5ef0a1fa5cc",
"type": "MESSAGE",
"participantType": "CUSTOMER",
"content": "Parcel is gone",
"contentCustomer": "Parcel is gone",
"languageCustomer": "en",
"contentAgent": "Parcel is gone",
"languageAgent": "en",
"status": "RECEIVED",
"id": "893da24c-32c9-4bcd-959a-bf58ef779619",
"pid": "a68d8992-1ad5-5c7d-97dc-95fe1344f6ce"
},
{
"time": "2025-07-31T05:09:32.042590Z",
"engagementPid": "a142fb87-c5b7-4e9f-b047-34ab7c480ae6",
"type": "MESSAGE",
"participantType": "BOT",
"content": "I'm not sure I understand. Can you rephrase or provide more details?",
"contentCustomer": "I'm not sure I understand. Can you rephrase or provide more details?",
"languageCustomer": "en",
"contentAgent": "I'm not sure I understand. Can you rephrase or provide more details?",
"languageAgent": "en",
"status": "VIEWED",
"id": "043b40d0-96a4-4e9d-8d70-f4cd8bcceec5",
"pid": "4688baf4-5c80-5b63-8d7f-c11c1fbe2d95"
},
{
"time": "2025-07-31T05:10:07Z",
"engagementPid": "a142fb87-c5b7-4e9f-b047-34ab7c480ae6",
"type": "MESSAGE",
"participantType": "CUSTOMER",
"content": "Order is still not delivered",
"contentCustomer": "Order is still not delivered",
"languageCustomer": "en",
"contentAgent": "Order is still not delivered",
"languageAgent": "en",
"status": "WAITING_FOR_ENRICHMENTS",
"id": "3c99280a-9871-4656-a472-5da68d30c01f",
"pid": "c2eb7856-7e9f-5d27-bac9-7b917604d69c"
}
]
}
Trigger
The trigger has a common properties.
Property | Type | Description |
---|---|---|
time | Time | The time when the event was received by Salted CX. |
type | String | |
participantType | String | The type of the participant to distinguish customer, agents, external agents, bots, etc. Values |
Depending on the type of the trigger there are additional properties covering specifics of the trigger.
Triggers List
Trigger | Description |
---|---|
Message | A participant sent a text message. |
File | A participant sent a media or a file. |
Message from Customer
This request is sent when a customer sends a message.
Property | Type | Description |
---|---|---|
content | String (Optional) | Content sent from the customer translated to the account content language. The content is not available in case translation is not enabled. Also if Salted CX is unable to translate the message in a short timeframe for any reason (for example translation service issues). |
language | String (Optional) | Account content language into which the message is translated. |
contentCustomer | String | The verbatim content the customer wrote in their language. |
languageCustomer | String | Detected language of the customer message. Remember that the detection is not 100% accurate and the accuracy depends on many factors including the length of the message. |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"time": "2025-04-11T10:57:42Z",
"expires": "2025-04-11T10:57:57Z",
"domain": "company",
"region": "eu",
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "Message",
"participantType": "Customer",
"content": "Hello, how are you?",
"language": "en",
"contentCustomer": "Hola, qué tal?",
"languageCustomer": "es"
}
/* rest of the event */
}
Message from Agent
You can use your logic to intercept messages from agents.
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"time": "2025-04-11T10:57:42Z",
"expires": "2025-04-11T10:57:57Z",
"domain": "company",
"region": "eu",
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "Message",
"participantType": "Agent",
"agent": "a7ac10b-58cc-4372-a567-0e02b2c3d472",
"content": "How can I help you?",
"language": "en"
}
/* rest of the event */
}
Send Files and Media
This request informs about media exchange. Salted CX also sends you a link to the file you can use to access the file data. The link to the media is valid for 24 hours.
Property | Type | Description |
---|---|---|
time | Time | When the turn was received or sent. |
type | File | Constant File for this requests. |
participantType | String — Agent, Bot, Customer, External Agent | Who sent the file. |
mediaName | String | The name of the file. |
mimeType | String | MIME type of the file. |
mediaLink | String | The full path to the file that can be used to download it. The link is valid for a time restricted time period 2č hours. |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"time": "2025-04-11T10:57:42Z",
"expires": "2025-04-11T10:57:57Z",
"domain": "company",
"region": "eu",
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "File",
"participantType": "Customer",
"mediaName": "theLastNameOfThe.pdf",
"mimeType": "application/pdf"
"mediaLink": "https://storage.aws.com/theLastNameOfThe.pdf"
}
/* rest of the event */
}
(Idea)
Menu StepSalted CX sends menu step whenever a customer reaches an article that has set the Technical ID property to any value. You can watch for these requests to trigger actions.
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"time": "2025-04-11T10:57:42Z",
"expires": "2025-04-11T10:57:57Z",
"domain": "company",
"region": "eu",
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "Menu Step",
"participantType": "Customer",
"technicalID": "refund-credits"
}
/* rest of the event */
}
Answer
When a customer or an agent replies to a question.
{
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "Answer",
"participantType": "Customer",
"externalID": "refund-credits"
}
/* rest of the event */
}
Review
When there is a review created by a participant Your Logic lets you know about it. This enables you to respond to customer or agent feedback. For example if the customer is unhappy with the response from a bot you ask agents for help.
{
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "REVIEW",
"reviewType": "Customer",
"questionPid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"questionName": "Thumbs Down",
"answerPid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"answerName": "Thumbs Down",
"reviewReason": "Confusing",
"turn": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
}
(Upcoming)
Conversation StateTriggered by changes in the conversation attributes.
{
"trigger": {
"time": "2025-04-11T10:57:42Z",
"type": "Conversation Update",
"conversation": {
"state": "Customer Resolved"
}
}
/* rest of the event */
}
Completed Engagement
This request is sent when an engagement gets completed. Using this event you can detect that an agent considers their engagement done and Your Logic can take over control of the conversation. This is useful for example for closing the conversation — asking the customer whether their issue is resolved, how they are satisfied, etc.
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"trigger": {
"type": "ENGAGEMENT_COMPLETE",
"engagement": {
"pid": "61ab68f3-9e07-4d65-9bee-5bddfcb2d75a",
"time": "2025-06-23T16:42:24.405361Z",
"agent": "4644535e-5d63-4dd8-8018-528bf55fcbac",
"type": "AGENT",
"status": "IN_PROGRESS",
"name": "",
"reasonCategory": "Reason Category 1",
"reason": "Reason 1",
"outcomeType": "ACCEPTED",
"outcomeCategory": "Outcome Category 1",
"outcome": "Outcome 1",
"cost": 3.9
}
}
}
Custom Data
Customer and conversation object have a JSON object custom
. This object can hold any data that you need to handle the conversation. Unlike the rest of the JSON the structure of this object is not restricted and may contain any keys and values of any type.
The custom data object size is limited to 1kB. The object is not intended to contain large complex data. If you need large data associated with the conversation store a reference to the data in the custom object and store the actual referenced data in your infrastructure.