API Reference
This document describes the API surface that is currently implemented by Adapt.
Authentication
Adapt supports two authentication methods:
- Session cookie (
adapt_session) from web login - API key using
X-API-Key: <key>
Generated resource routes require authentication. Non-superusers must also
have the corresponding read or write permission. For command-line
mutations, prefer an API key because an API-key-only request is CSRF-exempt.
Cookie-authenticated unsafe requests must send the adapt_csrf cookie value
in the X-CSRF-Token header (or in the csrf_token form field).
Each authentication method requires an active user. An inactive user cannot log in or authenticate with an existing session or API key.
Authentication endpoints:
GET /auth/login- Login page (HTML)POST /auth/login- Login using form fields (username,password)POST /auth/logout- Logout current sessionGET /auth/me- Current authenticated userPUT /auth/password- Change the current user passwordGET /profile- Authenticated profile page
PUT /auth/password accepts current_password and new_password. A
successful change revokes all browser sessions for the user and returns a
message that tells the user to sign in again. The new password must pass the
password-strength check.
User API key endpoints (for the currently authenticated user):
POST /api/apikeysGET /api/apikeysDELETE /api/apikeys/{key_id}— deactivates the key (is_active = false) and returns204. Adapt keeps the key record in the database, but the key will no longer authenticate.
Base URL
Default local URL: http://localhost:8000
Hosted vs Runtime API Schema
Adapt publishes two intentionally different OpenAPI views:
- Hosted documentation schema (this documentation site): generated from an app built with an empty docroot, so it documents only the API surface shared by all Adapt deployments.
- Runtime schema (
GET /openapi.jsonon a live server): generated per request and filtered by authentication, permissions, and discovered resources in that instance's docroot.
Runtime routes depend on discovered files and caller permissions. As a result, a live instance can expose more paths, or fewer visible paths, than the hosted documentation shows.
Generated Dataset APIs
For dataset resources (CSV, Excel sheets, Parquet), Adapt generates routes under:
/api/{resource}//schema/{resource}//ui/{resource}/
Examples:
- CSV
products.csv->/api/products/ - Excel
inventory.xlsxsheetStock->/api/inventory/Stock/ - Legacy Excel
inventory.xlssheetStock->/api/inventory/Stock/
Legacy .xls routes support read and schema requests. Their mutation requests
return 405 because legacy workbooks are read-only.
List Records
GET /api/{resource}/
Query parameters:
limit(optional)offset(optional, default0)sort(optional)order(optional:ascordesc, defaultasc)filter(optional JSON string)
Example:
curl -H "X-API-Key: key" "http://localhost:8000/api/products/?limit=10&sort=name&order=asc"
Mutations (Create, Update, Delete)
Adapt uses action-based mutation payloads at the collection endpoint.
POST /api/{resource}/
{
"action": "create",
"data": [
{
"name": "Keyboard",
"price": 49.99,
"category": "Electronics",
"in_stock": true
}
]
}
PATCH /api/{resource}/
{
"action": "update",
"data": {
"_row_id": 1,
"price": 39.99
}
}
DELETE /api/{resource}/
{
"action": "delete",
"data": {
"_row_id": 1
}
}
Notes:
- Dataset mutations are row-oriented and use
_row_id. - Adapt validates create and update values against the inferred or companion
schema before it locks or changes the backing file. Unknown columns and
incompatible values return
422. - Adapt accepts and normalizes numeric and boolean strings from the generated
HTML form. Blank strings and
nullremain valid because Adapt schemas do not describe nullability or required columns. - In read-only mode, mutation endpoints return
405. - Legacy
.xlsresources are always read-only and return405for mutations.
Schema Endpoint
GET /schema/{resource}/
Returns the inferred or companion schema.
For CSV and Excel resources, inference assigns only string, integer,
number, or boolean. These types control response serialization and the
default dataset UI columns. Adapt also uses these types to make sure that
values in create and update mutations are correct. For Parquet resources,
Adapt makes sure that the common Parquet type names correspond to these four
types. An unrecognized custom type remains metadata only.
The schema format does not currently express required columns or nullability.
Adapt validates fields that the caller supplies and permits blank or null
values. A validation failure uses status 422, for example:
{
"detail": "Schema validation failed: column 'price': expected number, received string"
}
Example:
curl -H "X-API-Key: key" http://localhost:8000/schema/products/
Content Endpoints
For HTML and Markdown resources, Adapt mounts content routes using file path namespaces.
- HTML content route:
/{resource} - Markdown content route:
/{resource}
Some resources are also available with extension-qualified paths. This depends on the mount namespace.
Examples:
readme.md->/readmeindex.html->/index
Media Endpoints
Media resources generate:
- Streaming endpoint:
/media/{resource} - Player UI:
/ui/{resource} - Gallery UI:
/ui/media
Example:
curl -H "X-API-Key: key" http://localhost:8000/media/sample.mp4
Python Handler Endpoints
Python handler files (.py) with an APIRouter named router are mounted under:
/api/{handler_name}
Example:
reports.pywith@router.get("/summary")->/api/reports/summary
Search Endpoint
GET /search
Full-text search covers every resource that the caller can read. Datasets,
Markdown, HTML, and media metadata all rank in one result list. Adapt filters
results by permission after it queries the index. As a result, count never
reveals the existence of a resource that the caller cannot see.
Query parameters:
q(optional, an empty value returns no results)limit(optional, default20, max100)offset(optional, default0)type(optional, comma-separated resource types, for examplecsv,markdown)
Example:
curl -H "X-API-Key: key" "http://localhost:8000/search?q=parental+leave&type=csv,markdown"
Returns JSON by default, or an HTML results page when the client sends
Accept: text/html. Each result includes resource, type, title,
snippet, score, and ui_url. Dataset row hits also include api_url and
row_id.
Adapt rebuilds the index incrementally on server startup (search_on_startup,
default true). You can also rebuild the index on demand:
adapt reindex /path/to/docroot [--force]
Upload Endpoint
POST /api/uploads
Uploads a single file to the document root. The endpoint accepts multipart form data with these fields:
filename(required): basename only, no path separatorsfile(required): binary file payload
Example:
curl -X POST \
-H "X-API-Key: key" \
-F "filename=notes.txt" \
-F "file=@./notes.txt" \
http://localhost:8000/api/uploads
Response example:
{
"path": "notes.txt",
"size": 42,
"mime_type": "text/plain",
"checksum": "<sha256>",
"operation": "created"
}
Behavior notes:
- Requires authenticated user with
writepermission on the document-root boundary. - Returns
405when global read-only mode is enabled. - Returns
403when upload feature is disabled (upload.enabled=false) or permission check fails. - Rejects path traversal and path-separator input in
filename. - Uses atomic write semantics and returns
operationascreatedoroverwritten. - Invalidates cache for the written resource and emits upload audit events.
- The configuration key
upload.strict_mime_sniffingcontrols optional strict MIME sniffing. When enabled, Adapt validates sniffed content against the filename extension and the optionalupload.allowed_mime_typeslist. - The configuration key
upload.collision_policycontrols collision handling:overwrite(default) orreject(returns409when the target exists). - The landing page (
/) shows the same upload form for authenticated users with root-boundarywritepermission whenupload.enabled=true.
To grant upload permission to a non-superuser through admin APIs, create a
write permission on the document-root boundary resource (""). The admin API
accepts "" directly. It also normalizes "__root__" or "<root>" to the
same boundary value.
Example:
curl -X POST \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: <csrf>" \
-b "adapt_session=<session-cookie>" \
-d '{"resource":"__root__","action":"write","description":"Root upload write"}' \
http://localhost:8000/admin/permissions
MCP Interface
Adapt mounts a Model Context Protocol
server at /mcp/. The server exposes the same permission-filtered
read, write, and search features as tools for agentic clients. See the
MCP Guide for a full walkthrough from account creation to
connecting a client.
| Tool | Equivalent to |
|---|---|
list_resources |
GET / (JSON) |
get_schema |
GET /schema/{resource}/ |
read_resource |
GET /api/{resource}/ |
write_resource |
POST/PATCH/DELETE /api/{resource}/ |
search |
GET /search |
Adapt enforces authentication when a tool executes. When OIDC is on, an
unauthenticated HTTP request to /mcp/ also returns 401 plus RFC 9728
metadata. MCP uses Adapt's shared authentication resolver (session cookie,
API key, or Bearer JWT). API keys remain the simple option for scripts. Set
mcp_enabled: false in .adapt/conf.json (or ADAPT_MCP_ENABLED=false) to
remove /mcp/ entirely.
Admin Endpoints
All admin endpoints require superuser authentication and are prefixed with /admin.
Users:
GET /admin/usersPOST /admin/usersPUT /admin/users/{user_id}/passwordPUT /admin/users/{user_id}/statusDELETE /admin/users/{user_id}
The password-reset request contains new_password. A successful reset revokes
all browser sessions for the target user. It does not revoke API keys.
The status request contains the Boolean is_active value. Deactivation
revokes browser sessions. API keys remain stored and cannot authenticate
until an administrator activates the user.
Groups:
GET /admin/groupsGET /admin/groups/{group_id}POST /admin/groupsDELETE /admin/groups/{group_id}POST /admin/groups/{group_id}/users/{user_id}DELETE /admin/groups/{group_id}/users/{user_id}
Permissions:
GET /admin/permissionsPOST /admin/permissionsDELETE /admin/permissions/{perm_id}GET /admin/groups/{group_id}/permissionsPOST /admin/groups/{group_id}/permissions/{perm_id}DELETE /admin/groups/{group_id}/permissions/{perm_id}
Locks:
GET /admin/locksDELETE /admin/locks/{lock_id}POST /admin/locks/clean
Cache:
GET /admin/cacheDELETE /admin/cacheDELETE /admin/cache/{key}(requiresresourcequery parameter)
API keys (admin-managed):
GET /admin/api-keysPOST /admin/api-keysDELETE /admin/api-keys/{key_id}
Audit logs:
GET /admin/audit-logs
Adapt currently creates audit entries for:
- Successful login and logout
- Password changes and administrator resets
- API-key creation and revocation
- User and group creation or deletion
- Group membership changes
- Permission creation, deletion, and group assignment changes
- Manual lock release and stale-lock cleanup
- Cache entry deletion and cache clearing
- Upload success, deny, and failure attempts
- Successful dataset creation, update, and deletion operations
Dataset mutations use these audit actions:
| Mutation | Audit action |
|---|---|
POST create |
create_dataset_rows |
PATCH update |
update_dataset_row |
DELETE delete |
delete_dataset_row |
Upload events use these actions:
| Result | Audit action |
|---|---|
| Success (create/overwrite) | upload_success |
| Permission/config deny | upload_denied |
| Validation/write failure | upload_failed |
The audit resource is the dataset path relative to the document root. The path includes the file extension and an Excel sheet namespace when applicable.
The details contain the created row count or the affected row ID. They do not contain dataset values.
Admin UI page:
GET /admin/
System Endpoint
Health
GET /health
- Unauthenticated callers receive base status info.
- Authenticated callers receive additional metrics.
Example fields:
statusversiontimestampuptime_seconds(authenticated)cache_size(authenticated)endpoint_count(authenticated)
Filtering, Sorting, and Pagination
Dataset and many admin list endpoints support:
filteras JSONsortorderoffsetlimit
Supported filter operators include:
$eq,$ne$gt,$gte,$lt,$lte$contains,$startswith,$regex$and
Example:
curl -H "X-API-Key: key" "http://localhost:8000/api/products/?filter={\"price\":{\"$gte\":100},\"category\":\"Electronics\"}"
Common Error Codes
400- Invalid request data401- Not authenticated403- Permission denied404- Resource not found405- Method not allowed (for example, read-only mode mutations)409- Lock acquisition conflicts422- FastAPI request or parameter validation failure
Error bodies are not a single Adapt-specific envelope. FastAPI-generated and
most application errors use a detail member, for example:
{"detail": "Not authenticated"}
Validation failures can use a list of structured objects under detail.
Adapt returns 409 when another operation holds the resource lock. This
response also applies when Adapt exhausts all lock acquisition retries.
Manual navigation: Previous: User Guide | Index | Next: Admin Guide