REST API
The Lotics API gives you programmatic access to everything in your workspace. Create records, query data, trigger workflows and generate documents -- all through a standard REST interface with an OpenAPI 3.1.0 specification.
Overview
- Protocol: Standard REST. Resources are nouns, HTTP methods are verbs, responses use standard HTTP status codes.
- Specification: OpenAPI 3.1.0, published at
https://lotics.ai/openapi.json(and athttps://api.lotics.ai/v1/openapi.json). - Base URL:
https://api.lotics.ai/v1 - Content type: All requests and responses use
application/json. - Date format: ISO 8601 strings in UTC (e.g.,
2026-04-04T12:00:00.000Z). - Record field values: Follow the same types as the Lotics interface -- text, number, date, select, multi-select, linked records, files, and computed fields (formula, rollup, lookup).
Every entity you interact with in the Lotics interface (tables, records, views, workflows, document templates, apps, files) is available through the API. The API is the same interface that the Lotics web application uses internally.
Authentication
API requests are authenticated with organization-scoped API keys.
| Property | Detail |
|---|---|
| Format | ltk_ followed by 48 characters (e.g., ltk_vAJZYFb9WrF94Z3OjpdZgxjc...) |
| Scope | Single organization |
| Permissions | Inherits the permissions of the team member who created the key |
| Who can create | Admin role only |
| Where to create | Settings -> API Keys |
| Expiry | None unless you set one. A key can expire on a fixed date, or after a chosen number of days without being used — in which case each use pushes the date out, until one year after the key was created. |
Sending the key
Include the key in the Authorization header on every request:
Authorization: Bearer ltk_your_key_here
Error responses
| Status | Meaning |
|---|---|
401 Unauthorized | Missing, invalid, disabled or expired API key |
403 Forbidden | The organization has been deleted |
Security best practices
- Keys are shown once at creation. Copy and store them securely (e.g., environment variables, secrets manager).
- Give each key a descriptive name (e.g., "Production sync", "CI/CD pipeline") for easy identification.
- If a key is compromised, disable it immediately from Settings -> API Keys and create a new one.
- Use separate keys for different environments (production, staging, development).
Available endpoints
The API provides full CRUD operations for all primary entities, plus specialized operations like record aggregation, document generation, and global search.
| Resource | Operations | Notes |
|---|---|---|
| Tables | List, Create, Get, Update, Delete, Clone | Includes field definitions. Clone duplicates structure and optionally data. |
| Fields | Create, Update, Delete | Add or modify fields on existing tables. Supports all field types including computed fields (formula, rollup, lookup). |
| Records | Query, Get, Get by IDs, Create, Update, Delete, Aggregate | Query supports filters, sorts, cursor pagination. Aggregate returns count, sum, avg grouped by field. Update can append to or remove from a multi-value field instead of replacing it. |
| Views | List, Create, Get, Update, Delete | Views store filter, sort, field visibility, and color rule configurations. |
| Workflows | List, Create, Get, Update, Delete | Includes trigger configuration, step definitions, and execution history. |
| Document Templates | List, Create, Get, Update, Delete, Generate | Generate fills a template with record data and produces a PDF or Excel file. |
| Apps | List, Create, Get, Update, Delete | Apps are interactive interfaces built on top of tables. |
| Comments | List, Create, Update, Delete | Comments are attached to records. List supports filtering by record. |
| Files | Upload, Read, Delete | Upload files to attach to file fields on records. Read returns signed download URLs. |
| Connected Accounts | List, Request, Delete | Query connected OAuth accounts. Request initiates a new OAuth flow. |
| Search | Global search | Search across all tables and records in the organization. |
Updating a multi-value field
A record update sends only the fields you name, and for a multi-value field — attachments, a multi-select, linked records, assigned people — you can name the ITEMS rather than the whole list. add_to appends the items you give, remove_from drops them, and both resolve against the record as it stands when the write lands.
That matters when more than one thing writes the same field. If you read the list, add your item and send the whole array back, anything added between your read and your write is gone — and the response still says the update succeeded, because from the server's side you asked for exactly that list. Sending add_to instead means two callers attaching a document at the same moment each keep theirs.
{
"records": [
{ "id": "rec_...", "data": {}, "add_to": { "fld_attachments": ["fil_..."] } }
]
}
Use the plain data form when you genuinely mean "the list is now this" — reordering it, or clearing it. A field may appear in data or in add_to/remove_from, not both.
Record queries
Record queries are executed server-side with the same filter engine used by the Lotics interface. Complex filters (nested AND/OR conditions, linked record lookups, date comparisons) perform identically through the API and in the app.
Pagination
All list endpoints use cursor-based pagination for consistent results even during concurrent writes.
| Parameter | Default | Maximum | Description |
|---|---|---|---|
limit | 100 | 1,000 | Number of items per page |
cursor | (none) | -- | Cursor from a previous response's next_cursor field |
How it works
- Make your initial request without a
cursorparameter. - If more results exist, the response includes a
next_cursorfield. - Pass the
next_cursorvalue as thecursorquery parameter in your next request. - Repeat until
next_cursoris absent, meaning you have reached the last page.
Rate limits
Limits are counted per 60-second window, and separately per client IP and per member. The budget depends on what the request does, not on which endpoint it hits:
| What the request does | Per IP | Per member |
|---|---|---|
Read (GET, record queries, aggregates) | 1,200 / min | 1,200 / min |
| Write (create, update, delete, presign) | 600 / min | 600 / min |
| Download | 300 / min | 600 / min |
| Upload bytes through the API | 200 / min | 400 / min |
| Sign in, password reset, token exchange | 20 / min | 30 / min |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. When you exceed a limit you receive 429 Too Many Requests with Retry-After set to the seconds until the window resets — read that header rather than guessing, and back off exponentially on repeated 429s. Contact us if your use case needs a higher ceiling.
Error responses
Every non-2xx response — including an unmatched path — is JSON with the same three fields:
{
"code": "not_found",
"message": "Resource with key=rec_9tK2 not found",
"hint": "The record may have been deleted. List the table's records to confirm."
}
codeis stable and is the only field to branch on.messageis human-readable prose. It gets reworded; do not match on it.hintis present only when there is an actionable next step, and is absent otherwise.
Some errors add their own fields alongside these — a 409 from a version conflict carries current_version_id, a rejected record write carries field_errors.
| Status | Code | Meaning |
|---|---|---|
400 | bad_request | Invalid request body, missing required fields, or malformed parameters |
400 | hook_error | A before_* table workflow rejected the write. See field_errors. |
401 | unauthorized | Missing, invalid, disabled or expired API key |
403 | forbidden | Authenticated, but not permitted — or the organization has been deleted |
404 | not_found | Resource does not exist, is not visible to this caller, or the path matches no route |
409 | conflict | Resource conflict (e.g. duplicate name, stale version) |
429 | rate_limit | Rate limit exceeded. Read Retry-After. |
500 | internal_error | Unexpected server error |
503 | service_unavailable | An upstream dependency is unreachable. Retry later. |
The same shapes are published in the OpenAPI document as the Error schema, referenced by every operation.
Webhooks
Webhooks run inbound: your system calls Lotics, and the call starts an automation. Create an automation with a Receive webhook trigger and Lotics issues a URL with a random 64-character path:
https://api.lotics.ai/v1/webhooks/triggers/{webhook_path}
POST a JSON body to it and the automation runs, with the body available to every step — so a webhook can create records, update statuses, generate a document, or send a notification, without any of that logic living in your caller.
Securing the endpoint
The path is unguessable, and you can require a signature on top of it. Set a shared secret on the trigger, then send X-Webhook-Signature as the hex HMAC-SHA256 of the exact request body:
X-Webhook-Signature: hmac_sha256_hex(secret, raw_request_body)
Sign the raw bytes you send, not a re-serialized copy — a body that is parsed and re-encoded produces a different signature. A request with a wrong or missing signature is rejected and no automation runs.
Reacting to changes in Lotics
There is no outbound event subscription: Lotics does not POST to a URL of yours when a record changes. Do that with an automation instead — a table workflow on after_create / after_update with an HTTP request step calls your endpoint, and unlike a fixed event catalogue you decide there exactly which records qualify and what the payload contains.
MCP Server
Lotics provides a Model Context Protocol (MCP) server that exposes the same capabilities as the REST API through the MCP standard. This allows AI assistants and LLM-based tools to interact with your Lotics data directly.
See the dedicated MCP Server documentation for setup instructions and available tools.
CLI and SDK
Lotics provides a command-line interface and Node.js SDK for scripting, automation, and integration.
Installation
curl -fsSL https://lotics.ai/install.sh | bash
On Windows, in PowerShell: irm https://lotics.ai/install.ps1 | iex. It downloads one compiled executable — no Node.js and no package manager.
From the command line
The CLI is the fastest way for an AI coding agent to work against a workspace — it authenticates once and exposes the same capabilities as the API:
lotics auth signup [email protected]
lotics run query_tables '{}'
lotics run create_records '{"table_id":"tbl_...","records":[{"fld_...":["opt_..."]}]}'
lotics tools lists every tool the run verb can reach, and lotics tools <name> prints one tool's
input schema. lotics docs cli_reference prints the per-command reference.
Generating a typed client
For a program rather than an agent, generate a client from the OpenAPI document — every operation carries a unique operationId, typed parameters and a response schema, so the generated methods are named and typed rather than stringly-addressed:
npx @openapitools/openapi-generator-cli generate \
-i https://lotics.ai/openapi.json \
-g typescript-fetch \
-o ./lotics-client
See CLI reference for the full command-line documentation.
OpenAPI specification
The OpenAPI 3.1.0 specification is published at:
https://lotics.ai/openapi.json
https://api.lotics.ai/v1/openapi.json
Both serve the same document; the first is an alias, for tools that probe the main domain. It is generated from the route schemas on every request, so it cannot drift from the API: every operation carries a unique operationId, a description, typed parameters, a response schema and the shared Error schema for its failure cases.
Import it into Postman, Insomnia, any OpenAPI-compatible code generator, or an agent framework that builds function-calling tools from a spec.
Use openapi-generator to generate typed SDKs in TypeScript, Python, Go, Java, and other languages:
npx @openapitools/openapi-generator-cli generate \
-i https://api.lotics.ai/v1/openapi.json \
-g typescript-fetch \
-o ./lotics-client
Common use cases
- System sync: Keep Lotics in sync with external systems (ERP, CRM, e-commerce) by pushing and pulling records through the API.
- Custom dashboards: Build dashboards that pull live data from Lotics tables using query and aggregate endpoints.
- Automated record creation: Create records from external events -- form submissions, payment confirmations, shipping updates.
- Report generation: Query and aggregate record data programmatically to generate reports.
- Document automation: Fill document templates with record data to produce PDFs and Excel files on demand.
- CI/CD integration: Use API keys in pipelines to create records, update statuses, or trigger workflows as part of your deployment process.
Frequently asked questions
Is there a rate limit on the API?
Yes — counted per 60-second window and per route class, not per second. Reads get 1,200 per minute, writes 600, uploads 200. Every response carries X-RateLimit-Remaining; a 429 carries Retry-After with the seconds until the window resets. See Rate limits for the full table.
Can I use the API to create workflows programmatically?
Yes. The workflows endpoint supports full CRUD. You can create triggers, define steps (including conditionals, loops, and AI actions), and deploy workflows entirely through the API. Workflow execution history is also available via the API.
How do I handle file uploads through the API?
Use the Files upload endpoint with a multipart/form-data request. The response returns a file ID that you can assign to a file field when creating or updating records. File download URLs are signed and time-limited for security.
Can I test the API without affecting production data?
Create a separate organization for development and testing. API keys are organization-scoped, so your test key will only access test data. There is no additional cost for development organizations.
Is the OpenAPI spec available for code generation?
Yes. The OpenAPI 3.1.0 spec at https://api.lotics.ai/v1/openapi.json can be imported into tools like openapi-generator, Postman, or any OpenAPI-compatible client to generate typed SDKs in TypeScript, Python, Go, Java, and other languages.
How does cursor pagination differ from offset pagination?
Cursor pagination uses an opaque token (next_cursor) instead of page numbers. This ensures consistent results even when records are created or deleted between requests. With offset pagination, insertions and deletions can cause you to skip records or see duplicates. Cursor pagination avoids these problems entirely.
How do I get notified when a record changes?
Build an automation. A table workflow on after_create or after_update can call your endpoint with an HTTP request step, and you decide in the workflow which records qualify and what the payload looks like. Lotics has no outbound event subscription to register — its webhooks point the other way, from your system into an automation.
Can AI assistants interact with the API?
Yes. The MCP Server exposes the same capabilities as the REST API through the Model Context Protocol standard. AI assistants and LLM-based tools can query data, create records, trigger workflows, and generate documents. See the MCP Server documentation for setup.
How do I filter records by multiple conditions?
The query endpoint supports nested AND/OR filter groups. Each filter specifies a field, operator, and value. You can combine filters into groups with and/or logic. The filter engine is the same one used in the Lotics interface, so any filter you build in the UI can be replicated through the API.
What field types are supported?
All field types available in the Lotics interface are supported through the API: text, number, date, select, multi-select, checkbox, linked records, files, formula, rollup, and lookup. Computed fields (formula, rollup, lookup) are read-only -- their values are calculated automatically based on their configuration.