# Records

The methods on this page work with list records. Field values are sent in the `data` object: the key is the field's `slug`, the value is in the format of its type. The formats of all types are described on the [Lists](https://support.watbot.org/api/lists#field-types) page.

## getListItems

Returns the records of a list page by page — with filtering by field values and sorting.

```endpoint
GET POST https://watbot.org/api/v1/getListItems
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `schema_id` | string | yes | List ID |
| `limit` | integer | no | Records per page — from 1 to 1000, 50 by default |
| `page` | integer | no | Page number, `1` by default |
| `order_by` | string | no | Sorting: the field's `slug` and the direction separated by a comma — `price,desc`. The direction is `asc` (ascending, the default) or `desc`. You can also sort by `created_at` and `updated_at`. Any other field or direction — `422` |
| `filters` | object | no | Filtering by field values — see below |
| `contact_id` | integer | no | Only records linked to this contact through a `contact` field |
| `bot_id` | integer | no | Only records linked to this bot through a `bot` field |

For example, lattes of 12 oz and more, largest first:

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/getListItems" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "schema_id": "6650a1f2c3d4e5f6a7b8c9d0",
    "filters": {"volume": ">=,12", "title": "like,%latte%"},
    "order_by": "volume,desc",
    "limit": 20
  }'
```

```json title="Response 200"
{
  "data": [
    {
      "id": "6650b7a1c3d4e5f6a7b8c9e1",
      "created_at": "2026-10-03T08:05:00+00:00",
      "updated_at": "2026-10-03T08:05:00+00:00",
      "title": "Oat milk latte",
      "price": 5.25,
      "photo": {
        "type": "image",
        "mime_type": "image/jpeg",
        "created_at": null,
        "name": "latte.jpg",
        "size": 0,
        "storage": "url",
        "caption": null,
        "meta": {"width": null, "height": null, "duration": null, "codec": null},
        "url": "https://example.com/menu/latte.jpg"
      },
      "in_stock": true,
      "volume": 16
    }
  ],
  "links": {
    "first": "…/v1/getListItems?page=1",
    "last": "…/v1/getListItems?page=1",
    "prev": null,
    "next": null
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "path": "…/v1/getListItems",
    "per_page": 20,
    "to": 1,
    "total": 1
  }
}
```

```json title="Response 422"
{
  "message": "The limit field must not be greater than 1000.",
  "errors": {
    "limit": ["The limit field must not be greater than 1000."]
  }
}
```

Each record contains `id`, `created_at`, `updated_at` and the values of all list fields, including hidden and encrypted ones (decrypted). If a record is linked to a contact or a bot, it also has `contact_id` or `bot_id`.

### Filtering

In `filters`, the key is the field's `slug` and the value is one of:

- `"value"` or just a JSON value — the field equals the value: `{"title": "Cappuccino"}`, `{"volume": 12}`, `{"in_stock": true}`;
- `"operator,value"` — a comparison: `{"volume": ">=,12"}`.

| Operator | Meaning |
|---|---|
| `=` | equals |
| `!=`, `<>` | not equal |
| `<`, `<=`, `>`, `>=` | less than, less than or equal, greater than, greater than or equal |
| `like` | matches a pattern: `%` — any characters, `_` — one character. Case does not matter. Without `%`, the whole value must match |
| `not like` | does not match a pattern |

An operator is recognized only if the text before the first comma is an operator from the table. Otherwise the whole string is the value: `{"title": "Flat white, large"}` finds the record "Flat white, large". If the value itself starts with an operator and a comma, such as `">, 5"`, set the operator explicitly: `"=,>, 5"`.

Conditions on different fields are combined with "and".

How the value is compared depends on the field type:

| Field type | Filter value | Operators |
|---|---|---|
| `string` | Text. A JSON number is compared as text | all |
| `number` | A number: `12`, `"12"`, `"4.5"` | all except `like` and `not like` |
| `money` | An amount in main units, as when writing: `5` or `"4.99"` | all except `like` and `not like` |
| `bool` | `true`, `false`, `"true"`, `"false"`, `1`, `0` | `=`, `!=` |
| `date` | A date: `"2026-10-15"`. The day is compared in UTC: `"2026-10-15"` also finds a record dated October 15, 14:30, and `"<=,2026-10-15"` finds everything up to the end of that day | all except `like` and `not like` |
| `datetime` | A date and time: `"2026-10-15 14:30"` or `"2026-10-15T14:30:00+03:00"`. Time without a time zone is UTC | all except `like` and `not like` |
| `contact`, `bot` | A contact or bot ID | all except `like` and `not like` |

A `like` or `not like` pattern can be up to 255 characters long with at most 10 `%` signs; several `%` in a row count as one.

A value that does not suit the field (text in a `number` field, `like` on an amount, an object instead of a value) — `422` with an error on `filters.<slug>`. If `filters` is not an object, the error is on `filters`.

A condition is skipped without an error if the list has no field with this `slug`, the field is encrypted, it is a file or an image, or the value is `null`.

In a `GET` request, filters are passed in the address: `filters[volume]=>=,12`. Encode special characters: `%` as `%25`.

