DevelopersAPI reference

Team chat API

REST endpoints for team chat in ServFlo: 8 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.

OperationEndpointRisk
What's waiting for me (badge counts)GET /organizations/{organizationId}/badgesread
My conversationsGET /organizations/{organizationId}/chatread
Who I can messageGET /organizations/{organizationId}/chat/peopleread
Open a direct messagePOST /organizations/{organizationId}/chat/directwrite
Open a job's conversationPOST /organizations/{organizationId}/jobs/{jobId}/chatwrite
A conversation's messagesGET /organizations/{organizationId}/chat/{conversationId}/messagesread
Write in a conversationPOST /organizations/{organizationId}/chat/{conversationId}/messageswrite
Mark a conversation readPOST /organizations/{organizationId}/chat/{conversationId}/readwrite

What's waiting for me (badge counts)

GET /organizations/{organizationId}/badges

The counts behind the red badges in the web and mobile apps: unread team chat messages (and which conversations), unread notifications, customers' texts waiting (messages: unread customer-text notifications, engagement.read), unread Inbox conversations (inboxUnread, engagement.read), and for the office what waits in the inbox: new requests and technicians' leads (requests.read), parts requests not yet handled (inventory.manage), technicians with time waiting for approval (timesheets.approve). Counts the caller may not see are 0. Read-only.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolchat_badges (toolset team)

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/badges" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
chatinteger
chatConversationsarray of string
notificationsinteger
messagesintegerUnread customer-text notifications in this business; already counted in notifications.
inboxUnreadintegerInbox conversations nobody on the team has opened since the customer's newest text, email, missed call, request or review (inbox.read; a technician's own line, read by them): the Inbox badge.
inboxobject
inbox.requestsinteger
inbox.partsinteger
inbox.timesheetsinteger
inbox.totalinteger
totalintegerchat + notifications + inbox.total: the app icon's badge.

My conversations

GET /organizations/{organizationId}/chat

The caller's team chat, most recent first: the whole team, their direct messages and job conversations (a technician's own jobs; for the office every job with messages in the last 30 days), each with a title, the last message and the caller's unread count. Read-only.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolchat_conversations (toolset team)

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstringConversation id (for …/chat/{conversationId}/messages).
kindenumOne of TEAM, DIRECT, JOB.
jobIdstring or nullThe job a JOB conversation is about.
titlestringTeam, the other person's name, or JOB-n · customer.
lastMessageobject or nullThe latest message (first 200 characters).
lastMessage.bodystring
lastMessage.authorstring
lastMessage.atstring (date-time)
unreadintegerMessages from others since the caller last read it.

Who I can message

GET /organizations/{organizationId}/chat/people

The business's members (name and role) to start a direct message with; not the caller. Read-only.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolchat_people (toolset team)

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat/people" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
userIdstringThe member's user id (for POST /chat/direct).
namestring
rolestring

Open a direct message

POST /organizations/{organizationId}/chat/direct

The caller's conversation with another member of the business (made on first use). 404 for someone who isn't a member.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolchat_openDirect (toolset team)

Request body

FieldTypeRequiredDescription
userIdstringYesUp to 200 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat/direct" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"userId":"user_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
kindenumOne of TEAM, DIRECT, JOB.
jobIdstring or null

Open a job's conversation

POST /organizations/{organizationId}/jobs/{jobId}/chat

The conversation about a job: its crew and the office (made on first use). Technicians: their own jobs (404 otherwise).

Permission: jobs.read (Owner, Admin, Dispatcher, Technician (own jobs), Member); risk write (OAuth scope servflo.write).

Permissionjobs.read
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolchat_openJob (toolset team)

Parameters

NameInTypeRequiredDescription
jobIdpathstringYes

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/jobs/{jobId}/chat" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
kindenumOne of TEAM, DIRECT, JOB.
jobIdstring or null

A conversation's messages

GET /organizations/{organizationId}/chat/{conversationId}/messages

The latest messages, oldest first (before for older ones), with who wrote each. 404 for a conversation the caller can't see. Read-only.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolchat_messages (toolset team)

Parameters

NameInTypeRequiredDescription
conversationIdpathstringYes
beforequerystring (date-time)No
limitqueryintegerNo1–100.

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat/{conversationId}/messages" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstring
userIdstringThe author's user id.
bodystring
createdAtstring (date-time)
authorstringThe author's name.
minebooleanSent by the caller.

Write in a conversation

POST /organizations/{organizationId}/chat/{conversationId}/messages

Posts a message (up to 4000 characters); the others in the conversation are told on their phones. Returns it.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolchat_send (toolset team)

Parameters

NameInTypeRequiredDescription
conversationIdpathstringYes

Request body

FieldTypeRequiredDescription
bodystringYesUp to 4000 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat/{conversationId}/messages" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"string"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
userIdstringThe author's user id.
bodystring
createdAtstring (date-time)
minebooleanSent by the caller.

Mark a conversation read

POST /organizations/{organizationId}/chat/{conversationId}/read

Everything in it up to now counts as read for the caller.

Permissionorganization.read (Owner, Admin, Dispatcher, Technician, Member)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolchat_read (toolset team)

Parameters

NameInTypeRequiredDescription
conversationIdpathstringYes

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/chat/{conversationId}/read" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue

On this page