Bot

Bots are core entities in the Botpress system, but they aren’t accessible through the Runtime API directly. Instead, they’re managed via the Admin API. Bots are software applications that handle events and messages, responding or acting on them accordingly.

Integration

Integrations connect Botpress to external services. Like bots, they’re not directly accessible from the Runtime API but are managed through the Admin API. Integrations handle the sending and receiving of messages, events, and data between Botpress and third-party services. They’re defined and managed in the Botpress Admin API.

Definitions and Instances

Two categories of objects exist in the Botpress Runtime API: definitions and instances. Each concept listed below is first defined when deploying the integration or bot and then instantiated during the bot or integration execution.

Message

Messages, just like in any messaging system are entities that carry information between multiple speakers in a conversation. Integrations define message types and their payload schemas.

Message instances represent actual messages exchanged with the bot or integration. They must conform to the schema defined for their message type by the Integration. Here’s the TypeScript representation of a message:

type Message = {
  id: string;
  createdAt: string;
  type: string;
  payload: { [k: string]: any };
  direction: "incoming" | "outgoing";
  userId: string;
  conversationId: string;
  tags: { [k: string]: string };
}

Direction

Each message has a direction indicating its source:

  • Incoming: Originates from an external service (e.g., WhatsApp) and is passed into the Runtime API via the integration.
  • Outgoing: Generated by the bot and sent to an external service via the integration.

This distinction helps determine whether the message was created by the integration or the bot.

User and Conversation ID

Messages are always part of a conversation and are associated with a user. Bots are considered users too. The userId and conversationId track the sender and the conversation context.

Tags

Tags are key-value pairs used to attach metadata to messages. Only tags defined by the Integration or Bot are permitted. See Tags for more.

Built-in Message Types

Botpress enforces a set of built-in message types that must be supported by integrations:

  • text A plain text message.
  • image An image message.
  • audio An audio message.
  • video A video message.
  • file A file message.
  • location A message indicating a location with a latitude and longitude.
  • carousel A message containing a carousel of card.
  • card A message containing an image and a button.
  • dropdown A message containing a dropdown with options.
  • choice A message containing a choice with options.
  • bloc A composite message that can contain multiple message types.

Here’s the TypeScript representation of each of these message’s payload:

type Text = { text: string }
type Image = { imageUrl: string }
type Audio = { audioUrl: string }
type Video = { videoUrl: string }
type File = {
  fileUrl: string
  title?: string
}
type Location = {
  latitude: number
  longitude: number
  address?: string
  title?: string
}

type Card = {
  title: string
  subtitle?: string
  imageUrl?: string
  actions: {
    action: 'postback' | 'url' | 'say'
    label: string
    value: string
  }[]
}

type Choice = {
  text: string
  options: {
    label: string
    value: string
  }[]
}

type Carousel = {
  items: Card[]
}

type Bloc = {
  items:
    | { type: 'text'; payload: Text }
    | { type: 'image'; payload: Image }
    | { type: 'audio'; payload: Audio }
    | { type: 'video'; payload: Video }
    | { type: 'file'; payload: File }
    | { type: 'location'; payload: Location }
}

When an integration is deployed, it can defined any message type, but can’t override any of the builtin message types with a breaking schema. This means that if an integration defines a message of type text, the payload must be compatible with { text: string; }. In other words, it can add type constraints like new properties to the payload, but it can not remove them.

Conversation

A conversation represents the interaction of multiple speakers sending messages. Here’s the TypeScript type for a conversation:

type Conversation = {
  id: string;
  createdAt: string;
  updatedAt: string;
  channel: string;
  integration: string;
  tags: { [k: string]: string };
}

Tags

Conversations support tags to store metadata. These tags must be defined in the integration or bot definition. See Tags for more.

Channel

A conversation belongs to a channel, which itself is part of an integration. For example, a GitHub integration might support messaging via issues and pull requests—each of those would be a separate channel. A conversation always occurs on a specific channel of a specific integration.

User

A user in the Runtime API is a speaker (person or entity) that can send messages in a conversation. Just like conversations, users belong to a specific integration. Interracting with your bot on WhatsApp and Slack will create two different users, even if they both represent the same person with the same email.

Many different kind of users exist in the whole Botpress system. This concept only refer to users of the Runtime API or as we often refer to: Chat Users. It must not be confused with users of the Botpress Admin API which are bot and integration Builders.

Here’s the user type:

type User = {
  id: string;
  createdAt: string;
  updatedAt: string;
  name?: string;
  pictureUrl?: string;
  tags: { [k: string]: string };
}

Tags

User tags provide metadata and must be defined in the integration or bot definition. See Tags for more.

Name and Picture URL

The name and pictureUrl fields are optional and useful for UI or debugging purposes but are not required for bot functionality.

Event

Events are another core unit of the Runtime API. Integrations and Bots define event types and payload schemas. Event instances represent real events triggered during execution.

type Event = {
  id: string;
  createdAt: string;
  type: string;
  payload: { [k: string]: any };
  conversationId?: string;
  userId?: string;
  messageId?: string;
  status: "pending" | "processed" | "ignored" | "failed" | "scheduled";
  failureReason: string | null;
}

Direction

Unlike messages, events have no direction. They are always consired incoming. This is because they are always sent to the Bot, by either an integration or the bot itself. You may send an event to your bot by an external calls to the Runtime API, but doing so, still requires you to authenticate as either a bot or an integration.

Associated IDs

Events can be linked to a conversation, user, or message via their respective IDs. These are optional but helpful for tracking or analytics.

Status

When an event is created via the Runtime API, it’s placed in a queue. The bot processes it asynchronously. The status field shows its current processing state.

State

State is a key-value store for persisting data related to a conversation, user, or other context. Payloads must match the schema defined by the integration or bot.

type State = {
  id: string;
  createdAt: string;
  updatedAt: string;
  botId: string;
  conversationId?: string;
  userId?: string;
  name: string;
  type: "conversation" | "user" | "bot" | "integration" | "workflow";
  payload: { [k: string]: any };
}

State Names

Each state is identified by a name. Bots or integrations can define multiple state types under different names.

State Types

The type indicates what kind of entity the state belongs to. The integration type is a misnomer and should be treated as a bot type.

Tags

Tags store string-based metadata for messages, users, and conversations. They’re defined by the integration or bot and allow filtering, analytics, or custom logic.

type Tag = {
  id: string;
  createdAt: string;
  updatedAt: string;
  type: "user" | "conversation" | "message";
  key: string;
  value: string;
}

Tags are defined by the integration or bot and can be used to store any additional information that is not covered by the other properties of the message, user, or conversation objects. Tags are key-value pairs, where both the key and value are strings. The type property indicates whether the tag is associated with a user, conversation, or message. It can be used later to filter or search user, conversation, or message objects based on their tags.

Unlike States, Tags are returned with the entity they are linked to. States can be bigger, but must be fetched separately. Also, tags are always string, while states can be any JSON object with a schema defined in the integration or bot definition.

Actions

Both bots and integrations can define actions which are functions with a specific signature. Both integration and bot actions are meant to be called by the bot itself. You may call an action by running an external call to the Runtime API, but doing so, still requires you to authenticate as either a bot. Actions appear as cards in Botpress Studio and are a core way to execute dynamic logic.

What’s Next

Now that API concepts are clear, you can explore the API reference.