API
Web configuration
The HTTP api endpoint is /api/.
Example:
curl -v http://localhost/api/ping/
curl -v http://localhost:8000/api/ping/
curl -v https://mycavaliba.host.com/api/ping/You may need to update your current nginx.conf if coming from an older Cavaliba release (3.26 and earlier). Add the proper location as described here. You may download a newer release to see a complete configuration.
The key point is to make the /api/ endpoint available without OAUTH2 or other Basic Authentication scheme. API Authentication is based on headers and shared secrets.
nginx.conf entry for /api/
# -----------------------
# nginx - cavaliba api
# -----------------------
location /api/ {
# no SAM/OIDC/OAUTH2 authentication
# no middleware authentication (Basic Auth / Digest)
# for API / file upload:
client_max_body_size 20M;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
real_ip_header X-Real-IP;
#proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://cavaliba_app;
}Authentication
Most API calls must provide a valid API Key. API Keys are created in the User Interface (sidebar / API Key), with a short keyname, a secret and Authorizations.
Example:
curl -H "X-Cavaliba-Key: test xxxxx" https://my-secure-cavaliba.com/api/version/Warning: always use HTTPS to avoid API key clear-text eavesdropping.
Authorizations
Most API calls must have valid authorizations, for the requested operation. Authorizations are configured in the ACL Authorization Text Field of each API Key.
You provide a list of permissions which are concatenated. You can use a ! to remove (negate) a set of permissions.
Example:
## ACL Authorisations
p_info
p_data_site_read
p_data_app_read
!p_data_app_read
role:role_test01 Import/Export API Keys
You can import/export API Key with a yaml snippet:
- classname: _apikey
keyname: test
displayname: test
is_enabled: true
secret: "$sha256$3146ac549c20d3dd58c353483f8ea493$bab660e7a4996ec851cfe32f02b47b3b3f5a8b658ce1589222f2ce1655abaad9$"
description: Test API Key
ip_filter: '*'
acl: "role:role_admin"At the moment, secrets must be set from the UI editor.
Special authorizations
- special authorization : timerange, IP range
Endpoints
- /api/ping/
- /api/version/
- /api/info/
- /api/permissions/
- /api/schemas/
- /api/assets/
- /api/rawfile/
- /api/pipelines/
- /api/tasks/
- /api/keyname/
- /api/load/
Common options
o=[json|yaml|txt] output format
id=<INT> object id for requested action
schema=SCHEMA_NAME schema name
page=<int> page
size=<int> number of items
search=SEARCH_PATTERN search string
refs=[_user,_group,_role[*|schema1,schema2,...]]
add details for inline object (references)
rev=<int> add revision history to exported object
field=GRAMMAR select which fields to export (/api/assets/ only, expand=false) option: revisions
New: V3.30
Include the last N revisions of each asset in a _revision field. Each entry contains the login, date, and action.
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/site/GAVLE/?rev=2
{
"id": 42,
"classname": "site",
"keyname": "GAVLE",
(...)
"_revision": [
{"login": "admin", "date": "2026-03-14T10:22:01", "action": "update"},
{"login": "alice", "date": "2026-03-10T08:15:44", "action": "update"}
]
}If rev=0 or absent, no _revision field is returned.
option: references
New: V3.30
References add details for the inline objects in a _refs field of each exported object.
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/968/?refs=*,_user
{
"id": 968,
"classname": "test",
(...)
"my_user": "adela81",
"_refs": {
"_user": [
{
"login": "adela81",
"displayname": "Marijn Torrecilla",
"firstname": "Marijn",
"lastname": "Torrecilla",
"email": "Torrecilla@demo.cavaliba",
"mobile": "+56-16832089",
"external_id": "BA-948192"
}
],
"test": [
{
"keyname": "test02",
"classname": "test",
"displayname": "test02"
}
],
"site": [
{
"keyname": "GAVLE",
"classname": "site",
"displayname": "Gavle Rehabilitation Center"
}
]
}
}ping
Returns a simple JSON response to check connectivity to the cavaliba API.
- Authentication required: no
curl http://localhost:8000/api/ping/
{
"status": "OK"
}server version
Returns the remote Cavaliba version.
- Authentication required: yes
- Permission required:
p_info
curl -H "X-Cavaliba-Key: test a_secret_key" http://localhost:8000/api/version/
{
"version": "3.31.0",
"cavctl_supported_version": "1.7.0"
}info
Returns instance identity followed by statistics about the Cavaliba instance.
- Authentication required: yes
- Permission required:
p_info
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/info/
{
"cavaliba_version": "4.4.0",
"cavaliba_db_version": "4.4.0",
"cavctl_supported_version": "2.2.0",
"start_date": "2026-07-19T16:50:14.066182+00:00",
"uuid": "34730ec5-69be-4f41-8a7b-52c157303acd",
"schema_count": 26,
"field_count": 251,
"instance_count": 970,
"instance_eav": 8843,
"instance_file": 2,
"filestore_file_count": 394,
"revision_count": 1605,
"user_count": 512,
"group_count": 65,
"role_count": 16,
"permission_count": 141,
"configuration_count": 56,
"log_count": 4989,
"apistat_count": 1,
"dashboard_count": 24,
"smsjournal_count": 0,
"status_raw_count": 1820,
"status_sample_hour_count": 168,
"status_sample_day_count": 22
}Notes:
cavaliba_versionis the running code version;cavaliba_db_versionis the persisted schema/data version from the registry - they should match on a healthy instance.start_dateanduuidcome from the registry (LAST_START/INSTANCE_UUID).instance_filecountsDataFileDB rows;filestore_file_countcounts actual files on disk underCAVALIBA_FILESTORE- a mismatch between the two indicates orphaned rows or orphaned files.
permissions
New: v3.32.0
Returns a list of permissions. Supports filtering by id, keyname, or search pattern.
- Authentication required: yes
- Permission required:
p_permission_read
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/permissions/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/permissions/<id>/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/permissions/<key>/
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/permissions/?search=data&page=1&size=10"Example:
curl -H "X-Cavaliba-Key: test xxxxx" 'http://localhost:8000/api/permissions/p_data_admin/'
{
"classname": "_permission",
"keyname": "p_data_admin",
"displayname": "Data Admin",
"is_enabled": true,
"is_builtin": true
}
curl -H "X-Cavaliba-Key: test xxxxx" 'http://localhost:8000/api/permissions/?search=data&o=yaml'
- classname: _permission
keyname: p_data_admin
displayname: Data Admin
is_enabled: true
is_builtin: true
- classname: _permission
keyname: p_data_create
displayname: Data Create
is_enabled: true
is_builtin: trueschemas
Returns a list of all schemas, or the detail of a single schema by keyname.
- Authentication required: yes
- Permission required:
p_schema_read
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/schemas/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/schemas/<keyname>/Example:
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/schemas/site/?o=yaml"
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/schemas/site/"
{
"classname": "_schema",
"keyname": "site",
"displayname": "Sites",
"is_enabled": true,
"_options": {
"icon": "fa-hospital-o",
"keyname_mode": "edit",
"keyname_label": "Keyname",
"displayname_label": "Displayname",
"p_admin": "p_data_site_admin",
"p_create": "p_data_site_create",
"p_read": "p_data_site_read",
"p_update": "p_data_site_update",
"p_delete": "p_data_site_delete"
},
"country": {
"displayname": "Country code",
"description": "Country code",
"is_enabled": true,
"dataformat": "string",
"dataformat_ext": "",
"order": 104,
"page": "Postal Address",
"cardinal_min": 0,
"cardinal_max": 1,
"default_value": ""
},
"zip": {
"displayname": "ZipCode",
"description": "ZipCode",
"is_enabled": true,
"dataformat": "string",
"dataformat_ext": "",
"order": 106,
"page": "Postal Address",
"cardinal_min": 0,
"cardinal_max": 1,
"default_value": ""
},
(...)assets
Returns instances (assets): a single instance by id or by schema+keyname, or a searchable/paginated list. Read permission is checked per instance and schema, so a search can return a partial set (visible instances only) rather than an all-or-nothing 401.
- Authentication required: yes
- Permission required: per schema (e.g.
p_data_<schema>_read)
Endpoints:
| Method | URL | Notes |
|---|---|---|
| GET | /api/assets/ |
List/search across all schemas |
| GET | /api/assets/<id>/ |
Single instance by numeric id |
| GET | /api/assets/<schema>/ |
List/search within one schema |
| GET | /api/assets/<schema>/<keyname>/ |
Single instance by schema + keyname |
Options:
search=SEARCH_PATTERN full-text search - bare word OR search, field:value,
related:CLASS:KEY (see Search Syntax docs)
page=<int> page number (list mode only, default: 1)
size=<int> items per page (list mode only, default: 10)
expand=true|false return full UI-detail shape instead of export
shape (default: false)
refs=[*|schema1,schema2,...] inline referenced objects' details in "_refs"
rev=<int> single-instance lookups only - include the last
N revisions in "_revision"
field=GRAMMAR select which schema fields are exported - see below
o=json|yaml|txt output formatNotes:
expand=false(default): each instance is returned in the export shape (id,classname,keyname, fields, optional_refs/_revision).expand=true: each instance is returned in the richer UI-detail shape (PAGESgrouping, per-field UI datapoints) -_refs/_revisionare not added in this mode, andfieldis ignored (not supported by this shape).revis only read for single-instance lookups (byid, orschema+keyname); it’s ignored in list/search mode.- A single-instance lookup that resolves but fails the read-permission check returns
401; one that doesn’t resolve at all returns404. A list/search with zero visible matches returns404.
option: field
New: V4.2.0
Select which schema fields are included in the export shape (expand=false,
the default). id/classname/keyname are always included.
field=* all fields (default - no filtering)
field=a,b,c* whitelist - only exact "a"/"b", or fields starting with "c"
field=!a,b,c* blacklist - leading "!" flips the whole list to exclude insteadcurl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/assets/site/GAVLE/?field=country,zip"
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/assets/site/GAVLE/?field=!last_login,last_update,last_sync,displayname"curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/<id>/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/<schema>/<keyname>/
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/assets/?search=zzz
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/assets/?search=zzz&refs=*&expand=true"
curl -H "X-Cavaliba-Key: test xxxxx" "http://localhost:8000/api/assets/site/GAVLE/?rev=2"See option: revisions and option: references above for the shape of _revision/_refs, and option: field above for the field-selection grammar.
rawfile
New: V4.4.0 (renamed from /api/import/; client-side CSV chunking/batching moved
to cavctl load / /api/load/ - this endpoint stays a whole-file, single-request
passthrough)
Import a whole file via POST. Supports JSON, YAML, and CSV content types (auto-detected
from Content-Type). Optional pipeline, schema, action, encoding, and dryrun parameters.
- Authentication required: yes
- Permission required:
p_api_rawfileand per object permission
Options:
pipeline=NAME apply a named Pipeline to each object (optional)
schema=NAME CSV only: classname for every row, overrides any "classname"
column already present; falls back to pipeline.classname if unset (optional)
delimiter=, CSV only: field delimiter (optional)
encoding=utf-8 CSV only: body encoding - utf-8, utf-8-sig, iso-8859-1, cp1252 (optional)
action=create|init|update|delete|enable|disable override every object's _action (optional)
dryrun=true|false skip the write, shallow - no perm/schema check (default: false)
sync=true|false touch last_sync on write (default: false)
o=json|yaml|txt output formatcurl -X POST -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/rawfile/ \
-H 'Content-Type: application/json' --data-binary \
@mydir/myfile.json
curl -X POST -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/rawfile/ \
-H 'Content-Type: text/x-yaml' --data-binary \
@myfile.yaml
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
"http://localhost:8000/api/rawfile/?pipeline=test_api" \
-H 'Content-Type: text/x-yaml' --data-binary \
@myfile.yaml
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
"http://localhost:8000/api/rawfile/?pipeline=test_api&schema=_user&delimiter=,&encoding=cp1252" \
-H 'Content-Type: text/csv' --data-binary \
@myfile.csvApp STATUS worklist
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/appstatus/worklist/ | jq .
{
"version": "1234567890",
"monitors": [
{
"keyname": "apache",
"displayname": "www.apache.org",
"type": "HTTP",
"is_enabled": true,
"timeout": 2000,
"target": "https://www.apache.org/",
"http_code": 200,
"http_ssl_verify": true,
"http_allow_redirect": true,
"http_pattern": "Foundation"
}
]
}pipelines
New: V3.33
Apply pipelines to existing assets. Use for bulk transformations (e.g. remove out-of-sync objects, populate new fields, etc.).
Endpoints:
| Method | URL | Permission |
|---|---|---|
| GET | /api/pipelines/ |
p_pipeline_read |
| POST | /api/pipelines/<pipeline_name_or_id>/ |
p_pipeline_run + asset permissions |
Options:
schema=<SCHEMA> target schema (required for most pipelines)
dryrun=true|false simulate without writing changes (default: false)
o=json|yaml|txt output format# List available pipelines
curl -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/pipelines/
# Run a named pipeline on a schema
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/pipelines/bulk_delete_all/?schema=test'
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/pipelines/bulk_delete_out_of_sync/?schema=site'
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/pipelines/bulk_disable_out_of_sync/?schema=_user'
# Dry run
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/pipelines/bulk_delete_all/?schema=test&dryrun=true'See builtin pipelines for available operations.
tasks
New: V3.33
List and manage long-running background tasks.
Endpoints:
| Method | URL | Permission |
|---|---|---|
| GET | /api/tasks/ |
p_task_view |
| GET | /api/tasks/<UUID>/ |
p_task_view |
| POST | /api/tasks/<UUID>/stop/ |
p_task_manage |
Notes:
p_task_viewandp_task_manageapply to the current user’s own tasks only.p_task_allextends view and manage (stop) permissions to tasks from all users.
Options:
state=RUNNING|DONE|QUEUED|ABORTED|ALL filter by task state (default: ALL)
page=<int> page number
size=<int> items per page
o=json|yaml|txt output format# List all tasks
curl -H "X-Cavaliba-Key: test xxxxx" 'http://localhost:8000/api/tasks/'
# Filter by state
curl -H "X-Cavaliba-Key: test xxxxx" 'http://localhost:8000/api/tasks/?state=RUNNING'
curl -H "X-Cavaliba-Key: test xxxxx" 'http://localhost:8000/api/tasks/?state=DONE&page=4&size=1'
# Get task detail
curl -H "X-Cavaliba-Key: test xxxxx" \
http://localhost:8000/api/tasks/14828cf7-fb35-4300-9aef-a89d20336c7b/
# Stop a running task
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
http://localhost:8000/api/tasks/14828cf7-fb35-4300-9aef-a89d20336c7b/stop/keyname
New: V4.2.0
Rename an instance keyname, cascading the change to every other instance referencing it through a schema-type field.
Endpoints:
| Method | URL | Permission |
|---|---|---|
| POST | /api/keyname/ |
p_keyname_rename |
Options:
s=<SCHEMA> schema/classname of the instance to rename (required)
old=<KEYNAME> current keyname (required)
new=<KEYNAME> new keyname (required)
dryrun=true|false simulate without writing changes (default: true)
force=true|false allow rename on user/group/role (default: false)
o=json|yaml|txt output formatNotes:
dryrundefaults totruehere (unlikepipelines) - passdryrun=falseexplicitly to write.user/group/roleare refused unlessforce=true; some identities (e.g.user/admin,role/role_admin,role/role_default) and builtin objects (is_builtin=true) are refused even withforce=true.
# Dry run (default)
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/keyname/?s=site&old=site01&new=site01bis'
# Apply the rename
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
'http://localhost:8000/api/keyname/?s=site&old=site01&new=site01bis&dryrun=false'load
New: V4.4.0
Write a small, synchronous batch of JSON objects via load_broker() - the same
engine used by /api/rawfile/, cavaliba load, and the code editor. Unlike
/api/rawfile/, the body is always JSON (no CSV/YAML, no delimiter/encoding
options).
Endpoints:
| Method | URL | Permission |
|---|---|---|
| POST | /api/load/ |
p_api_load and per object (regular create/update) |
Options:
pipeline=NAME apply a named Pipeline to each object (optional)
action=create|init|update|delete|enable|disable override every object's _action (optional)
dryrun=true|false skip the write (default: false)
verbose=true|false include a result entry for every object, not just failures (default: false)
sync=true|false touch last_sync on write (default: false)
o=json|yaml|txt output formatBody: a single JSON object, or a JSON list of objects - each one shaped like an
/api/rawfile/ entry (classname, keyname, fields, optional _action).
Notes:
dryrun=trueis shallow: it never callsload_broker(), so it does not check schema existence or create/update permission - it only reports how many objects would be attempted vs. discarded by the pipeline, same ascavaliba load’s own--dryrun. It is not a substitute for a real write to catch permission/validation errors.- Processing aborts early once failures exceed
CAVALIBA_LOAD_BATCH_MAX_ERROR(default: 20); the response’sabortedfield reports this. verbose=false(default) only lists failed/koobjects inresults;verbose=truealso listsokanddiscardedones.sync=truesetslast_syncon every written object, same as/api/rawfile/.
curl -X POST -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/load/ \
-H 'Content-Type: application/json' --data-binary \
'{"classname": "site", "keyname": "GAVLE", "country": "SE"}'
curl -X POST -H "X-Cavaliba-Key: test xxxxx" http://localhost:8000/api/load/ \
-H 'Content-Type: application/json' --data-binary \
'[{"classname": "site", "keyname": "s01"}, {"classname": "site", "keyname": "s02"}]'
# validate only, no write
curl -X POST -H "X-Cavaliba-Key: test xxxxx" \
"http://localhost:8000/api/load/?dryrun=true" \
-H 'Content-Type: application/json' --data-binary \
'{"classname": "site", "keyname": "GAVLE", "country": "SE"}'
{
"dryrun": false,
"aborted": false,
"count": 2,
"count_ok": 2,
"count_ko": 0,
"count_discarded": 0,
"duration": 0.014,
"results": []
}