Chat API

The Chat API powers the FloatMessage live chat widget. It handles widget configuration, visitor management, messaging, and real-time updates via Server-Sent Events.

GET/api/chat/config?userId={userId}

Public endpoint that returns the chat widget configuration for a given user. Called by the embedded chat script to initialize the widget on the client’s site.

Query Parameters

ParameterTypeDescription
userIdstringRequired. The FloatMessage user/account ID.

Headers Checked

CF-IPCountry — Server-side geo check. If the chat widget is restricted to specific countries, the visitor’s country is validated before returning the config.

Response 200

{
  "enabled": true,
  "welcomeMessage": "Hi there! How can we help?",
  "offlineMessage": "We're currently offline. Leave a message!",
  "position": "BOTTOM_RIGHT",
  "primaryColor": "#6366f1",
  "collectName": true,
  "collectEmail": true,
  "clientDataPaths": ["/support", "/pricing"],
  "schedule": {
    "days": [1, 2, 3, 4, 5],
    "timeStart": "09:00",
    "timeEnd": "18:00",
    "timezone": "America/New_York"
  },
  "dismiss": {
    "behavior": "SESSION",
    "duration": null
  },
  "showDelay": 2000,
  "autoHideDelay": null,
  "customX": 100,
  "customY": 50,
  "jsApiEnabled": true
}

Response Fields

FieldTypeDescription
enabledbooleanWhether the chat widget is active.
welcomeMessagestringGreeting shown when the widget opens.
offlineMessagestringMessage shown outside scheduled hours.
positionstringWidget position on screen.
primaryColorstringHex color for the widget theme.
collectNamebooleanWhether to ask for visitor name.
collectEmailbooleanWhether to ask for visitor email.
clientDataPathsstring[]URL paths where the widget should appear. Empty means all pages.
scheduleobjectOnline hours schedule with days, time range, and timezone.
dismissobjectDismiss behavior and duration settings.
showDelaynumber | nullMilliseconds before the widget appears on page load.
autoHideDelaynumber | nullMilliseconds before the widget auto-hides, or null to stay visible.
customXnumber | nullCustom X position in pixels from left edge. Overrides position preset.
customYnumber | nullCustom Y position in pixels from bottom edge. Overrides position preset.
jsApiEnabledbooleanWhether the JavaScript API (window.FloatMessage) is exposed.

CORS

Access-Control-Allow-Origin: *

POST/api/chat/visitor

Creates a new visitor or retrieves an existing one by token. Used by the chat widget to establish a visitor identity for the conversation.

Request Body

{
  "userId": "user_abc123",
  "visitorToken": "vt_existing_token_or_null",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "pageUrl": "https://example.com/pricing",
  "userAgent": "Mozilla/5.0 ...",
  "customData": {
    "plan": "pro",
    "companySize": "50-100"
  }
}

Body Fields

FieldTypeDescription
userIdstringRequired. The FloatMessage account ID.
visitorTokenstring | nullExisting token to resume a visitor session, or null to create a new one.
namestring | undefinedOptional. Visitor display name.
emailstring | undefinedOptional. Visitor email address.
pageUrlstring | undefinedOptional. URL of the page the visitor is on.
userAgentstring | undefinedOptional. Browser user agent string.
customDataobject | undefinedOptional. Arbitrary key-value data attached to the visitor.

Response 200

{
  "visitor": {
    "id": "vis_abc123",
    "token": "vt_generated_token",
    "name": "Jane Doe",
    "email": "jane@example.com"
  },
  "conversationId": "conv_xyz789"
}

GET/api/chat/messages?conversationId={id}

Returns all messages for a given conversation, ordered chronologically.

Query Parameters

ParameterTypeDescription
conversationIdstringRequired. The conversation ID to fetch messages for.

Response 200

[
  {
    "id": "msg_001",
    "conversationId": "conv_xyz789",
    "content": "Hi, I need help with pricing.",
    "senderType": "VISITOR",
    "createdAt": "2026-03-23T10:00:00.000Z"
  },
  {
    "id": "msg_002",
    "conversationId": "conv_xyz789",
    "content": "Sure! What plan are you looking at?",
    "senderType": "AGENT",
    "createdAt": "2026-03-23T10:01:30.000Z"
  }
]

POST/api/chat/messages

Sends a new message in a conversation. Can be sent by either a visitor or an agent.

Request Body

{
  "conversationId": "conv_xyz789",
  "content": "Hello, I have a question about my account.",
  "senderType": "VISITOR"
}

Body Fields

FieldTypeDescription
conversationIdstringRequired. The conversation to send the message in.
contentstringRequired. The message text.
senderTypestringRequired. VISITOR or AGENT.

Response 201

{
  "id": "msg_003",
  "conversationId": "conv_xyz789",
  "content": "Hello, I have a question about my account.",
  "senderType": "VISITOR",
  "createdAt": "2026-03-23T10:05:00.000Z"
}

GET/api/chat/sse

Opens a Server-Sent Events (SSE) stream for real-time updates. The chat widget uses this connection to receive new messages, typing indicators, and status changes without polling.

Connection

const eventSource = new EventSource("/api/chat/sse?conversationId=conv_xyz789");

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log(data);
};

Event Format

data: {
  "type": "message",
  "payload": {
    "id": "msg_004",
    "content": "Thanks for your patience!",
    "senderType": "AGENT",
    "createdAt": "2026-03-23T10:06:00.000Z"
  }
}

Response Headers

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

The stream stays open until the client disconnects. The server sends periodic keep-alive pings to prevent timeouts.

POST/api/chat/presence

Visitor heartbeat endpoint. Updates the visitor's last-seen timestamp and returns new messages since the given time. Also returns a typing indicator hint.

Request Headers

X-Visitor-Token: vt_abc123

Request Body

{
  "conversationId": "conv_xyz789",
  "since": "2026-03-23T10:00:00.000Z"
}

Response 200

{
  "ok": true,
  "messages": [],
  "typing": true
}

Response Fields

FieldTypeDescription
okbooleanAlways true on success.
messagesarrayNew messages since the given timestamp.
typingbooleanTrue when the last message in the conversation was from the visitor (reply is pending). Used to show typing indicator.