Skip to main content
Tables define data storage schemas for your agent. They provide structured storage that’s automatically synced with Botpress Cloud and accessible throughout your agent.

Creating a table

Create a table definition in src/tables/:
import { Table, z } from "@botpress/runtime";

export default new Table({
  name: "PricingTable",
  columns: {
    itemName: z.string(),
    price: z.string(),
  },
});

Naming a table

To properly deploy your agent, make sure your table name follows the correct convention:
  • Must start with a letter or underscore
  • Must be 35 characters or less
  • Can contain only letters, numbers, and underscores
  • Must end with Table

Table schema

Simple definition

Define your table using Zod schemas:
export default new Table({
  name: "OrderTable",
  columns: {
    userId: z.string(),
    items: z.array(z.string()),
    total: z.number(),
    status: z.string(),
    createdAt: z.string().datetime(),
    updatedAt: z.string().datetime(),
  },
});

Extended definition

You can also define table columns with additional options for each column:
import { Table, z } from "@botpress/runtime";

export default new Table({
  name: "OrderTable",
  columns: {
    itemName: {
      schema: z.string(),
      searchable: true
    },
    price: {
      schema: z.string(),
      searchable: true
    }
  },
});
Check out the column options in the Table props reference for a full overview of the available options.

Using tables

Tables are automatically created and synced when you deploy. You can import them and interact with them directly using the table instance methods, which provide type-safe operations.

Creating rows

import OrderTable from "../tables/order-table";

const { rows } = await OrderTable.createRows({
  rows: [{ userId: "user123", total: 99.99, status: "pending" }],
});

Finding rows

const { rows: orders } = await OrderTable.findRows({
  filter: { status: "pending" },
  orderBy: "createdAt",
  orderDirection: "desc",
  limit: 10,
});

Updating rows

await OrderTable.updateRows({
  rows: [{ id: orders[0].id, status: "completed" }],
});

Getting a single row

const row = await OrderTable.getRow({ id: 42 });

Deleting rows

await OrderTable.deleteRows({ status: "cancelled" });

Upserting rows

Insert rows or update them if they match on a key column:
const { inserted, updated } = await OrderTable.upsertRows({
  keyColumn: "userId",
  rows: [{ userId: "user123", total: 149.99, status: "pending" }],
});

Filtering

Use filter operators for advanced queries:
const { rows } = await OrderTable.findRows({
  filter: {
    total: { $gt: 100 },
    status: { $in: ["pending", "processing"] },
  },
});

Available operators

OperatorDescription
$eqEqual to
$neNot equal to
$gtGreater than
$gteGreater than or equal
$ltLess than
$lteLess than or equal
$inIn array
$ninNot in array
$existsField exists
$regexRegex match

Logical operators

Combine filters with $and, $or, and $not:
const { rows } = await OrderTable.findRows({
  filter: {
    $or: [
      { status: "pending" },
      { total: { $gt: 500 } },
    ],
  },
});
Search across columns marked as searchable using natural language:
const { rows } = await TicketsTable.findRows({
  search: "VPN connection issues",
  limit: 10,
});
You can combine search with filter for hybrid queries:
const { rows } = await TicketsTable.findRows({
  search: "network problems",
  filter: { status: "open" },
  limit: 20,
});

Aggregation

Use the group parameter to perform aggregation operations:
const { rows } = await OrderTable.findRows({
  group: {
    status: "key",
    total: ["sum", "avg", "count"],
  },
});
// rows: [{ statusKey: "pending", totalSum: 500, totalAvg: 100, totalCount: 5 }, ...]

Available operations

OperationApplies toDescription
keyAll typesGroup by this value
countAll typesCount of rows
sumNumbersSum of values
avgNumbersAverage of values
maxNumbers, strings, datesMaximum value
minNumbers, strings, datesMinimum value
uniqueAll typesArray of unique values

Reference

Table props

Table methods

Tables are automatically synced with Botpress Cloud. When you deploy your agent, table schemas are created or updated to match your definitions.
Last modified on April 1, 2026