Data API
In the admin: Settings › Data API
Settings › Data API groups these pages of the admin: Limits, Transactions, Executions, OpenAPI, MCP.
Limits
Settings › Data API › Limits
Limits bounds what one Data API request may ask for, so no request, careless or hostile, can make PostgreSQL do unbounded work. A request past a limit is refused before any SQL runs. See Errors.
Pagination
| Setting | Key | Default | Range |
|---|---|---|---|
| Default page size | api.default_limit | 50 | ≥ 1. When a request sets no limit |
| Maximum page size | api.max_limit | 500 | ≥ 1 |
| Maximum offset | api.max_offset | 100000 | ≥ 0 |
Query complexity
| Setting | Key | Default | |
|---|---|---|---|
| Maximum relation depth | api.max_relation_depth | 3 | Levels of related tables one request may reach: site.customer.name reaches 2 |
| Maximum filter depth | api.max_filter_depth | 10 | Nesting of _and / _or / _not |
| Maximum query nodes | api.max_query_nodes | 200 | Filter, sort and field nodes together |
Writes
| Setting | Key | Default | |
|---|---|---|---|
| Require a filter for bulk update | api.require_where_for_update | on | An update of several rows needs a where. Applies to the workflow Update records step too |
| Require a filter for bulk delete | api.require_where_for_delete | on | Same, for deletes |
| Maximum bulk items | api.bulk_max_items | 500 | Rows one bulk create, update or delete may touch |
| Maximum nested write depth | api.nested_write_max_depth | 2 | 1-3: parent → child → grandchild |
| Maximum nested write records | api.nested_write_max_records | 500 | Across all levels |
Requests
| Setting | Key | Default | |
|---|---|---|---|
| Maximum request body size | api.max_body_bytes | 5 MB | ≥ 1024 bytes. Past it, REQUEST_BODY_TOO_LARGE |
| Maximum query string size | api.max_query_string_bytes | 32768 bytes | ≥ 256. Raising it above the value at startup needs a restart |
| Maximum query parameters | api.max_query_parameters | 200 | |
| Request timeout | api.request_timeout_ms | 30000 ms | 100 ms to 1 h. PostgreSQL cancels the query, and the caller gets QUERY_CANCELED |
Query features
| Setting | Key | Default | |
|---|---|---|---|
| Allow count | api.allow_count | on | count=true |
| Allow regular expressions | query.allow_regex | on | _regex. It can't use an ordinary index |
| Allow containment operators | query.allow_contains | on | _contains, _contained_by, _overlap. Fast with a GIN index |
| Allow having | query.allow_having | on | Filters on aggregates |
Transactions
Settings › Data API › Transactions
Transactions
POST /api/transactions runs several writes in one PostgreSQL transaction, all or nothing. See Transactions.
| Setting | Key | Default | |
|---|---|---|---|
| Enable transactions | transactions.enabled | on | A role also needs the Can run transactions capability: see Creating a role |
| Maximum operations | transactions.max_operations | 20 | |
| Statement timeout | transactions.timeout_ms | 0 | Up to 600000 ms. 0: the request timeout from Limits. A cancelled statement rolls back the whole transaction |
Idempotency
An Idempotency-Key header makes a write safe to retry: the same key returns the first answer instead of writing again. See Writing.
| Setting | Key | Default | |
|---|---|---|---|
| Enable idempotency keys | idempotency.enabled | on | |
| Key lifetime | idempotency.ttl_hours | 24 h | |
| Maximum stored response | idempotency.max_response_bytes | 65536 bytes | A larger answer isn't stored; a retry gets an error instead of the original body |
Executions
Settings › Data API › Executions
TotalBase works through two queues in the background, both kept in PostgreSQL: executions (function calls made with ?async=true) and data events (the changes that start Database event workflows).
Executions
| Setting | Key | Default | |
|---|---|---|---|
| Enable the worker | async_executions.enabled | on | Off: queued executions wait |
| Maximum retries | async_executions.max_retries | 3 | Only failures that can be retried |
| Retry delay | async_executions.retry_delay_seconds | 30 s | |
| Stale timeout | async_executions.stale_timeout_ms | 120000 ms | An execution running longer without news is treated as abandoned by a crashed worker, and picked up again |
| Poll interval | async_executions.poll_interval_ms | 2000 ms | |
| Keep finished executions | async_executions.retention_days | 7 days | 0: forever |
See Calling functions.
Data events
| Setting | Key | Default | |
|---|---|---|---|
| Processed event retention | outbox.retention_days | 7 days | 1-3650. Failed events that ran out of attempts are kept |
| Maximum attempts | outbox.max_attempts | 5 | 1-100 |
| Retry delay | outbox.retry_delay_seconds | 30 s | Doubles after each attempt |
| Processing lease | outbox.lease_seconds | 1200 s | Keep it longer than your longest workflow run |
An event is written in the same transaction as the change, and processed only after it commits. See Audit and events.
OpenAPI
Settings › Data API › OpenAPI
TotalBase generates an OpenAPI document of the Data API from your schema, permissions and workflows: each caller gets the one their roles can use. See OpenAPI.
| Setting | Key | Default | |
|---|---|---|---|
| Publish the OpenAPI document | openapi.enabled | on | Serves /api/openapi.json. Off: 404, though administrators still see it in the admin |
| Include example values | openapi.include_examples | on | |
| Cache generated documents | openapi.cache_enabled | on | Kept per set of roles until the schema, permissions, workflows or settings change |
MCP
Settings › Data API › MCP
MCP turns on the MCP server an AI agent builds and operates the instance through, served at the instance's own address, /mcp, with an administrator's token. See AI Agents.
Connection
Above the settings, the details to connect an agent: the Address (the public URL plus /mcp), Create a token (to your My account › Tokens), the claude mcp add command for Claude Code and a .mcp.json snippet, each with a copy button.
Settings
| Setting | Key | Default | |
|---|---|---|---|
| Enable MCP | mcp.enabled | off | Off: /mcp doesn't answer, and the totalbase-mcp command refuses to start |
| Mode | mcp.mode | FULL | Read only, Standard (no deleting or revoking) or Full (destructive calls need an explicit confirmation). On top of every permission check |
Tools
Each group of tools can be switched off; an agent doesn't see the tools of a group that's off. All are on by default.
| Setting | Key |
|---|---|
| Tables and schema | mcp.tools_schema |
| Records | mcp.tools_records |
| Permissions | mcp.tools_access |
| Users | mcp.tools_users |
| DataViews and pages | mcp.tools_screens |
| Dashboards | mcp.tools_dashboards |
| Workflows | mcp.tools_workflows |
| Templates | mcp.tools_templates |
| SQL | mcp.tools_sql. Also needs Allow API tokens in SQL Console |
See Tools.
Agent
| Setting | Key | Default | |
|---|---|---|---|
| Project instructions | mcp.instructions | empty | Your project's conventions, given to every agent on connecting: naming, language, what never to touch. Up to 8000 characters |
| Requests per minute | mcp.rate_limit_per_minute | 600 | Per token. An MCP request with a token counts only here, not toward the Network limit |
| Allowed hosts | mcp.allowed_hosts | none | The host names /mcp answers to, such as localhost:3050. Empty: the public URL's host and localhost. Protects against DNS rebinding |