Bash CLI for the exivo raw API v1 (access control): persons, media, doors, visits, logs — with alias support
  • Shell 97.6%
  • Makefile 2.4%
Find a file
2026-08-17 11:25:00 +02:00
exivo Fix shellcheck warning, make shellcheck output advisory 2026-08-17 11:22:18 +02:00
Makefile chore: fixed Makefile 2026-08-17 11:25:00 +02:00
README.md Add Makefile with install/uninstall/check targets 2026-08-17 11:21:48 +02:00

exivo-cli

A self-contained Bash CLI for the exivo raw API v1 (https://api.exivo.io/v1) — manage sites, persons, media, digital keys, access groups/zones, doors, visits, time profiles, special days, access logs and more from your terminal.

Single file, no build step. Dependencies: curl + jq.

Install

git clone https://git.miskam.xyz/mxm/exivo-cli.git
cd exivo-cli
make install                    # installs to /usr/local/bin
# or pick another prefix:
make install PREFIX=$HOME/.local

make uninstall removes it again, make check runs a syntax/shellcheck pass.

Authentication

The API uses HTTP Basic Auth. Create API_KEY / API_SECRET in the exivo customer application under API Settings (requires the Connectivity service, enabled in the Partner app). The secret is shown only once — store it safely.

export EXIVO_API_KEY="..."
export EXIVO_API_SECRET="..."
export EXIVO_SITE_ID="..."        # uuid of your site

Alternatively pass --key, --secret, --site as global options.

Usage

exivo [global options] <group> <action> [options]

Global options: --raw (unformatted JSON), --dry-run (print the equivalent curl command instead of executing), --host (override API base URL).

Run exivo --help for the full reference.

Command groups

Group Actions
site info
person list get create update delete revoke unrevoke set-pin reset-pin assign-group unassign-group assign-medium unassign-medium assign-key unassign-key
medium list get register unregister activate block
digitalkey list get register unregister activate block
accessgroup list get create update delete assign-zone unassign-zone
accesszone list get
component list get unlock set-mode
visit list get create revoke
digitalkeyvisit list get create revoke
timeprofile list get create update delete
specialday list set
accesslog person [id] component [id] (with --from/--to/pagination)
swisspass search register
connectionstate site component
alias refresh list set rm

All list endpoints support --skip --limit --sort --sort-dir. Payload flags build JSON safely via jq; --data '{...}' merges arbitrary fields; the literal value null clears optional fields (exivo update semantics).

Examples

exivo site info
exivo person list --limit 5
exivo person create --first-name Max --last-name Muster --email max@example.com
exivo person assign-group max-muster general
exivo component unlock haupteingang
exivo component set-mode haupteingang --mode open
exivo accesslog component haupteingang --from 2026-08-14 --to 2026-08-16
exivo --dry-run visit create --code 4281 --valid-from 2026-08-20T08:00:00Z \
  --valid-to 2026-08-20T18:00:00Z --components haupteingang --email gast@example.com

Aliases

Instead of UUIDs you can use human-friendly aliases everywhere an ID is expected:

exivo alias refresh     # build alias file from live identifiers/names
exivo alias list        # show aliases
exivo alias set front-door 8cefae41-2a21-40ca-a8b7-d1d523ad6131
exivo alias rm front-door

alias refresh slugifies component identifiers, access zone/group names, person names and time profile names ("Büro 6"buero-6) into ~/.config/exivo/aliases.<siteId> (override with EXIVO_ALIASES). Collisions get a numeric suffix. Original names also work:

exivo component unlock haupteingang
exivo component get "Büro 6"
exivo accesslog person christin-baumert --limit 5

Re-run alias refresh after adding persons/components on the site.

Notes & API quirks

  • Access log is read-only — entries are created by real door events only.
  • component unlock returns 204 when the request is accepted; there is no guarantee the door physically opened. Check connectionstate first.
  • The API rejects POST requests without Content-Type: application/json — the CLI always sends it (empty body becomes {}).
  • person update only changes submitted fields; send null to clear optional ones.
  • Assigning a new medium to a person blocks their previously active medium.
  • A person has exactly one access group but may hold multiple media.
  • Timestamps are RFC 3339 UTC; the site info endpoint reports the local time zone.

License

MIT