DevelopersAPI referenceEngagement

Messaging API

REST endpoints for messaging in SKUFlow: 8 operations with parameters, request and response fields, permissions and curl examples.

Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.

OperationEndpointRisk
Get messaging settingsGET /organizations/{organizationId}/messaging/settingsread
Change messaging settingsPATCH /organizations/{organizationId}/messaging/settingswrite
List the email and SMS providersGET /organizations/{organizationId}/messaging/channelsread
Connect an email or SMS providerPATCH /organizations/{organizationId}/messaging/channels/{channel}sensitive
Disconnect a provider (back to test mode)DELETE /organizations/{organizationId}/messaging/channels/{channel}sensitive
Send a test messagePOST /organizations/{organizationId}/messaging/channels/{channel}/testsensitive
Simulate a customer's text reply (test mode)POST /organizations/{organizationId}/messaging/simulate-replywrite
Run the automations nowPOST /organizations/{organizationId}/messaging/runsensitive

Get messaging settings

GET /organizations/{organizationId}/messaging/settings

Quiet hours (in the organization's timezone; default 21:00–08:00), the cap on automated messages per customer per day, sender name, reply-to, business phone and review link. Read-only.

Permissionengagement.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolmessaging_settings (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/settings" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
quietHoursEnabledboolean
quietHoursStartstring
quietHoursEndstring
maxPerCustomerPerDayinteger
senderNamestring or null
replyTostring or null
businessPhonestring or null
reviewUrlstring or null
emailBrandColorstring or nullEmail branding: the accent colour (#rrggbb); null = SKUFlow blue.
emailHeaderTextstring or nullEmail branding: the line under the logo.
emailFooterTextstring or nullEmail branding: the business's footer text.
timezonestringThe organization's timezone: quiet hours are counted in it.
updatedAtstring or nullISO 8601 time (UTC).

Change messaging settings

PATCH /organizations/{organizationId}/messaging/settings

Quiet hours, the daily cap per customer, sender name, reply-to, business phone and review link. Only the fields sent change.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolmessaging_updateSettings (toolset settings)

Request body

FieldTypeRequiredDescription
quietHoursEnabledbooleanNo
quietHoursStartstringNoStart of quiet hours, HH:MM in the org timezone.
quietHoursEndstringNoEnd of quiet hours, HH:MM in the org timezone.
maxPerCustomerPerDayintegerNoAutomated messages per customer per day; 0 = no cap. 0–50.
senderNamestring or nullNoUp to 100 characters.
replyToempty string or string (email) or nullNo
businessPhonestring or nullNoUp to 32 characters.
reviewUrlempty string or string (uri) or nullNoWhere review requests point, e.g. your Google review link.
emailBrandColorempty string or string or nullNoEmail branding: the accent colour of the header bar and buttons (#rrggbb).
emailHeaderTextstring or nullNoEmail branding: a line under the logo, e.g. "Custom printing since 1998". Up to 120 characters.
emailFooterTextstring or nullNoEmail branding: the business's own footer text (website, hours, license number). Up to 500 characters.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/settings" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"quietHoursEnabled":true,"quietHoursStart":"09:00","quietHoursEnd":"09:00"}'

Response

200: the answer's fields
FieldTypeDescription
quietHoursEnabledboolean
quietHoursStartstring
quietHoursEndstring
maxPerCustomerPerDayinteger
senderNamestring or null
replyTostring or null
businessPhonestring or null
reviewUrlstring or null
emailBrandColorstring or nullEmail branding: the accent colour (#rrggbb); null = SKUFlow blue.
emailHeaderTextstring or nullEmail branding: the line under the logo.
emailFooterTextstring or nullEmail branding: the business's footer text.
timezonestringThe organization's timezone: quiet hours are counted in it.
updatedAtstring or nullISO 8601 time (UTC).

List the email and SMS providers

GET /organizations/{organizationId}/messaging/channels

The provider of each channel: test mode (log only, the default) or the connected provider with its sender, the last four characters of its credential, its webhook URLs (inbound texts, delivery status, bounces) and the last test. Never returns credentials. Read-only.

Permissionchannels.manage (Owner, Admin)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolmessaging_channels (toolset settings)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/channels" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
channelsarray of object
channels[].channelenumOne of EMAIL, SMS.
channels[].providerKeystringtest (log only) | skuflow_email (SKUFlow email, the default for new businesses) | resend | postmark | sendgrid | mailgun | ses | skuflow (SKUFlow texting) | twilio
channels[].testModeboolean
channels[].settingsobjectSender and options; never credentials.
channels[].secretHintstring or nullLast four characters of the main credential.
channels[].webhookUrlsobject
channels[].webhookUrls.inboundstring or null
channels[].webhookUrls.statusstring or null
channels[].webhookUrls.eventsstring or null
channels[].lastTestedAtstring or nullISO 8601 time (UTC).
channels[].lastTestErrorstring or null
channels[].updatedAtstring or nullISO 8601 time (UTC).
providersarray of object
providers[].keystring
providers[].channelstring
providers[].labelstring

Connect an email or SMS provider

PATCH /organizations/{organizationId}/messaging/channels/{channel}

Sends data out: sets the channel's provider: test (log only), or resend / postmark / sendgrid / mailgun / ses (EMAIL) or twilio (SMS) with its sender and credentials. Credentials are encrypted at rest and never returned; leave a credential blank to keep the stored one. From then on messages really go out through it.

Permissionchannels.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolmessaging_setChannel (toolset settings)
ApprovalWaits for your approval in SKUFlow when called with an API key or a connected app: the first call answers 428 APPROVAL_REQUIRED; once you approve it, repeat the call with the X-SKUFlow-Approval header. See Approvals.

Parameters

NameInTypeRequiredDescription
channelpathenumYesOne of EMAIL, SMS.

Request body

FieldTypeRequiredDescription
providerKeyenumYesOne of test, resend, postmark, sendgrid, mailgun, ses, twilio.
fromAddressstringNoUp to 254 characters.
fromNamestringNoUp to 100 characters.
fromNumberstringNoTwilio: the sending number (+E.164). Up to 32 characters.
messagingServiceSidstringNoUp to 64 characters.
regionstringNoSES region, or Mailgun us / eu. Up to 32 characters.
domainstringNoMailgun sending domain. Up to 253 characters.
messageStreamstringNoPostmark message stream. Up to 100 characters.
apiKeystringNoCredential (write-only). Up to 500 characters.
serverTokenstringNoCredential (write-only). Up to 500 characters.
accessKeyIdstringNoCredential (write-only). Up to 200 characters.
secretAccessKeystringNoCredential (write-only). Up to 500 characters.
accountSidstringNoCredential (write-only). Up to 100 characters.
authTokenstringNoCredential (write-only). Up to 200 characters.
webhookSigningSecretstringNoBounce webhook signing secret (write-only). Up to 500 characters.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/channels/{channel}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"providerKey":"test"}'

Response

200: the answer's fields
FieldTypeDescription
channelenumOne of EMAIL, SMS.
providerKeystringtest (log only) | skuflow_email (SKUFlow email, the default for new businesses) | resend | postmark | sendgrid | mailgun | ses | skuflow (SKUFlow texting) | twilio
testModeboolean
settingsobjectSender and options; never credentials.
secretHintstring or nullLast four characters of the main credential.
webhookUrlsobject
webhookUrls.inboundstring or null
webhookUrls.statusstring or null
webhookUrls.eventsstring or null
lastTestedAtstring or nullISO 8601 time (UTC).
lastTestErrorstring or null
updatedAtstring or nullISO 8601 time (UTC).

Disconnect a provider (back to test mode)

DELETE /organizations/{organizationId}/messaging/channels/{channel}

Destructive: deletes the channel's provider and its stored credentials; messages are logged in test mode (SENT_TEST) again and nothing is sent.

Permissionchannels.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolmessaging_removeChannel (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Parameters

NameInTypeRequiredDescription
channelpathenumYesOne of EMAIL, SMS.

Example

curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/channels/{channel}" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
channelenumOne of EMAIL, SMS.
providerKeystringtest (log only) | skuflow_email (SKUFlow email, the default for new businesses) | resend | postmark | sendgrid | mailgun | ses | skuflow (SKUFlow texting) | twilio
testModeboolean
settingsobjectSender and options; never credentials.
secretHintstring or nullLast four characters of the main credential.
webhookUrlsobject
webhookUrls.inboundstring or null
webhookUrls.statusstring or null
webhookUrls.eventsstring or null
lastTestedAtstring or nullISO 8601 time (UTC).
lastTestErrorstring or null
updatedAtstring or nullISO 8601 time (UTC).

Send a test message

POST /organizations/{organizationId}/messaging/channels/{channel}/test

Sends a message: a short test email or text to the given address through the channel's provider (in test mode it is only logged, SENT_TEST). The outcome is recorded on the provider and in the message log.

Permissionchannels.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolmessaging_testSend (toolset settings)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Parameters

NameInTypeRequiredDescription
channelpathenumYesOne of EMAIL, SMS.

Request body

FieldTypeRequiredDescription
tostringYesEmail address or phone number. Up to 254 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/channels/{channel}/test" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"2026-11-03"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
directionenumOne of OUTBOUND, INBOUND.
sourceenumSystem: a message the customer asked for themselves (a portal sign-in code; its code is scrubbed once sent). One of AUTOMATION, MANUAL, TEST, INBOUND, CAMPAIGN, SYSTEM.
channelenumOne of EMAIL, SMS.
purposeenumOne of TRANSACTIONAL, MARKETING.
statusenumOne of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
statusReasonstring or null
providerstring or null
toAddressstring or null
fromAddressstring or null
subjectstring or null
previewstringThe first 160 characters of the body.
customerIdstring or null
customerNamestring or null
ruleIdstring or null
ruleNamestring or null
campaignIdstring or nullThe marketing campaign it belongs to (source CAMPAIGN).
openedAtstring or nullFirst open the email provider reported.
clickedAtstring or nullFirst click the email provider reported.
subjectTypestring or null
subjectIdstring or null
scheduledForstringISO 8601 time (UTC).
sentAtstring or nullISO 8601 time (UTC).
createdAtstringISO 8601 time (UTC).

Simulate a customer's text reply (test mode)

POST /organizations/{organizationId}/messaging/simulate-reply

Test mode only (no SMS provider connected): processes a text as if the customer sent it from from, exactly like a signed Twilio webhook: STOP / START / HELP change consent, the reply is logged as an inbound message and message.replied ends cadences. 400 with a real provider (replies come from its webhook).

Permissionchannels.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolmessaging_simulateReply (toolset settings)

Request body

FieldTypeRequiredDescription
fromstringYesThe customer's phone number. Up to 32 characters.
bodystringYesUp to 1600 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/simulate-reply" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"2026-11-03","body":"string"}'

Response

200: the answer's fields
FieldTypeDescription
messageIdstring
customerIdstring or null
keywordenum or nullOne of STOP, START, HELP.
replystring or null

Run the automations now

POST /organizations/{organizationId}/messaging/run

Customer-facing: runs this organization's engine once without waiting for the worker: arms and fires due RELATIVE timers (reminders), runs due scheduled rules, advances cadences and sends due messages. The outbox (events) is consumed for every organization in order, as the worker does. now is for tests only (refused in production).

Permissionengagement.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolmessaging_runNow (toolset settings)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Request body

FieldTypeRequiredDescription
nowstring (date-time)NoTests only: run as of this moment (ISO 8601). Refused when the server runs with NODE_ENV=production.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/run" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"now":"2026-11-03T15:00:00Z"}'

Response

200: the answer's fields
FieldTypeDescription
ranAtstring
eventsinteger
timersobject
timers.armedinteger
timers.firedinteger
timers.cancelledinteger
timers.skippedinteger
cadenceStepsinteger
messagesobject
messages.attemptedinteger
messages.sentinteger
messages.testinteger
messages.failedinteger
messages.skippedinteger
messages.retryinginteger

On this page