Tendrl CLI: Command Reference
Commands read as product → resource → verb: tendrl-cli contact entities list, tendrl-cli strand runs get <id>, tendrl-cli surface scan file ./report.pdf. Run any group with --help for its full options.
This page is the map. Each product has a detailed reference with every command's options, request-body fields, and examples:
- Contact commands — entities, messages, files, fanouts, dashboards, alerts, services, access control, deployments
- Strand commands — workflows, versions, runs, connectors, functions, vault, team
- Surface commands — scans, history, profiles, account, keys
- Options Reference — every command's arguments and flags with types and defaults, generated from the CLI itself
Global flags#
| Flag | Effect |
|---|---|
--json |
Print the raw API response to stdout (for jq and scripts) |
--app-url <origin> |
Target another environment (default https://app.tendrl.com) |
--data '<json>' / -d |
JSON request body for create/update commands (- reads stdin) |
--file <path> / -f |
Read the JSON body from a file instead |
--limit / --offset |
Paging on list commands |
--yes / -y |
Skip the confirmation prompt on destructive commands |
Session & account#
| Command | What it does |
|---|---|
login / logout |
Sign in with email + password; revoke and forget the session |
whoami [--permissions] |
Signed-in user, active account, and optionally your role's allowed actions |
accounts list |
Accounts you belong to |
accounts switch <name> |
Switch the session's active account |
accounts show |
Active account details |
billing plans [--product] |
Public plan catalog |
Contact#
Uses your Contact account key (TENDRL_API_KEY). Details: Contact commands.
| Group | Verbs | Notes |
|---|---|---|
entities |
list get create update delete reboot heartbeat state provision-payload rotate-key boards |
Create returns the entity key once. Create/update bodies require a role (e.g. DefaultEntity). Provisioning verbs need an MQTT-enabled entity |
messages |
list get search export |
Read-only by design — publishing is the device SDKs' job |
files |
list get upload download rescan delete |
upload --dest <entity> sends a file to a device |
fanouts |
list get create delete add remove publish |
Groups of entities; publish fans a message out to every member |
directories |
list get create delete move |
Fleet tree; directories are addressed by id |
dashboards |
list get fields query |
query runs the batched widget-data endpoint |
alerts |
list get create update delete test |
Triggers: entity_offline, entity_online, message_condition |
flows |
list get connectors connector-templates test-connector |
Message routing |
services |
list get create delete validate |
Payload schemas; validate checks a service definition |
insights |
summary usage messages entities validation flows |
usage is your data usage against plan limits |
keys |
list get create rotate delete |
Account API keys; tokens shown once on create/rotate |
users |
list invite invites revoke-invite set-role remove |
Team management |
roles / policies |
list get create delete |
IAM; built-in roles can be listed but not fetched by id |
audit |
list export |
Audit log (Standard plan and up) |
deployments |
list get create deploy |
OTA: create takes local app files (--name, --entry, --no-scan) |
Strand#
Uses your Strand key (STRAND_API_KEY). Details: Strand commands.
| Group | Verbs | Notes |
|---|---|---|
workflows |
list get create update delete run save versions export import schedule-presets |
Every save mints an immutable version; export/import round-trip as JSON files |
runs |
list get steps cancel approve reject |
approve/reject act on a paused approval step (--comment for the audit trail) |
connectors |
list get create delete test types ai-models |
ai-models lists available AI models by provider |
functions |
list get create delete test |
test <id> runs a saved function; test --code-file fn.py runs unsaved code |
vault |
list set delete |
Encrypted secrets; values are never returned |
configurations |
list get create delete |
Named JSON config blobs workflows can read |
templates |
list get readiness use |
use creates a workflow from a template |
keys |
list create rotate delete |
Strand API keys |
team / roles |
list invite set-role remove / list get permissions |
Role names resolve automatically (--role Viewer) |
usage |
current history breakdown summary |
Runs against plan limits |
audit |
— | Audit log (Standard plan and up) |
whoami |
— | The account and role behind your Strand key |
Surface#
Uses your Surface key (SURFACE_KEY). Details: Surface commands.
| Group | Verbs | Notes |
|---|---|---|
scan |
file payload get |
--local targets a running scanner daemon instead of the hosted API |
history |
list get export |
Scan history; export needs a plan with data export |
account |
show usage analytics blocked-ips |
usage is always available, even on Free |
profiles |
list get create update delete test-webhook |
allowed_types is a comma-separated string, e.g. "pdf,txt" |
keys |
list create delete |
Surface API keys |
Local configuration#
| Command | What it does |
|---|---|
config show |
Current config with secrets masked |
config path |
Where the config file lives |
config set-url <origin> |
Persist a platform URL |
config set-scanner <url> |
Persist a local scanner daemon URL for scan --local |
config set-key <product> [key] |
Store an API key (prompts if omitted) |
config unset-key <product> |
Remove a stored key |
The escape hatch#
Anything without a curated verb is still reachable — same credentials, any customer endpoint:
tendrl-cli api contact GET /entities/<id>/heartbeat
tendrl-cli api strand POST /workflows/<id>/run -d '{"data": {}}'
tendrl-cli api surface GET /account/history -q limit=5
-q key=value adds query parameters (repeatable); -d/-f supply a body.
The CLI shows the platform's own error reasons — a 403 names the missing role action or plan feature, a 422 names the missing field. When a body shape isn't obvious, the Contact API reference, Strand API reference, and Surface API reference document the request schemas.
Tendrl