Statflo Documentation

Universal Compliance

Universal Compliance

SOC2

After 8 years of enabling outreach with front-line teams, we saw that the single most important reason that opt-outs occured, lack of replies or risk was created was due to lack of compliance.

One wrong word read out of context was enough to cause offense or create risk. As such, TextKit's universal Compliance service was built to ensure that every attempt to communicate with a Campaign Member is checked against a number of rules, to filter every message sent or received, and to allow for an unlimited number of configuration rules per Customer or Partner.

While there are a number of scopes to our Compliance API available to enterprise Customers and Partners (DNC, etc), some scopes include:

dataStream

All activity in Textkit is available as a dedicated Kinesis stream where enterprises can have multiple webhooks triggered from, based on events saved there, providing low latency (sub 10ms) notification of key actions taken. Data shared with the data stream includes Twilio data, campaign data, activity and data connected to TextKit's Apollo data graph.

optOutPages

An enterprise feature automatically - optionally added to any message sent to Canadian phone numbers or any enterprise campaign. In production use since 2016. Supports multi-language, personalization, localization, and custom branding.

universalDNC

Go beyond opt-out management on a per-number of per-campaign level, and track all opt-outs by channel. We also check if a business meets the rules for TCPA or existing business relationship exemptions.

Some of the channels supported:

enum method {
SMS
WHATSAPP
WEBCHAT
INAPP
CALL
RCS
VIDEO
APPLEMESSAGE
GOOGLEMESSAGE
EMAIL
WECHAT
FACEBOOK
RCS
LINE
VIBER
TWITTER
}

verifyMessage

This query checks against configured rules to determine if message content is to be rejected. An interface sends the query:

{
"VerifyMessageInput":
{
"content": "The system won't let me do that"
}
}
query VerifyMessage ($VerifyMessageInput: VerifyMessageInput!) {
verifyMessage(input: $VerifyMessageInput) {
originalContent
complianceAdvices {
reasonCode
reasonMessage
reasonDescription
content
contentArea
{
start
end
}
}
}
}

Which responds with, if error:

{
"data": {
"verifyMessage": {
"originalContent": "The system won't let me do that",
"complianceAdvices": [
{
"reasonCode": "VIOLATION",
"reasonMessage": "Sounds Defensive",
"reasonDescription": "This makes you appear to not be in control. Let's remove this phase to sound like we can do something for them.",
"content": "The system won't let",
"contentArea": {
"start": 0,
"end": 20
}
}
]
}
}
}

Optional datasets and partner integrations can check against custom dictionaries, mispellings, L337, symbols and tens of thousands of known phrases that could offend, not be considered neutral or cause a message to not get delivered.

# Sample phrases to avoid:
#
# you're killing it
# free gift
# spreading like a virus
# that guy
# those people are the worst
{
"VerifyMessageInput":
{
"content": "I have a free gift for you from the best bank in town"
}
}
query VerifyMessage ($VerifyMessageInput: VerifyMessageInput!) {
verifyMessage(input: $VerifyMessageInput) {
originalContent
complianceAdvices {
reasonCode
reasonMessage
reasonDescription
content
contentArea
{
start
end
}
}
}
}

Which would return:

{
"data": {
"verifyMessage": {
"originalContent": "I have a free gift for you from the best bank in town",
"complianceAdvices": [
{
"reasonCode": "SPAM",
"reasonMessage": "Likely blocked as SPAM",
"reasonDescription": "You'll get a better result if you remove this phrase and stay conversational.",
"content": "free gift",
"contentArea": {
"start": 9,
"end": 18
}
},
{
"reasonCode": "VIOLATION",
"reasonMessage": "Over-promising",
"reasonDescription": "You could be at risk. Please use a different phrase or be more specific if you can.",
"content": "the best bank",
"contentArea": {
"start": 32,
"end": 45
}
}
]
}
}
}