### Pages

The total number of records and pages is in `meta.total` and `meta.last_page`, the address of the next page is in `links.next` (`null` on the last one). Without `order_by` the order of records is not defined: when going through pages, set a sort order, for example `created_at`.

Errors:

- The list does not exist — `404`: `{"message": "Schema not found", "error": "Schema not found", "errors": {"schema_id": ["Schema not found"]}}`.
- The list belongs to someone else's project — `403`.
- Invalid `order_by` or `filters` — `422`.

## addListItem

Adds a record to a list.

```endpoint
GET POST https://watbot.org/api/v1/addListItem
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `schema_id` | string | yes | List ID |
| `data` | object | yes | Field values: the key is the `slug`, the value is in the format of the field type |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/addListItem" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "schema_id": "6650a1f2c3d4e5f6a7b8c9d0",
    "data": {
      "title": "Cappuccino",
      "price": 4.5,
      "photo": {
        "url": "https://example.com/menu/cappuccino.jpg",
        "storage": "url",
        "name": "cappuccino.jpg",
        "type": "image"
      },
      "in_stock": true,
      "volume": 12
    }
  }'
```

```json title="Response 201"
{
  "data": {
    "id": "6650b7a1c3d4e5f6a7b8c9e2",
    "created_at": "2026-10-03T08:10:00+00:00",
    "updated_at": "2026-10-03T08:10:00+00:00",
    "title": "Cappuccino",
    "price": 4.5,
    "photo": {
      "type": "image",
      "mime_type": null,
      "created_at": null,
      "name": "cappuccino.jpg",
      "size": 0,
      "storage": "url",
      "caption": null,
      "meta": {"width": null, "height": null, "duration": null, "codec": null},
      "url": "https://example.com/menu/cappuccino.jpg"
    },
    "in_stock": true,
    "volume": 12
  }
}
```

```json title="Response 422"
{
  "message": "The data.title field is required.",
  "errors": {
    "data.title": ["The data.title field is required."]
  }
}
```

Notes and errors:

- Required fields (`is_required: true`) must be filled, otherwise `422`. Fields missing from `data` stay empty. Keys that are not fields of the list are ignored.
- A value of the wrong type — `422` with an error on `data.<slug>`: for example, text in a `number` field or a contact ID that does not exist.
- Someone else's contact or bot in `contact` and `bot` fields — `403`.
- Dates in the response are strings in UTC, as in `getListItems`: `"2026-10-15T00:00:00.000000Z"`.
- The list does not exist — `404`, as in `getListItems`; the list belongs to someone else's project — `403`.

## updateListItem

Changes the field values of a record. Fields missing from `data` do not change.

```endpoint
GET POST https://watbot.org/api/v1/updateListItem
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `item_id` | string | yes | Record ID |
| `data` | object | yes | New field values: the key is the `slug`, the value is in the format of the field type |

For example, a new price and the "out of stock" mark:

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/updateListItem" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": "6650b7a1c3d4e5f6a7b8c9e2",
    "data": {"price": 4.75, "in_stock": false}
  }'
```

```json title="Response 200"
{
  "data": {
    "id": "6650b7a1c3d4e5f6a7b8c9e2",
    "created_at": "2026-10-03T08:10:00+00:00",
    "updated_at": "2026-10-03T09:30:00+00:00",
    "title": "Cappuccino",
    "price": 4.75,
    "photo": {
      "type": "image",
      "mime_type": null,
      "created_at": null,
      "name": "cappuccino.jpg",
      "size": 0,
      "storage": "url",
      "caption": null,
      "meta": {"width": null, "height": null, "duration": null, "codec": null},
      "url": "https://example.com/menu/cappuccino.jpg"
    },
    "in_stock": false,
    "volume": 12
  }
}
```

```json title="Response 404"
{
  "message": "Item not found",
  "error": "Item not found",
  "errors": {
    "item_id": ["Item not found"]
  }
}
```

The response contains the whole record.

Notes and errors:

- Only the fields you send are validated. A required field cannot be sent empty — `422`.
- This method cannot clear a field: `null` and empty values are skipped, and the field keeps its previous value.
- Dates in the response are strings in UTC, as in `getListItems`.
- The record does not exist, has been deleted, or its list has been deleted — `404`. The error text is in `error` and `message`; for compatibility it is also in `errors.item_id`.
- The record belongs to a list in someone else's project — `403`.

## deleteListItem

Deletes a record.

```endpoint
GET POST https://watbot.org/api/v1/deleteListItem
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `item_id` | string | yes | Record ID |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/deleteListItem" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"item_id": "6650b7a1c3d4e5f6a7b8c9e2"}'
```

```json title="Response 404"
{
  "message": "Item not found",
  "error": "Item not found",
  "errors": {
    "item_id": ["Item not found"]
  }
}
```

A successful response is code `204` with no body.

Errors:

- The record does not exist, has already been deleted, or its list has been deleted — `404`, as in [`updateListItem`](#updatelistitem).
- The record belongs to a list in someone else's project — `403`.
