REST endpoints for messages in ServFlo: 10 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
The message log: every email and text sent (or logged in test mode as SENT_TEST), deferred by quiet hours, skipped with its reason, failed or bounced, and every inbound reply (direction INBOUND). Filter by status, channel, direction, customer, automation, dates or text. Newest first. Read-only.
System: 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.
items[].channel
enum
One of EMAIL, SMS.
items[].purpose
enum
One of TRANSACTIONAL, MARKETING.
items[].status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
items[].statusReason
string or null
items[].provider
string or null
items[].toAddress
string or null
items[].fromAddress
string or null
items[].subject
string or null
items[].preview
string
The first 160 characters of the body.
items[].customerId
string or null
items[].customerName
string or null
items[].ruleId
string or null
items[].ruleName
string or null
items[].campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
GET /organizations/{organizationId}/messages/{messageId}
One message with the exact rendered body (and the email's HTML), its status timeline (queued, deferred, sent, delivered, failed …), what produced it and the replies to it. Read-only.
System: 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.
channel
enum
One of EMAIL, SMS.
purpose
enum
One of TRANSACTIONAL, MARKETING.
status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
statusReason
string or null
provider
string or null
toAddress
string or null
fromAddress
string or null
subject
string or null
customerId
string or null
customerName
string or null
ruleId
string or null
ruleName
string or null
campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
openedAt
string or null
First open the email provider reported.
clickedAt
string or null
First click the email provider reported.
subjectType
string or null
subjectId
string or null
scheduledFor
string
ISO 8601 time (UTC).
sentAt
string or null
ISO 8601 time (UTC).
createdAt
string
ISO 8601 time (UTC).
body
string
html
string or null
providerMessageId
string or null
contactMethodId
string or null
templateId
string or null
variantId
string or null
stepIndex
integer or null
sentByUserId
string or null
deliveredAt
string or null
ISO 8601 time (UTC).
failedAt
string or null
ISO 8601 time (UTC).
attemptCount
integer
timeline
array of object
timeline[].at
string
timeline[].status
string
timeline[].note
string
context
object
inReplyTo
object or null
inReplyTo.id
string
inReplyTo.direction
enum
One of OUTBOUND, INBOUND.
inReplyTo.source
enum
System: 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.
inReplyTo.channel
enum
One of EMAIL, SMS.
inReplyTo.purpose
enum
One of TRANSACTIONAL, MARKETING.
inReplyTo.status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
inReplyTo.statusReason
string or null
inReplyTo.provider
string or null
inReplyTo.toAddress
string or null
inReplyTo.fromAddress
string or null
inReplyTo.subject
string or null
inReplyTo.preview
string
The first 160 characters of the body.
inReplyTo.customerId
string or null
inReplyTo.customerName
string or null
inReplyTo.ruleId
string or null
inReplyTo.ruleName
string or null
inReplyTo.campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
inReplyTo.openedAt
string or null
First open the email provider reported.
inReplyTo.clickedAt
string or null
First click the email provider reported.
inReplyTo.subjectType
string or null
inReplyTo.subjectId
string or null
inReplyTo.scheduledFor
string
ISO 8601 time (UTC).
inReplyTo.sentAt
string or null
ISO 8601 time (UTC).
inReplyTo.createdAt
string
ISO 8601 time (UTC).
replies
array of object
replies[].id
string
replies[].direction
enum
One of OUTBOUND, INBOUND.
replies[].source
enum
System: 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.
replies[].channel
enum
One of EMAIL, SMS.
replies[].purpose
enum
One of TRANSACTIONAL, MARKETING.
replies[].status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
replies[].statusReason
string or null
replies[].provider
string or null
replies[].toAddress
string or null
replies[].fromAddress
string or null
replies[].subject
string or null
replies[].preview
string
The first 160 characters of the body.
replies[].customerId
string or null
replies[].customerName
string or null
replies[].ruleId
string or null
replies[].ruleName
string or null
replies[].campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
POST /organizations/{organizationId}/messages/send/preview
The Send dialog for a quote, an invoice (or a reminder about it), a customer's portal link or a visit reminder: who it goes to and whether consent allows it, the other addresses to choose from, and the rendered subject and body to edit. Nothing is sent, but the record's customer link (invoice or portal) is made if it does not exist yet. Then POST /messages/send.
Permission
messages.send (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
messages_previewSend (toolset marketing, in the default set)
POST /organizations/{organizationId}/messages/send
Customer-facing: sends the (possibly edited) message from POST /messages/send/preview by email or text, now, or at the end of quiet hours. Sending a draft quote marks it sent; sending a draft invoice issues it (SENT). Consent applies: no text without OK-to-text or after STOP (the answer is SKIPPED with the reason). In test mode the message is logged as SENT_TEST.
Permission
messages.send (Owner, Admin, Dispatcher)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
messages_send (toolset marketing, in the default set)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.
System: 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.
message.channel
enum
One of EMAIL, SMS.
message.purpose
enum
One of TRANSACTIONAL, MARKETING.
message.status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
message.statusReason
string or null
message.provider
string or null
message.toAddress
string or null
message.fromAddress
string or null
message.subject
string or null
message.preview
string
The first 160 characters of the body.
message.customerId
string or null
message.customerName
string or null
message.ruleId
string or null
message.ruleName
string or null
message.campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
The Inbox: one conversation per customer (else per number or email address that is nobody's), newest first, with the newest item and whether it is unread (the customer's newest item is newer than the last time anyone on the team opened it). kinds picks what counts (default TEXT): texts in which the customer texted or staff replied, emails the customer sent in, missed calls and voicemails, requests the customer made, reviews, and website chats in which the visitor wrote (CHAT: open one with GET /web-chats/{webChatId}). unread=true keeps the ones waiting. unread in the answer counts every unread conversation of those kinds. Read-only.
customer:<customerId>; phone:<+E.164> or email:<address> when it is nobody's; request:<id>, review:<id> or chat:<webChatId> for an item that names nobody (open the item itself).
items[].customerId
string or null
items[].customerName
string or null
items[].phone
string or null
The customer's number in the newest text, call or request.
items[].email
string or null
The email address, for a conversation that has one.
items[].lastMessage
object
items[].lastMessage.id
string
The message, call, request, review, ServFlo review or website chat (by kind).
items[].lastMessage.kind
enum
Text: texts. EMAIL: emails the customer sent in and staff's answers. CALL: inbound calls missed, sent to voicemail or left for a follow-up. REQUEST: requests the customer made (website, booking page, portal, AI receptionist). REVIEW: Google reviews posted since connecting, and ServFlo reviews. CHAT: website chats in which the visitor wrote (open one with GET /web-chats/{webChatId}; its id is the item's id). One of TEXT, EMAIL, CALL, REQUEST, REVIEW, CHAT.
items[].lastMessage.direction
enum
One of OUTBOUND, INBOUND.
items[].lastMessage.status
string
A text's or email's message status; a call's MISSED / VOICEMAIL / COMPLETED; a request's status; a review's UNANSWERED / ANSWERED, or FEEDBACK for a ServFlo review.
items[].lastMessage.title
string or null
An email's subject, a request's REQ-n, a Google reviewer's name, the name a chat visitor typed.
items[].lastMessage.rating
integer or null
A review's stars.
items[].lastMessage.preview
string
The first 160 characters.
items[].lastMessage.createdAt
string
items[].lastAt
string
items[].lastInboundAt
string or null
The customer's newest item (not STOP / START / HELP, not staff's answers).
items[].lastReadAt
string or null
When someone on the team last opened it.
items[].unread
boolean
The customer's newest item is newer than lastReadAt.
GET /organizations/{organizationId}/conversations/thread
One conversation, oldest first: activity holds its emails, missed calls and voicemails, requests and reviews; messages the customer's texts and the business's (automated, sent by staff, with their status: queued, deferred, sent, delivered, failed), who sent each, whether it is unread, who a reply goes to and whether consent allows it (with the reason), and whether the business can text now (texting set up, A2P approved). Does not mark it read (POST /conversations/read). Read-only.
POST /organizations/{organizationId}/conversations/read
Opening a conversation: it is read for the whole team (until the customer texts again) and the caller's own "New text from …" notifications for it are read. Changes nothing the customer sees.
POST /organizations/{organizationId}/conversations/link
A conversation with a number that is nobody's, saved to a customer: the number is added to the customer's primary contact as a mobile (unless one of their contacts has it already; no OK to text is given), and the number's texts, opt-ins and opt-outs, read state and unread "New text from …" notifications move into the customer's conversation. Create the customer first (customers.create) to save it to someone new. Texts already on another customer are not moved. Changes nothing the customer sees.
Permission
customers.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
POST /organizations/{organizationId}/conversations/reply
Customer-facing: sends a free-form text (1–1,600 characters, sent as written; no merge fields) from the business's texting number to the customer's conversation, answering their newest text (recorded as sent by the caller). It goes to the number that last texted in, else the customer's mobile. Refused with the reason: texting not set up or the A2P 10DLC registration not approved (fix in Settings → Messaging), a number that replied STOP, a number marked not to text, texts turned off for the customer, or no OK to text when the number has not texted the business in the last 30 days (answering a customer who texted counts as consent for the reply, never for marketing). An answer goes now, even in quiet hours; a text that starts a conversation waits for the end of quiet hours (DEFERRED). In test mode it is logged as SENT_TEST. Supports Idempotency-Key.
System: 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.
channel
enum
One of EMAIL, SMS.
purpose
enum
One of TRANSACTIONAL, MARKETING.
status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
statusReason
string or null
provider
string or null
toAddress
string or null
fromAddress
string or null
subject
string or null
preview
string
The first 160 characters of the body.
customerId
string or null
customerName
string or null
ruleId
string or null
ruleName
string or null
campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).
POST /organizations/{organizationId}/conversations/reply-email
Customer-facing: sends an email (1–20,000 characters of plain text, sent as written in the business's branded email) to the conversation's customer: to the address that last emailed in, else the customer's email; the subject is "Re: " the customer's newest email's. Recorded as sent by the caller. With ServFlo email the customer's answer comes back into the Inbox. Refused when there is no address, or it bounced or complained. In test mode it is logged as SENT_TEST.
System: 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.
channel
enum
One of EMAIL, SMS.
purpose
enum
One of TRANSACTIONAL, MARKETING.
status
enum
One of QUEUED, DEFERRED, SENDING, SENT, SENT_TEST, DELIVERED, FAILED, BOUNCED, SKIPPED, CANCELLED, RECEIVED.
statusReason
string or null
provider
string or null
toAddress
string or null
fromAddress
string or null
subject
string or null
preview
string
The first 160 characters of the body.
customerId
string or null
customerName
string or null
ruleId
string or null
ruleName
string or null
campaignId
string or null
The marketing campaign it belongs to (source CAMPAIGN).