Your Logic decides what actions should Salted CX do with each update in the conversation.
Your Logic Response Endpoint
Your Logic sends the request to https://api.eu.salted.cx/api/v1/live/your-logic
endpoint that contains account ID and conversation PID.
https://api.eu.salted.cx/api/v1/live/your-logic/accounts/[ACCOUNT]/conversations/[CONVERSATION]
Each call to this endpoint MUST contain shared secret in the Authorization
header. Each response that does not contain the header or contains unexpected value is ignored and no action is taken.
Authorization: Bearer <shared secret>
Common Properties
Property | Type | Description |
---|---|---|
requestId | UUID (Optional) | Unique identifier of the request. Use it tell Salted CX that it can consider the request to be resolved and move forward. |
conversation | UUID (Path parameter) | Identifier of the conversation this request is related to. This property cannot be present together with the request property. |
control | Object | Gives Salted CX information about how to process the response and what actions to take. |
customer | Object | Object with customer attributes to be updated. You can use this to provide information about the customer that will appear in analytics when you use one of the supported attributes. You can also use custom object in the customer object to provide additional details that you will receive with the next request. |
actions | Array | List of actions that are executed by Salted CX after receiving this response. There are many different actions such as sending a message, saving a note for agents, inviting people to the conversation. If Salted CX fails to execute an action the rest of the actions are ignored. |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"control": {
/* Customize how Salted CX behaves */
"skipToTime": "time",
"skipToLatest": true,
"ignoreOnCustomerAction": true,
"ignoreOnAgentAction": false,
}
"customer": {
/* You can use this object to update customer data across multiple conversations */
"custom": {
}
},
"conversation": {
/* You can use this object to update conversation data */
"custom": {
/* Use this object to store session data that will not be visible in the ananalytics */
}
},
"actions": [
/* List of actions that are performed sequentially by Salted CX when it processes this reponse */
]
}
Control
Control enables you to modify the default Salted CX behavior for processing the participant actions. Control enables Your Logic to deal with asynchronous communication, provide faster responses to customers and optimize costs by processing less incremental requests.
Property | Type | Description |
---|---|---|
skipToTime | Time | Ignore all events up to this time. Request will be sent only for events that happened after this time. |
skipToLatest | Boolean | This will skip to the latest event. In case this property is set to true the skipToTime is ignored. |
ignoreOnCustomerAction | Boolean | Actions returned by this response are ignored if there are any updates from the customer side. |
ignoreOnAgentAction | Boolean | Actions returned by this response are ignored if there are any updates from the agent side. |
{
"requestId": "a9c9f343-8a80-43f5-a6b2-d61cc06d4d1d",
"control": {
"skipToTime": "2025-04-15T18:15:51Z",
"skipToLatest": true,
"ignoreOnCustomerAction": true,
"ignoreOnAgentAction": true
}
}
Response without Request
You can also send responses unrelated to any specific requests. In this case you have to reference a conversation. A good example would be a very long running background task that needs to be completed or some action you perform after an timeout unless it is canceled during the conversation.

