Skip to main content
Chat SDK is fully typed with TypeScript. This page documents the core types and interfaces you’ll encounter when building with the SDK.

Message Types

Author

Information about a message author.
interface Author {
  userId: string;
  userName: string;
  fullName: string;
  isBot: boolean | "unknown";
  isMe: boolean;
}
userId
string
required
Platform-specific unique user ID
userName
string
required
Username/handle for mentions
fullName
string
required
Display name
isBot
boolean | 'unknown'
required
Whether the author is a bot (or unknown if platform doesn’t provide this)
isMe
boolean
required
Whether the author is this bot instance

MessageMetadata

Message metadata like timestamps and edit status.
interface MessageMetadata {
  dateSent: Date;
  edited: boolean;
  editedAt?: Date;
}

Attachment

File or media attachment.
interface Attachment {
  type: "image" | "file" | "video" | "audio";
  url?: string;
  name?: string;
  mimeType?: string;
  size?: number;
  width?: number;
  height?: number;
  data?: Buffer | Blob;
  fetchData?: () => Promise<Buffer>;
}
type
'image' | 'file' | 'video' | 'audio'
required
Attachment type
fetchData
() => Promise<Buffer>
Function to fetch attachment data with platform authentication
Use fetchData() for private attachments that require authentication (e.g., Slack private URLs).

FileUpload

File to upload with a message.
interface FileUpload {
  filename: string;
  data: Buffer | Blob | ArrayBuffer;
  mimeType?: string;
}

Event Types

ActionEvent

Fired when a user clicks a button in a card.
interface ActionEvent<TRawMessage = unknown> {
  actionId: string;
  threadId: string;
  messageId: string;
  user: Author;
  value?: string;
  triggerId?: string;
  adapter: Adapter;
  thread: Thread<TRawMessage>;
  raw: unknown;
  openModal(modal: ModalElement | CardJSXElement): Promise<{ viewId: string } | undefined>;
}

ReactionEvent

Fired when a user adds or removes a reaction.
interface ReactionEvent<TRawMessage = unknown> {
  threadId: string;
  messageId: string;
  user: Author;
  emoji: EmojiValue;
  rawEmoji: string;
  added: boolean;
  message?: Message<TRawMessage>;
  adapter: Adapter;
  thread: Thread<TRawMessage>;
  raw: unknown;
}
emoji
EmojiValue
required
Normalized emoji as an EmojiValue singleton (enables === comparison)
rawEmoji
string
required
Platform-specific emoji string (e.g., “+1” for Slack, ”👍” for GChat)
added
boolean
required
Whether the reaction was added (true) or removed (false)

SlashCommandEvent

Fired when a user invokes a slash command.
interface SlashCommandEvent<TState = Record<string, unknown>> {
  command: string;
  text: string;
  user: Author;
  channel: Channel<TState>;
  triggerId?: string;
  adapter: Adapter;
  raw: unknown;
  openModal(modal: ModalElement | CardJSXElement): Promise<{ viewId: string } | undefined>;
}
command
string
required
The slash command (e.g., “/help”)
text
string
required
Arguments after the command

ModalSubmitEvent

Fired when a user submits a modal form.
interface ModalSubmitEvent<TRawMessage = unknown> {
  callbackId: string;
  values: Record<string, string>;
  user: Author;
  viewId: string;
  privateMetadata?: string;
  relatedThread?: Thread<Record<string, unknown>, TRawMessage>;
  relatedMessage?: SentMessage<TRawMessage>;
  relatedChannel?: Channel<Record<string, unknown>, TRawMessage>;
  adapter: Adapter;
  raw: unknown;
}
values
Record<string, string>
required
Form field values keyed by input ID
The thread where the modal was triggered (if from ActionEvent)
The message containing the button that opened the modal (if from ActionEvent)
The channel where the modal was triggered (if from SlashCommandEvent)

ModalCloseEvent

Fired when a user closes/cancels a modal (requires notifyOnClose: true).
interface ModalCloseEvent<TRawMessage = unknown> {
  callbackId: string;
  user: Author;
  viewId: string;
  privateMetadata?: string;
  relatedThread?: Thread<Record<string, unknown>, TRawMessage>;
  relatedMessage?: SentMessage<TRawMessage>;
  relatedChannel?: Channel<Record<string, unknown>, TRawMessage>;
  adapter: Adapter;
  raw: unknown;
}
Responses you can return from onModalSubmit handlers:

