# Lists

The methods in this section create and delete [lists](https://support.watbot.org/lists), change their fields and manage records: add, read, update and delete them. For example, your website can keep a "Coffee shop menu" list up to date, and the bot shows it to people.

## How a list is structured

A list has two parts:

- **The schema** — the list's name and its fields. The methods on the [Lists and fields](https://support.watbot.org/api/lists/schemas) page work with it. Method names call it exactly that: `getListSchema`, `createListSchema`.
- **Records** — the rows of the list with field values. The methods on the [Records](https://support.watbot.org/api/lists/items) page work with them.

Lists belong to a project. A list can be created in a project or in a bot — in that case it also goes to the project of that bot. The API gives access to all lists in the projects owned by the key holder: both those created in bots and those created directly in the project.

## Identifiers

| What | What it looks like | Where to get it |
|---|---|---|
| List (`schema_id`, `id` in responses) | A 24-character string: `6650a1f2c3d4e5f6a7b8c9d0` | Responses of `getListSchemas` and `createListSchema` |
| Record (`item_id`, `id` in responses) | A 24-character string, like a list's | Responses of `getListItems` and `addListItem` |
| Field (`slug`) | Letters, digits, `-` and `_`, preferably Latin: `price` | Keys of the `fields` object in the `getListSchema` response |
| Project (`project_uuid`, `project` in responses) | A UUID: `3f2b8c1e-…` | The project's address in your account: `/projects/<uuid>/…` |
| Bot (`bot_id`) | A number | The bot's address in your account: `/bots/12345/…` |
| Contact | A number | The contact methods |

The `slug` is [the field's name in templates](https://support.watbot.org/lists/create#the-fields-name-in-templates): the value is stored in the record under it, and the bot's blocks read it by the same name. Fields created in your account get it automatically; through the API you set it yourself.

## Field types

The type is set in the `type` parameter when the field is created and cannot be changed later.

| `type` | Type in your account | What to send | What comes back |
|---|---|---|---|
| `string` | "Text" | A string | A string |
| `number` | "Number" | A number or a string with a number: `12`, `"4.5"` | A number |
| `bool` | "Yes/No" | `true` or `false` (`1` and `0` work too) | `true` or `false` |
| `date` | "Date" | A date in any common format: `"2026-10-15"` | A date and time in UTC: `"2026-10-15T00:00:00.000000Z"` |
| `datetime` | "Date and time" | A date and time: `"2026-10-15 14:30"` or `"2026-10-15T14:30:00-05:00"` | A date and time in UTC |
| `money` | "Money" | An amount in dollars, euros, etc.: `4.5` or `12.99` | The amount in the same units: `4.5` |
| `file` | "File" | An object with a link — see below | An object describing the file |
| `image` | "Image" | An object with a link — see below | An object describing the file |
| `contact` | "Contact ID" | A contact ID | The contact ID |
| `bot` | "Bot ID" | A bot ID | The bot ID |

An empty field comes back as `null`.

### Date and time

A time without a time zone is treated as UTC: `"2026-10-15 14:30"` is saved as 14:30 UTC. To send local time, add the offset: `"2026-10-15T14:30:00-05:00"`. A `date` field does not cut off the time: if you send a date with a time, the time is kept.

### Money

The currency is set on the field when the field is created (`currency`) and is not sent with records. It is a three-letter ISO 4217 code: `USD`, `EUR`, `GBP`. In `createListSchema` the currency can be omitted — then it is `USD`; in `addListSchemaField` it is required. An unknown code — `422`.

Send amounts in main units — dollars, not cents. An amount is rounded to the currency's decimal places (two for the dollar and the euro), halves rounded up: `0.295` is saved as `0.30`.

### Files and images

The value of a `file` or `image` field is an object. Through the API you can only store a link to a file that is available on the internet:

```json
{
  "url": "https://example.com/menu/cappuccino.jpg",
  "storage": "url",
  "name": "cappuccino.jpg",
  "type": "image"
}
```

| Key | Required | Description |
|---|---|---|
| `url` | yes | An `http://` or `https://` link |
| `storage` | yes | Always `"url"` |
| `name` | no | File name |
| `type` | no | Kind of file: `image`, `video`, `audio` or `document` |
| `mime_type` | no | MIME type: `image/jpeg` |
| `size` | no | Size in bytes |
| `caption` | no | Caption |

> [!WARNING]
> Without `"storage": "url"`, or with a link of another kind (not `http`/`https`), the value is silently not saved — the field ends up `null`, and there is no error.

Other keys (such as `uuid` or `path`) are ignored: the field stores only the external link, and the response returns it exactly as you sent it. A link to a file in the platform's storage — the kind that responses contain for files uploaded in your account — can only be stored within your own account; a link to another account's file is not saved, and the field ends up `null`. If you send `updateListItem` the file that is already in the record, for example a whole record from `getListItems`, it stays as it was.

In responses, a file is described by an object with the keys `type`, `mime_type`, `created_at`, `name`, `size`, `storage`, `caption`, `meta` (width, height, duration, codec) and `url`. Links to files uploaded in your account are temporary: download the file right away or request the record again.

### Contact and bot

`contact` and `bot` fields take an ID. The contact must belong to your bot and the bot must be yours, otherwise the response is `403`. An ID that does not exist fails validation — `422`.

Besides the value of the field itself, the record gets the service keys `contact_id` or `bot_id` — the filter in [`getListItems`](10-items.md#getlistitems) works on them. If a list has several such fields, they hold the value of the last one.

## Field settings

| Parameter | Type | Default | Description |
|---|---|---|---|
| `is_required` | boolean | `true` | "Required field": a record without a value is not added |
| `is_hidden` | boolean | `false` | "Hide field from interface": the field is not shown in the table of records in your account. The API returns it as usual |
| `is_encryptable` | boolean | `false` | "Encrypt field": the value is stored encrypted. The API returns it decrypted. In your account encryption exists only for the `string` and `number` types — use it only for them. Filters do not work on encrypted fields |

> [!IMPORTANT]
> By default, a field created through the API is required — unlike in your account. If a field may stay empty, send `"is_required": false`.

## Limits

- Up to 5000 lists per project.
- From 1 to 30 fields when a list is created.
- List and field names — up to 255 characters.
- Service field names cannot be used: `id`, `_id`, `contact`, `contact_id`, `bot`, `bot_id`, `user`, `user_id`, `project`, `project_id`, `data`, `schema_id`, `created_at`, `updated_at`, `deleted_at` and any name starting with `__`. For such a `slug` the API responds with `422` and the text "The slug is reserved.".

General rules — the key, request rate, error codes — are described on the [API](https://support.watbot.org/api#errors) page.

## Methods

| Method | What it does |
|---|---|
| [`getListSchemas`](05-schemas.md#getlistschemas) | All lists of your projects |
| [`getListSchema`](05-schemas.md#getlistschema) | One list with its fields |
| [`createListSchema`](05-schemas.md#createlistschema) | Create a list |
| [`deleteListSchema`](05-schemas.md#deletelistschema) | Delete a list |
| [`addListSchemaField`](05-schemas.md#addlistschemafield) | Add a field |
| [`deleteListSchemaField`](05-schemas.md#deletelistschemafield) | Delete a field |
| [`getListItems`](10-items.md#getlistitems) | Records of a list with filtering and sorting |
| [`addListItem`](10-items.md#addlistitem) | Add a record |
| [`updateListItem`](10-items.md#updatelistitem) | Update a record |
| [`deleteListItem`](10-items.md#deletelistitem) | Delete a record |
