> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Entities

> Read and change an app's data model with the Base44 Apps API

An entity is a table in your app's database. Its schema is a JSON Schema that names the entity's fields, marks which are required, and holds its row-level security rules under `rls`. The entity endpoints let you read and change those schemas, read and change the records they hold, and count the records and users an app holds.

Use these endpoints to:

* Read an app's entity schemas, one at a time or all together.
* Add, replace, or remove an entity.
* Make an app's live data model match its source in one call. This one is limited to apps whose source code you manage yourself.
* Read, add, change, or remove an entity's records.
* Count an entity's records, or the app's users.

## Schema writes don't change your code

Every write here changes the app's live data model, so it takes effect immediately. It doesn't change the entities configuration file that defines that model in the app's source code, at `base44/entities/<EntityName>.jsonc`. Base44 rebuilds the live model from those files whenever one of them is written or the app's code is pulled from GitHub, so a change made only through this API is reverted at that point.

To change the model for good, change the file. If the app is connected to a GitHub repository, commit the change there and call [Pull changes from GitHub](/api-reference/pull-changes-from-github), which rebuilds the live model from your file. Otherwise ask the AI to add or edit the entity with [Send chat message](/api-reference/send-chat-message), which writes the file the same way the Base44 online app editor does.

That makes the write endpoints a good fit for pushing a schema Base44 should serve right now, and a poor fit for a lasting schema edit.

## The User entity

`User` is built in, so it doesn't behave like an entity you defined:

* You can't create it. Use [Update entity schema](/api-reference/update-entity-schema) with `User` to add custom fields to it, which also creates those fields the first time.
* Reading it returns only the custom fields you added, not the built-in ones, and returns a 404 when there are none.
* Custom fields can't redeclare `email` or `full_name`, which Base44 manages.
* Its stored schema carries no `name` key, unlike the schema of an entity you defined.
* Counting users has its own endpoint, [Count app users](/api-reference/count-app-users). Don't pass `User` to [Count entity records](/api-reference/count-entity-records).
* The record endpoints don't reject it either. [List](/api-reference/list-entity-records), [Create](/api-reference/create-entity-record), [Get](/api-reference/get-entity-record), [Update](/api-reference/update-entity-record), and [Delete entity record](/api-reference/delete-entity-record) all accept `User` as an `entity_name`, but they read and write a separate, disconnected set of records stored under that name, not the app's real user accounts.

## Filtering, sorting, and paging

[List entity records](/api-reference/list-entity-records) accepts these query parameters.

### Filter

Two ways to filter:

* Pass one of the entity's own field names directly as a query parameter, for an exact match. `?status=paid` matches records where `status` is `"paid"`.
* Pass `q` as a JSON object, for anything beyond an exact match, for example `{"amount": {"$gt": 100}}`. `q` accepts:
  * Compare: `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`
  * Match a set: `$in`, `$nin`
  * Combine conditions: `$and`, `$or`, `$nor`, `$not`
  * Check presence or type: `$exists`, `$type`
  * Arrays: `$all`, `$elemMatch`, `$size`
  * Substring or pattern: `$regex`
  * Geospatial and full-text, if the field actually holds that kind of data: `$near`, `$nearSphere`, `$geoIntersects`, `$geoWithin`, `$text`, `$search`

A query parameter that isn't `q`, `limit`, `skip`, `sort`, or `fields`, and isn't one of the entity's own field names, is still read as a filter on that name. A misspelled field name matches nothing rather than returning an error.

Base44 wraps every filter in the entity's own row-level-security conditions before checking nesting depth, so how deep you can nest `q` depends on the entity's `rls` rules.

### Sort

Sort with a single field name in `sort`, prefixed with `-` for descending, for example `-created_date`. Sorting by more than one field isn't supported.

### Page

Page with `limit` (1 to 5000, defaults to 5000) and `skip` (defaults to 0). Base44 caps every call at 5000 records, whether you leave `limit` out or ask for more, and the response doesn't indicate when it was cut short.

### Select fields

Reduce the response size with `fields`, a comma-separated list of field names. Reach into an object with dots, as in `customer.email`. Every record still carries its `id`.

## Rate limits

Each entity endpoint states its base rate limit in its `429` response. [List entity records](/api-reference/list-entity-records) and [Count entity records](/api-reference/count-entity-records) share one allowance, scoped to one app rather than shared across the workspace's other apps, and also drawn down by version-history activity in the Base44 online app editor. A paid plan gets a multiple of the base number. See [Rate limits](/developers/references/apps-api/get-started/rate-limits) for the multiplier table.