ModalErrorsResponse

Show validation errors on the modal.
interface ModalErrorsResponse {
  action: "errors";
  errors: Record<string, string>;
}

ModalUpdateResponse

Update the modal with new content.
interface ModalUpdateResponse {
  action: "update";
  modal: ModalElement;
}

ModalPushResponse

Push a new modal onto the stack (Slack only).
interface ModalPushResponse {
  action: "push";
  modal: ModalElement;
}

ModalCloseResponse

Close the modal.
interface ModalCloseResponse {
  action: "close";
}

Fetch Types

FetchOptions

Options for fetching messages.
interface FetchOptions {
  limit?: number;
  cursor?: string;
  direction?: "forward" | "backward";
}
limit
number
Maximum messages to fetch (default varies by adapter, typically 50-100)
cursor
string
Pagination cursor from previous FetchResult
direction
'forward' | 'backward'
  • backward (default): Fetch most recent messages. Cursor moves to older messages.
  • forward: Fetch oldest messages. Cursor moves to newer messages.

FetchResult

Result of fetching messages.
interface FetchResult<TRawMessage = unknown> {
  messages: Message<TRawMessage>[];
  nextCursor?: string;
}
Messages are always returned in chronological order (oldest first) within each page.

ThreadInfo

Thread metadata.
interface ThreadInfo {
  id: string;
  channelId: string;
  channelName?: string;
  isDM?: boolean;
  metadata: Record<string, unknown>;
}

ChannelInfo

Channel metadata.
interface ChannelInfo {
  id: string;
  name?: string;
  isDM?: boolean;
  memberCount?: number;
  metadata: Record<string, unknown>;
}

Emoji Types

EmojiValue

Immutable emoji value object with object identity.
interface EmojiValue {
  readonly name: string;
  toString(): string;
  toJSON(): string;
}
These are singleton objects - the same emoji name always returns the same frozen object instance, enabling === comparison:
if (event.emoji === emoji.thumbs_up) {
  // User gave a thumbs up!
}

WellKnownEmoji

Type union of 80+ cross-platform emoji names:
type WellKnownEmoji =
  | "thumbs_up"
  | "thumbs_down"
  | "heart"
  | "fire"
  | "rocket"
  // ... and many more
See the emoji documentation for the complete list.

EmojiFormats

Platform-specific emoji formats.
interface EmojiFormats {
  slack: string | string[];
  gchat: string | string[];
}
Example:
{
  slack: "+1",
  gchat: "👍"
}

Configuration Types

ChatConfig

Configuration for the Chat instance.
interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string, Adapter>> {
  userName: string;
  adapters: TAdapters;
  state: StateAdapter;
  logger?: Logger | LogLevel;
  dedupeTtlMs?: number;
  streamingUpdateIntervalMs?: number;
  fallbackStreamingPlaceholderText?: string | null;
}
userName
string
required
Default bot username across all adapters
adapters
Record<string, Adapter>
required
Map of adapter name to adapter instance
state
StateAdapter
required
State adapter for subscriptions and locking
dedupeTtlMs
number
default:"300000"
Message deduplication TTL in milliseconds (5 minutes)
streamingUpdateIntervalMs
number
default:"500"
Update interval for fallback streaming (post+edit) in milliseconds
fallbackStreamingPlaceholderText
string | null
default:"\"...\""
Placeholder text for fallback streaming. Set to null to wait for real text before posting.

WebhookOptions

Options for webhook handling.
interface WebhookOptions {
  waitUntil?: (task: Promise<unknown>) => void;
}
waitUntil
(task: Promise<unknown>) => void
Function to run message handling in the background (e.g., Next.js after() or Vercel Functions waitUntil)

Error Types

ChatError

Base error class for Chat SDK errors.
class ChatError extends Error {
  constructor(message: string);
}

RateLimitError

Thrown when rate limited by a platform.
class RateLimitError extends ChatError {
  constructor(message: string, public retryAfter?: number);
}
retryAfter
number
Seconds until rate limit resets (if provided by platform)

LockError

Thrown when failing to acquire a lock.
class LockError extends ChatError {
  constructor(message: string);
}

NotImplementedError

Thrown when calling an unimplemented adapter feature.
class NotImplementedError extends ChatError {
  constructor(feature: string);
}

Constants

THREAD_STATE_TTL_MS

Default TTL for thread state: 30 days in milliseconds.
const THREAD_STATE_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 2,592,000,000ms

See Also