Articles in this section

Integrating Kustomer SMS with Solve Widget

You can connect Kustomer’s SMS channel to Forethought by setting up a Kustomer workflow that sends incoming SMS messages to Forethought’s Kustomer SMS API. This allows Solve to respond to and manage SMS-based customer conversations using your existing Solve workflows—just adapted for SMS format.

When to Use This Integration

Use this integration if your team supports customers via SMS using Kustomer and you want Forethought’s Solve Widget to:

  • Automatically respond to incoming SMS inquiries
  • Run existing Solve workflows based on message content
  • Escalate to agents when needed

This feature is available for customers using Kustomer with the Twilio integration enabled. 

Why It Matters

Enable AI-Powered SMS Resolution

Let Solve automatically handle SMS inquiries using the same logic you’ve built for your widget workflows.

Reduce Manual Work

Automate message handling without requiring agent involvement unless necessary.

Maintain Contextual Conversations

Messages within a 24-hour window are kept in the same conversation thread, allowing AI to act with full context.

How It Works (Step-by-Step)

Step 1: Prerequisites

Step 2: Create a Workflow in Kustomer

  • Use the Message Create trigger as your workflow entry point. Learn more here: Workflows Overview
  • You may use the workflow example (JSON) below as a starting point

⚠️  You must modify the API key and any custom variables before using this workflow

