Chat SDK reference

The API surface for @getuserfeedback/chat and @getuserfeedback/chat-react.

Last reviewed

Chat SDK reference

The Chat SDK is a headless client for user-facing conversation UIs. Use it when your app should show conversation history and let a signed-in user reply from your own UI.

If you're setting up for the first time, start with the React Chat SDK guide or JavaScript Chat SDK guide.

Packages

PackageUse it when
@getuserfeedback/chatYou want a TypeScript client for the Chat API. Works in browsers, React Native, and server-side proxy code with fetch.
@getuserfeedback/chat-reactYou want React or React Native hooks.

Authentication

Every request needs a JWT bearer token created by your app. Configure your backend or auth provider to issue a token for the signed-in user with this audience:

aud: https://getuserfeedback.com/v1/apps/{appId}sub: your user id

If your getuserfeedback.com app uses a custom JWT claim mapping, include exactly one claim that maps to userId. The examples use sub, which is the default.

Pass that token to the SDK. The SDK sends it as a bearer token:

Authorization: Bearer <token>

getuserfeedback.com verifies the token and uses the signed user id to decide which conversations the user can read or reply to.

createChatClient(options)

import { createChatClient } from "@getuserfeedback/chat";const chat = createChatClient({auth: {jwt: {token,},},});

Options

OptionTypeDefaultDescription
auth.jwt.tokenstringrequiredJWT bearer token for the current user session.
baseUrlstringhttps://api.getuserfeedback.com/v1Absolute API base URL. Custom values are used exactly.
fetchtypeof fetchglobalThis.fetchCustom fetch implementation. Required only in runtimes without global fetch.

baseUrl must be absolute. If you proxy through your backend, include the full path your proxy expects:

createChatClient({baseUrl: "https://app.example.com/api/chat/v1",auth: { jwt: { token: appSessionToken } },});

In proxy mode, auth.jwt.token is the bearer token your backend expects. Your backend should authenticate that token, then call getuserfeedback.com with a JWT minted for your getuserfeedback.com app and that user.

chat.configure(updates)

Update auth after the client has been created.

await chat.configure({auth: {jwt: {token: refreshedToken,},},});

Clear auth on logout:

await chat.configure({auth: {jwt: null,},});

After auth is cleared, SDK requests fail with missing_auth_jwt until a new token is configured.

chat.conversations.list(input?)

Lists conversations visible to the signed user.

const page = await chat.conversations.list({limit: 25,});

Input

FieldTypeDescription
limitnumberPage size. Defaults to the API default.
cursorstringCursor returned by a previous page.
signalAbortSignalOptional cancellation signal.

Response

type ChatConversationListResponse = {conversations: ChatConversation[];limit: number;nextCursor: string | null;};

chat.messages.list(input)

Lists messages in one conversation.

const page = await chat.messages.list({conversationId: "conv_123",limit: 50,});

Input

FieldTypeDescription
conversationIdstringConversation to read.
limitnumberPage size. Defaults to the API default.
cursorstringCursor returned by a previous page.
signalAbortSignalOptional cancellation signal.

Response

type ChatMessageListResponse = {conversationId: string;limit: number;messages: ChatMessage[];nextCursor: string | null;};

chat.messages.send(input)

Sends a message from the signed user into an existing conversation.

const { message } = await chat.messages.send({conversationId: "conv_123",text: "Thanks — that helps.",});

Input

FieldTypeDescription
conversationIdstringConversation to send into.
textstringMessage text, from 1 to 10,000 characters.
clientMessageIdstringOptional idempotency key for this message. Set this only when you manage send retries yourself, such as in a proxy or non-React client. Reuse the same value when retrying the same send after a timeout or lost response.
signalAbortSignalOptional cancellation signal.

Response

type ChatMessageSendResponse = {message: ChatMessage;};

Message shape

type ChatMessage = {author: "system" | "team" | "unknown" | "user";content:| { type: "text"; text: string }| { type: "flow_response"; responseId: string }| { type: "unsupported" };conversationId: string;id: string;receivedAt: string;sentAt: string;timestamp: string;};

Render unsupported with a quiet fallback. It means the conversation contains a message type this SDK version doesn't know how to display yet.

React provider

import { GetUserFeedbackChatProvider } from "@getuserfeedback/chat-react";<GetUserFeedbackChatProviderclientOptions={{auth: {jwt: {token,},},}}><App /></GetUserFeedbackChatProvider>

The provider creates the chat client and owns an in-memory store for the hooks below it. When clientOptions.auth.jwt.token changes, the provider updates auth and resets the store so the next user doesn't see the previous user's cached conversations.

Props

PropTypeDescription
clientOptionsChatClientOptionsRecommended. Provider-owned client options.
clientChatClientAdvanced. Pass an explicitly created client instead of clientOptions.

Use clientOptions.baseUrl when proxying through your backend:

<GetUserFeedbackChatProviderclientOptions={{baseUrl: "https://app.example.com/api/chat/v1",auth: { jwt: { token: appSessionToken } },}}><App /></GetUserFeedbackChatProvider>

useConversationList(options?)

Loads conversations on mount by default.

const { conversations, error, hasMore, loadMore, refresh, status } =useConversationList({ limit: 25 });

Options

FieldTypeDefaultDescription
enabledbooleantrueSet to false to disable the first load.
limitnumber25Page size for the initial load and pagination.

Return value

FieldDescription
conversationsLoaded conversations.
statusLoad state for the list.
errorLast load error, if any.
hasMoretrue when another page is available.
loadMore()Loads the next page.
refresh()Reloads the first page.

useConversation(options)

Loads one conversation's messages on mount by default.

const {error,hasMore,loadMore,messages,refresh,send,sendError,sendStatus,status,} = useConversation({ conversationId: "conv_123" });

Options

FieldTypeDefaultDescription
conversationIdstringrequiredConversation to read and send into.
enabledbooleantrueSet to false to disable the first load.
limitnumber50Page size for the initial load and pagination.

Return value

FieldDescription
messagesLoaded messages.
statusLoad state for messages.
errorLast message load error, if any.
hasMoretrue when older messages are available.
loadMore()Loads older messages.
refresh()Reloads the first page.
send({ text })Sends a message and returns the saved message.
sendStatusCurrent send state.
sendErrorLast send error, if any.

Errors

Failed API responses throw ChatApiError.

import { ChatApiError } from "@getuserfeedback/chat";try {await chat.conversations.list();} catch (error) {if (error instanceof ChatApiError) {console.log(error.status, error.code, error.message);}}

Common codes:

CodeMeaning
missing_auth_jwtThe client has no configured JWT.
identity_missingThe verified JWT did not include a signed userId identity.
identity_ambiguousThe verified JWT mapped to more than one signed userId.
invalid_cursorThe pagination cursor is malformed or belongs to a different request.
not_foundThe conversation does not exist or does not belong to the signed user.

Current limits

  • You can list conversations and send messages into them.
  • Realtime updates, typing indicators, and read receipts are not exposed in the SDK yet.