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_version is the running code version; cavaliba_db_version is the persisted schema/data version from the registry - they should match on a healthy instance.
  • start_date and uuid come from the registry (LAST_START / INSTANCE_UUID).
  • instance_file counts DataFile DB rows; filestore_file_count counts actual files on disk under CAVALIBA_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: true

schemas

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 format

Notes:

  • 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 (PAGES grouping, per-field UI datapoints) - _refs/_revision are not added in this mode, and field is ignored (not supported by this shape).
  • rev is only read for single-instance lookups (by id, or schema+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 returns 404. A list/search with zero visible matches returns 404.

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 instead
curl -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_rawfile and 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 format
curl -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.csv

App 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_view and p_task_manage apply to the current user’s own tasks only.
  • p_task_all extends 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 format

Notes:

  • dryrun defaults to true here (unlike pipelines) - pass dryrun=false explicitly to write.
  • user/group/role are refused unless force=true; some identities (e.g. user/admin, role/role_admin, role/role_default) and builtin objects (is_builtin=true) are refused even with force=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 format

Body: 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=true is shallow: it never calls load_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 as cavaliba 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’s aborted field reports this.
  • verbose=false (default) only lists failed/ko objects in results; verbose=true also lists ok and discarded ones.
  • sync=true sets last_sync on 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": []
}