{
    "description": "- checks that new message is inbound and SMS\n- adds conversation to a queue where forethought conversations go before they are automated / handed off\n- adds ft_sms_automating tag\n- calls Forethought's SMS API with an example workflow context variable",
    "name": "export-forethought-sms-channel--fea8a0aa-a7f2-43f5-92db-6a27ea4f88b2",
    "meta": {
        "displayName": "Export Forethought SMS Channel - Example"
    },
    "steps": [
        {
            "transitions": [
                {
                    "target": "4vlL8t7L",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "H5IhGfk8",
            "action": "kustomer.conversation.find-by-id",
            "params": {
                "id": "/#steps.1.conversation"
            },
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [
                {
                    "target": "VXTGEpoD",
                    "condition": {
                        "op": "eq",
                        "values": [
                            "/#steps.4vlL8t7L.queue",
                            "66f2d7eed40b1be12fd18951"
                        ]
                    },
                    "meta": {
                        "name": "Is in Forethought (SMS) queue?"
                    }
                }
            ],
            "errorCases": [],
            "id": "4vlL8t7L",
            "action": "kustomer.conversation.update",
            "params": {
                "id": "/#steps.H5IhGfk8.id",
                "queue": "66f2d7eed40b1be12fd18951"
            },
            "meta": {
                "displayName": "Conversation Update Queue"
            },
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [
                {
                    "target": "mR02lKuF",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "VXTGEpoD",
            "action": "kustomer.customer.find",
            "params": {
                "identifier": "/#steps.1.customer"
            },
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [
                {
                    "target": "aEqHE92z",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "mR02lKuF"
        },
        {
            "transitions": [
                {
                    "target": "T3hpfyL7",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "aEqHE92z"
        },
        {
            "transitions": [
                {
                    "target": "vw9KdXPG",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "T3hpfyL7",
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [
                {
                    "target": "SdgX6798",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    },
                    "meta": {
                        "name": "Is SMS conversation",
                        "description": ""
                    }
                }
            ],
            "errorCases": [],
            "id": "vw9KdXPG",
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [
                {
                    "target": "Yp6tJmKU",
                    "condition": {
                        "op": "true",
                        "values": [
                            true
                        ]
                    }
                }
            ],
            "errorCases": [],
            "id": "SdgX6798",
            "action": "kustomer.conversation.append-tags",
            "params": {
                "id": "/#steps.H5IhGfk8.id",
                "tags": [
                    "66db0fc7f367b27e4b7f0ba1"
                ]
            },
            "meta": {
                "displayName": "ft_sms_automating tag"
            },
            "appVersion": "kustomer-^1.9.9"
        },
        {
            "transitions": [],
            "errorCases": [],
            "id": "Yp6tJmKU",
            "action": "kustomer.rest-api.json",
            "params": {
                "uri": "https://api.forethought.ai/kustomer/sms/message-created",
                "method": "POST",
                "data": {
                    "message_id": "/#steps.1.id",
                    "conversation_id": "/#steps.1.conversation",
                    "additional_context": {
                        "data-ft-first-name": "/#steps.VXTGEpoD.displayName"
                    }
                },
                "headers": {
                    "Authorization": "Bearer <API KEY>",
                    "Content-Type": "application/json"
                },
                "json": true
            },
            "appVersion": "kustomer-^1.9.9",
            "meta": {
                "displayName": "forethought /kustomer/sms/message-created"
            }
        },
        {
            "transitions": [],
            "errorCases": [],
            "id": "KG2DlDAy",
            "action": "kustomer.rest-api.json",
            "params": {
                "uri": "https://api.forethought.ai/kustomer/sms/conversation-updated",
                "method": "POST",
                "data": {
                    "message_id": "/#steps.1.id",
                    "conversation_id": "/#steps.1.conversation"
                },
                "headers": {
                    "Authorization": "Bearer <API KEY>",
                    "Content-Type": "application/json"
                },
                "json": true
            },
            "appVersion": "kustomer-^1.9.9"
        }
    ],
    "trigger": {
        "transitions": [
            {
                "target": "H5IhGfk8",
                "condition": {
                    "op": "and",
                    "values": [
                        {
                            "op": "eq",
                            "values": [
                                "/#steps.1.channel",
                                "sms"
                            ]
                        },
                        {
                            "op": "eq",
                            "values": [
                                "/#steps.1.direction",
                                "in"
                            ]
                        }
                    ]
                },
                "meta": {
                    "name": "Is inbound SMS?"
                }
            }
        ],
        "eventName": "kustomer.message.create",
        "id": "1",
        "appVersion": "kustomer-^1.9.9"
    }
}
 

Step 3: Add a REST API JSON Step to the Workflow

If you're using the example workflow from Step 2, this REST API step is already included.

⚠️  Just make sure to update the Authorization header with your Solve Widget API key before using it.

  • Endpoint: https://api.forethought.ai/kustomer/sms/message-created
  • Method: POST

Headers:

{
  "Authorization": "Bearer <WIDGET API KEY>",
  "Content-Type": "application/json"
}

Data:

{
  "message_id": "...",
  "conversation_id": "...",  // this is the kustomer conversation id
  "additional_context": {  // these are data-ft context variables that will be used in conversation initialization
    "data-ft-first-name": "..."
}

Step 4: Understand Solve Behavior

When Forethought receives a valid SMS message from Kustomer, Solve determines what to do based on the tags applied to the conversation.

Solve will respond only if:

  • The Kustomer conversation contains the ft_sms_automating tag, and
  • The conversation does not contain the ft_sms_automated or ft_sms_failure tags.

What happens when a message is received:

  • If it’s a new Kustomer conversation → A new Solve conversation is created.
  • If it’s an ongoing conversation → The existing Solve conversation is updated.
  • If the conversation contains ft_sms_automated or ft_sms_failure → The message is ignored.
  • If the conversation does not contain ft_sms_automating → The message is ignored.

Additional Logic:

  • All workflows from the Widget channel are used and certain steps are re-formatted to support SMS messages.
  • If Solve encounters an error or a handoff is requested, the conversation is passed to the queue defined in your widget config via support_sms_handoff_queue_id.
  • Forethought replies are sent through the support_sms_number, which must be added to your Kustomer integration credentials.

Tag Behavior

Tag Managed By Description
ft_sms_automating Admin User Manually added by your team via a Kustomer workflow to signal that Forethought should process and respond to the conversation. Required for Solve to engage with the SMS message.
ft_sms_automated Forethought Automatically added by Forethought after a handoff is performed or the conversation is completed. This tag prevents Solve from processing the conversation any further.
ft_sms_failure Forethought Automatically added only when Solve encounters a failure. Prevents any further handling by Solve.

Step 5: Test the Workflow

Before going live, test your Kustomer workflow to ensure it's working as expected.

To test:

  1. Filter for a specific customer:You can modify the workflow to only proceed for certain users, such as the admin performing the test. This ensures your test messages don’t affect real users.
  2. Activate the workflow in Kustomer.
  3. Send an SMS message to your Twilio number, which is associated with your Kustomer instance.

If everything is configured correctly, the message will trigger the workflow, send a request to Forethought, and either create or update a conversation in Solve.

Best Practices

✅ Add the ft_sms_automating tag in your workflow to ensure Forethought responds

✅ Test your workflow before going live to confirm the API call is working

✅ Monitor handoffs and failures using the queue defined in support_sms_handoff_queue_id

❌ Don’t forget to update your API key and variable names in the JSON example

Q&A

Can I use the example JSON without changes?

No. You’ll need to update the API key, context variables, and any custom logic before it works with your environment.

How long do SMS conversations last in Kustomer?

Messages within 24 hours are grouped into the same conversation. New messages after 24 hours start a new thread.

What if the AI can’t handle the message?

The conversation is routed to the queue you define in support_sms_handoff_queue_id.

How does Forethought handle conversation persistence?

Forethought uses its standard conversation persistence logic. If a new message is received and the previous Forethought conversation is no longer active (e.g., redacted or expired), a new Forethought conversation will be created.

Are there cases where Forethought will ignore incoming messages?

Yes. If the Kustomer conversation contains either the ft_sms_automated or ft_sms_failure tag, Forethought will ignore any new messages. These tags indicate that Forethought has already completed its part in the conversation or encountered a failure.

Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.

Support

  • Need help?

    Click here to submit a support request. We are here to assist you.

  • Business hours

    Monday to Friday 8am - 5pm PDT excluding US holidays

  • Contact us

    support@forethought.ai