Responses without requests can contain exactly the same actions as the responses related to a requests. They have to contain Conversation PID instead of Request PID.
{
"conversation": "c9bf9e57-1685-4c89-bafb-ff5af830be8a",
"actions": [
{
"type": "MESSAGE",
"content": "Your travel plans have been confirmed with all the travel agencies. Here is your itenerary https://demoadventures.com/trips/1679287. Have a nice trip!"
}
]
}
Response with Multiple Actions
Your Logic can send response with multiple actions. Salted CX executes those actions sequentially. If one action fails the rest of the actions are not executed. In the example below Your Logic lets customer know that it may take a while to involve a human agent and thens write a short summary of the previous conversation as a note.
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"actions": [
{
"type": "MESSAGE",
"content": "Sorry, I do not know about that. Give me a moment to connect you with a human colleague."
},
{
"type": "NOTE",
"content": "The customer is asking about a product not mentioned in our knowledge base - Star Plan."
},
{
"type": "NEEDS_HELP",
"needsHelp": true
}
]
}
You can check for examples of responses with multiple actions in Your Logic Response Examples.
Available Actions
There are these actions currently available in Your Logic.
Action | Description |
---|---|
MESSAGE | Send a message a message visible to a customer as a bot. |
NEEDS_HELP | Asks any agent for help. |
NOTE | Saves a note invisible to the customer. |
QUESTION | Asks a question defined in Salted CX to a customer. |
QUESTION_DYMAMIC | Sends a dynamically built question. Your Logic can customize the question and the question |
CONVERSATION_UPDATE | Update custom properties of a conversation. |
INVITE_EXTERNAL_AGENT | Invites an external to the conversation by sending an email to them. |
ENGAGEMENT_COMPLETE | Completes the engagement. You can use this to kick the agents out of the conversation. |
COMPLETE_CONVERSATION | Completes the conversation and all engagements in that conversation. Customers can still write back and reopen the conversation. |
CREATE_CONVERSATION | Creates an empty conversation. |
SEND_FILE | Sends a file to a user. |
WHATSAPP_TEMPLATE | Sends approved WhatsApp template to the customer. |
No Action
Empty response means that Salted CX will do nothing as the response. You SHOULD send even empty responses to tell Salted CX that it can move forward with the conversation and send the next event into Your Logic if there is any. Sending this event as soon as possible is important for reducing latency.
{
"actions": [
{
"type": "NO_ACTION"
}
]
}
Send Message
This response sends a message that is visible to a customer.
Property | Type | Description |
---|---|---|
content | String | The content of the message to send to the customer. |
language | String (Optional) | Two-letter ISO-639 alpha-2 language code. |
{
"actions": [
{
"type": "MESSAGE",
"content": "Would moving the booking to this Friday at 17:00 work for you?"
}
]
}
Send WhatsApp Template Message
Sends an approved WhatsApp template to the customer. This enables to start outbound conversations from Your Logic.
Property | Type | Description |
---|---|---|
whatsAppTemplateId | String | Identifier of the template in WhatsApp. |
variables | Object | Key value pairs of variables to fill into the template. |
{
"actions": [
{
"type": "WHATSAPP_TEMPLATE",
"templateName": "offer_help_named_params",
"language":{"code": "en"},
"parameters": {
"customer_name": "Adam",
"discount_value": "6",
"questions_reference" : "serving lunch"
}
}
]
}
Needs Help
Ask for help makes the conversation appear in inbox for the agents. Your Logic still receives all the requests during the communication. However agents can join the conversation and help with its resolution.
Property | Type | Description |
---|---|---|
needsHelp | Boolean | true if the conversation should be flagged with Needs Help, conversations with Needs Help appear in Live Conversations so agents can join the conversations, this flag can be raised even when an agent is currently engaged, which enables another agent to join
false if the conversation no longer needs help of an agent |
{
"actions": [
{
"type": "NEEDS_HELP",
"needsHelp": true
}
]
}
Save Note
This response saves a note that is only visible to agents, external agents but invisible to customers.
Property | Type | Description |
---|---|---|
content | String | The content of the note. |
responseTo | UUID (Optional) | The UUID of the turn that the note is attached to. |
{
"actions": [
{
"type": "NOTE",
"content": "It is unlear what it our policy for Switzerland.",
"responseTo": "<uuid>"
}
]
}
Send WhatsApp Template
This action sends an outbound message to a customer. Prepared messages are picked from the existing peppered ones. They can be customized using variables.
Property | Type | Description |
---|---|---|
templateName | String | ID of an approved WhatsApp template to be sent to the customer. |
language | String | ISO code of the template language to use. |
parameters | Object | Key-value pairs of variables to fill into placeholders in the template. These variables enable to customize the message for the specific customer. |
{
"actions": [
{
"type": "WHATSAPP_TEMPLATE",
"templateName": "offer_help_named_params",
"language":{"code": "en"},
"parameters": {
"customer_name": "Radek",
"discount_value": "6",
"questions_reference" : "serving lunch"
}
}
]
}
Send File
This action sends a file to a user. Before triggering the action, you must first call the API, which returns an upload URL and file path. After uploading your file to the provided URL, you can then trigger the action using the file path from the API response.
https://api.eu.salted.cx/api/v1/live/media/accounts/[ACCOUNT]/upload-url
Each call to this endpoint MUST contain shared secret in the Authorization
header.
Authorization: Bearer <shared secret>
Property | Type | Description |
---|---|---|
path | String | URL pointing to the storage location of the uploaded media file. |
name | String | Optional name of the uploaded file. |
content | String | Optional content or description associated with the file. |
mimeType | String | MIME type indicating the file format (e.g., image/png , application/pdf ). |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"actions": [
{
"type": "SEND_FILE",
"path": "/path/that/you/retrieved/from/our/file/service.extension",
"name": "invoice.pdf",
"content": "Invoice for Order #739281",
"mimeType": "application/pdf"
}
]
}
Ask Question
This action sends a question to the target participant. You can use any Question PID in Salted CX. To find out what is the question PID for a given question open the question in Salted CX and copy its PID from the browser address bar.
Property | Type | Description |
---|---|---|
targetParticipantType | String | The type of the participant who should reply to this message. Currently limited to the Customer. |
questionPid | UUID | The PID of question in Salted CX to send to the participant to answer. |
enableTranslation | Boolean | If true Salted CX translates the question and answers.
Default false . |
saveAsReview | Boolean | Tells whether the answer should be saved as review. This is useful when asking for example for customer satisfaction that you might want to view in analytics. |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"actions": [
{
"type": "QUESTION",
"questionPid": "36c8f00c-44c9-4633-bfa7-2f3a3b51c1df"
}
]
}
Ask Ad-Hoc Question
Asking ad-hoc question enables you to give customers and other participant dynamically generated choices without the need for a question created in Salted CX. This enables you to have dynamically generated question. Answers to these questions are not in reporting but are visible in the reporting.
When the customer submits the answer you will get the answer in a request sent to Your Logic so you can react to customer clicking on any of the options.
{
"actions": [
{
"type": "QUESTION_DYNAMIC",
"question": {
"externalId": "question1",
"content": "What is your preffered time slot?",
"answers": [
{
"externalId": "16-00",
"content": "16:00 to 16:30"
},
{
"externalId": "16-30",
"content": "16:30 to 17:00"
},
{
"externalId": "17-00",
"content": "17:00 to 17:30"
}
]
}
}
]
}
See Answer how to listen for answers in case customers click on them.
Update Conversation
Updates custom conversation properties. You can use custom
attribute to store up to 1kB of custom object associated with the conversation. This enables you to keep information related to the conversation in Salted CX without having to maintain this information in Your Logic. This enables to handle some scenarios more easily — such as as restarting or upgrading your service.
We take the value of the custom
attribute as-is. The custom attribute value has to be a valid JSON value to be parsed successfully. Beyond this requirement and size limitation we do not do any validation of the value. The custom object can contain any inner structure.
We do not process the content of the object in any way. Your Logic implementation is responsible for providing complete object with all values set to the latest state.
{
"actions": [
{
"type": "CONVERSATION_UPDATE",
"custom": {
"customer_name": "Adam",
"orderNumber": "ORDER-123",
"allOrdersInProgress": [
"ORDER-245",
"ORDER-982"
]
}
}
]
}
(Upcoming)
Update CustomerUpdates custom customer properties. You can use custom
attribute to store up to 1kB of custom object associated with the customer. This enables you to keep information related to the customer in Salted CX without having to maintain this information in Your Logic. This enables to handle some scenarios more easily — such as as restarting or upgrading your service.
We take the value of the custom
attribute as-is. The custom attribute value has to be a valid JSON value to be parsed successfully. Beyond this requirement and size limitation we do not do any validation of the value. The custom object can contain any inner structure.
We do not process the content of the object in any way. Your Logic implementation is responsible for providing complete object with all values set to the latest state.
{
"request": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"actions": [
{
"type": "CUSTOMER_UPDATE",
"contacts": [
{
"type": "Phone",
"contact": "+1234567890"
},
{
"type": "Customer ID",
"contact": "CUST-123456"
}
]
"custom": {
"totalBusinessValue": 4300,
"predictedSpend1Y": 2100,
"customerProgram": "Gold",
"lastOrders": [
{
"orderId": "ORDER-1",
"status": "Delivered"
},
{
"orderId": "ORDER-2",
"status": "In Progress"
}
]
}
}
]
}
Start Conversation
Starts a conversation from your logic using the selected channel.
Property | Type | Description |
---|---|---|
customer | Object | Object describing the customer. |
customer.displayName | String | Name of the customer as it should show for the agent. It should not be protected personal information. We generally recommend using the first (given) name. |
customer.contact | Object | Object containing the contact itself. |
customer.contact.contactType | String | Type of the contact such as Email or Phone. |
customer.contact.contact | String | The actual contact. |
{
"actions": [
{
"type": "CREATE_CONVERSATION",
"conversation": {
"channelVendor": "WHATSAPP",
"languageCustomer": "cs"
},
"customer": {
"displayName": "Radek Outbound",
"contact": {
"contactType": "PHONE",
"contact": "+1098765431"
}
}
}
]
}
Future target JSON
{
"actions": [
{
"type": "START_CONVERSATION",
"customer": {
"displayName": "Radek",
"contact": {
"contactType": "Phone",
"contact": "+1234567890",
}
},
"conversation": {
"channelVendor": "WhatsApp",
"companyContact": "+1800111222333",
"custom": {
}
}
}
]
}
Invite External Agent
This action sends an invite to an external agent to join the conversation. The external agent will receive a notification (email) with link authorizing them to access the conversation.
Property | Type | Description |
---|---|---|
String | Email that can be used to reach the external agent. This can be a person in your company that does not have user account in Salted CX. | |
name | String (optional) | User facing name of the external agent. Defaults to the email. |
subject | String (optional) | Subject of the email sent to the external agent.
Default value is Join a Conversation with a Customer |
message | String (optional) Markdown??? | The message to send to the external agent. Use this opportunity to communicate urgency and expectations. By default the following message will be sent:
Hello,
you are invited to assist in a conversation with a customer. Please join as soon as possible to make sure the customer gets the best possible customer care.
Thank you.
You can change the default invitation message in brand preferences. |
expires | Time | The time until which the partner has access to the conversation. After this time period the link no longer enables the external agent to access the conversation. In case you want the external agent to engage in the conversation you need to send a new invite. The maximum expiration time is 10 days from the current time. |
permissions | Object | Salted permissions object. |
{
"actions": [
{
"type": "INVITE_EXTERNAL_AGENT",
"email": "agent@company.cx",
"name": "Agent Name",
"subject": "Help with order",
"message": "Hello, I need assistance with order from your shop.",
"expires": "2025-07-29T10:30:00Z"
}
]
}
(Upcoming)
Customize External InvitesEnables you to list email addresses that agents are enabled to invite into a conversation. This enables to offer these emails to the agent and also restricts their options. These restrictions do not apply to Your Logic.
Property | Type | Description |
---|---|---|
inviteSubject | String | Email subject for all invitations. |
inviteMessage |
{
"actions": [
{
"type": "CONVERSATION_UPDATE",
"conversation": {
"externalAgents": {
"inviteSubject": "Help us with the Customer",
"inviteMessage": "Hello, how are you?",
"allowCustomization": false,
"allowCustomEmails": true,
"allowed":[
{
"name": "Partner",
"email": "support@partner.com"
},
{
"name": "Partner - VIP",
"email": "vip@partner.com",
}
]
}
}
}
]
}
(Upcoming)
Complete EngagementThis action enables you to tell that the engagement is considered complete. By default this action is related to the engagement associated with Your Logic.
Property | Type | Description |
---|---|---|
engagementPid | PID | The engagement that should be completed. |
name | String | The name of the engagement that is shown in the reporting. |
outcomeType | Enum | The outcome type related to the engagement. |
outcome | String | The outcome of the engagement. |
outcomeCategory | String | Higher level classification of the outcome. |
reason | String | The reason for the call. |
reasonCategory | String | Higher level classification of the reason. |
cost | Decimal | The costs associated with the engagement. |
{
"actions": [
{
"type": "ENGAGEMENT_COMPLETE",
"engagementPid": "582fa5da-d423-46ae-b69f-aa1d2b01f736",
"name": "Engagement Outbound #2",
"reasonCategory": "CUSTOMER_REQUEST",
"reason": "Customer requested to end the conversation",
"outcome": "COMPLETED",
"outcomeType": "ACCEPTED",
"outcomeCategory": "Delivered",
"cost": "0.6"
}
]
}
(Upcoming)
Complete ConversationThis action completes the conversation and all of its engagements (if there are any).
Action has no properties.
{
"actions": [
{
"action": "CONVERSATION_COMPLETE"
}
]
}
(Idea)
Disengage Your LogicIn case Your Logic no longer wants to be included the conversation in any way it can let Salted CX know by setting the property engageYourLogic
to false
. From this moment Your Logic will receive no updates regarding this conversation.
Property | Type | Description |
---|---|---|
engageYourLogic | Boolean | Tells whether to engage Your Logic in this conversation. Your Logic can set this to false. It is impossible for Your Logic to set it to true as it does not receive events when it is engaged. |
{
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"actions": [
{
"type": "ENGAGE_YOUR_LOGIC",
"engageYourLogic": false
}
]
}
(Idea)
Navigation OptionsOffer the customers options to move forward in their menu.
{
"actions": [
{
"action": "Menu",
"questionName": "What would you like to do with the reservation?",
"asnwers": [
{
"technicalID": "rebook",
"name": "Rebook"
},
{
"technicalID": "cancel",
"name": "Cancel"
}
]
}
]
}
(Idea)
Navigate ArticleNavigates the user to the provided article.
{
"actions": [
{
"type": "ARTICLE_NAVIGATE",
"article": "e27ac10b-58cc-4372-a567-0e02b2c3d421"
}
]
}
(Idea)
Mute the ConversationThis action mutes the conversation which agents do not receive any notifications about it. You can use this action to silence abusive customers. The messages will be still visible in the customer journey and Your Logic will receive requests related to the conversation.
{
"actions": [
{
"type": "CONVERSATION_MUTE",
"mute": true
}
]
}
(Idea)
Block ConversationThis action blocks the conversation. Salted CX blocks drops all messages related to this conversation from the customer.
{
"actions": [
{
"type": "CONVERSATION_BLOCK",
"block": true
}
]
}
(Idea)
Mute the CustomerThis action mutes all the conversations (current and future) with the customers. Muted customers can write you and you will receive their messages in Your Logic.
{
"customer": {
"muted": false
}
"actions": [
{
"type": "CUSTOMER_MUTE",
"mute": true
}
]
}
(Idea)
Block CustomerThis action blocks the customer. Salted CX blocks drops all messages related to this customer and prevents a conversation from starting.
{
"customer": {
"muted": false
}
"actions": [
{
"type": "CUSTOMER_BLOCK",
"block": true
}
]
}