The credenco-cli Command-Line Client
credenco-cli is a single binary that drives the public Credenco Business Wallet API from a
terminal. It covers 81 operations in 15 command groups, and on top of those there are four
hand-written workflow commands that chain several calls into one: issue, verify, revoke and
wallet create.
Five tag groups of the public API are deliberately left out of the generated surface and have no command: Direct Issue Credential, Verify a Credential, Integration Channels, Integration Deliveries and Public Integration Schemas. Use the API directly for those, or the web interface.
It is meant for three kinds of user:
- Operators, who need a wallet set up, a template created or a credential revoked without clicking through the web interface.
- Integrators, who want to see the exact request and response of an API call before writing it into their own backend.
- AI agents, which can discover the whole command surface from the binary itself. That use is described separately in Driving credenco-cli from an AI agent.
Every terminal screen on these pages is a capture of a real run against a Credenco test
environment, issuing and presenting the Bank Account credential built up in
Usage examples. Commands, flags, field names, statuses and response bodies
are verbatim. Three things are normalised for readability: the host name is written as
wallet.acc.credenco.com, home directories are shown as ~, and secrets are redacted.
Install
Pre-built binaries for macOS, Linux and Windows (amd64 and arm64) are published on this site. The install scripts detect your OS and architecture, check the download against its SHA-256 checksum and install without admin rights. Run the same command again to upgrade.
macOS, Linux and WSL
curl -fsSL https://docs.credenco.com/cli/install.sh | sh
The binary goes to ~/.local/bin. The script tells you if that directory is not on your PATH.
Windows
In PowerShell:
irm https://docs.credenco.com/cli/install.ps1 | iex
The binary goes to %LOCALAPPDATA%\credenco-cli, which the script adds to your user PATH.
Open a new terminal afterwards.
Check the installation
credenco-cli --version
Specific version or manual download
To install a specific version, set CREDENCO_CLI_VERSION before running the script:
curl -fsSL https://docs.credenco.com/cli/install.sh | CREDENCO_CLI_VERSION=v1.2.0 sh
To download an archive yourself, take credenco-cli_<os>_<arch>.tar.gz (.zip for Windows) from
https://docs.credenco.com/cli/latest/, or from https://docs.credenco.com/cli/v<version>/ for a
specific version. <os> is darwin, linux or windows and <arch> is amd64 or arm64.
Verify the archive against checksums.txt in the same directory, unpack it and put
credenco-cli on your PATH.
macOS blocks a binary downloaded with a browser because it is not notarized. The install script
does not have this problem. For a browser download, clear the quarantine flag once:
xattr -d com.apple.quarantine credenco-cli.
Authenticate once with login
credenco-cli login [host] works like az login. It asks for the host if you leave it out, then
for an API key or an OAuth2 client id and secret. It verifies the credentials against the wallet,
lets you pick a default wallet, and writes everything to ~/.credenco/config.json (directory
0700, file 0600).
$ credenco-cli login wallet.acc.credenco.com
Logging in to https://wallet.acc.credenco.com
Authentication method:
[1] API key
[2] OAuth2 client credentials
Select [1]: 1
API key:
Verifying credentials...
Default wallet: Tulip Trust Bank (2a0ae7d8-2b17-4d05-94ab-02a1cc74606f)
Login succeeded, saved as profile "default" in ~/.credenco/config.json
The key you type is not echoed. The capture above asks only twice, because the host was given as an argument and the credentials saw a single wallet, which is then chosen for you. With more than one wallet, a numbered list follows and you pick one.
The answers are read line by line, so a login can also be scripted by piping them into the command, which is how the capture above was made.
Profiles
Each login is stored as a named profile. The first one stored becomes the current one; pick
another for a single command with --profile or CREDENCO_PROFILE, or switch for good with
credenco-cli profile use.
$ credenco-cli profile list
NAME HOST WALLET AUTH
acme https://wallet.acc.credenco.com 9a5660e4-c113-4e15-8610-831dbb616b83 oauth
ada https://wallet.acc.credenco.com a6f8b20e-3bb0-44b5-b11d-ed35a28c6147 api-key
* tulip-bank https://wallet.acc.credenco.com 2a0ae7d8-2b17-4d05-94ab-02a1cc74606f api-key
The * marks the current profile. credenco-cli logout removes the whole file, all profiles
included; environment variables are left alone.
Discover the commands
credenco-cli operations prints every command with its HTTP method and path, grouped by API tag.
The command table is generated from the Business Wallet's own public OpenAPI document rather than
hand-maintained, so a command's method, path and required fields follow the API. The listing is
always plain text, piped or not.
$ credenco-cli operations
CREDENTIAL
credential delete-wallet-holder-credential DELETE /api/v1/wallets/{walletExternalKey}/credentials/{credentialExternalKey} Delete a wallet credential [--yes]
credential get-wallet-holder-credential GET /api/v1/wallets/{walletExternalKey}/credentials/{credentialExternalKey} Get a single wallet credential
credential list-wallet-holder-credentials GET /api/v1/wallets/{walletExternalKey}/credentials List all wallet credentials
CREDENTIAL-REVOCATION
credential-revocation revoke-credential POST /api/credential/revoke/{revocationUuid} Revoke an issued verifiable credential [--yes]
...
WALLET-MANAGEMENT
wallet-management create-wallet POST /api/wallets Create a new wallet for the caller
wallet-management delete-wallet DELETE /api/wallets/{walletExternalKey} Delete an existing wallet [--yes]
wallet-management get-all-wallets GET /api/wallets List all accessible wallets
wallet-management get-wallet GET /api/wallets/{walletExternalKey} Get a single wallet's details
wallet-management patch-wallet PATCH /api/wallets/{walletExternalKey} Partially update an existing wallet
wallet-management update-wallet PUT /api/wallets/{walletExternalKey} Fully update an existing wallet
81 operations in 15 groups
Per-group and per-command help works as you would expect, and the per-command help lists the field flags generated from the request body:
credenco-cli --help
credenco-cli wallet-management --help
credenco-cli issuer-template create-issuer-template --help
Request bodies
A request body can be given as inline JSON, as @file, or as @- to read standard input. On top
of that, most top-level fields of the body are also a flag, and a flag overrides the same field in
--body. Two kinds of field get no flag and stay --body only:
- Nested structures, such as
attributes,displays,queryDefinitionandclaims. Lists of plain strings do get a flag, taking a comma-separated or repeated value. - Secrets and one-time codes, any field whose name contains
passwordorsecret, pluscode,tx_codeandverificationCode. A flag would leak them into shell history and the process table, for the same reason the API key has no flag.
credenco-cli public-profile patch-public-profile --body '{"website":"https://tulip-trust-bank.example"}'
credenco-cli public-profile update-public-profile --body @public-profile.json
credenco-cli public-profile patch-public-profile --phone-number "+31 30 123 4567" --address-city Utrecht
credenco-cli role create-role --name Admin --wallet-roles WALLET_READ,WALLET_CRUD
The wallet path parameter is bound to --wallet and CREDENCO_WALLET rather than to a positional
argument, so a configured default wallet applies to every wallet-scoped command. All other path
parameters are positional.
Output
For a command that calls the API, output is a table when standard output is a terminal and JSON
when it is piped. --json and --table force a format. Progress messages, QR codes and errors go
to standard error, so a piped standard output is always valid JSON and can go straight into
jq.
The local commands that print no API response are the exception: operations, profile list and
every --help are plain text whether piped or not.
credenco-cli wallet-management get-all-wallets | jq -r '.content[].displayName'
Safety
Destructive commands refuse to run without --yes, and --dry-run prints the request that would
be sent and sends nothing at all, not even an OAuth token request.
$ credenco-cli issuer-template delete-issuer-template bank-account-issuer
error: issuer-template delete-issuer-template is destructive; pass --yes to confirm (or --dry-run to preview)
exit code: 2
--dry-run is safe on a destructive command even without --yes, because it changes nothing. It
is just as useful to preview an update, such as a change to the wallet's public profile:
$ credenco-cli public-profile patch-public-profile --website https://tulip-trust-bank.example --dry-run
{
"dryRun": true,
"method": "PATCH",
"url": "https://wallet.acc.credenco.com/api/v1/wallets/2a0ae7d8-2b17-4d05-94ab-02a1cc74606f/public-profile",
"headers": {
"Accept": "application/json",
"Content-Type": "application/json",
"x-api-key": "[REDACTED]"
},
"requestBody": {
"website": "https://tulip-trust-bank.example"
}
}
Exit codes
| Code | Meaning |
|---|---|
0 | success |
1 | unexpected local failure (network, I/O, malformed response) |
2 | usage error or missing configuration |
3 | authentication or authorisation failure (401, 403) |
4 | not found (404) |
5 | server error (5xx) |
6 | any other API error (4xx) |
The distinct codes exist so a script, a CI job or an agent can branch on the kind of failure without parsing the message:
$ credenco-cli issuer-template get-issuer-template no-such-template
{
"detail": "Issuer template not found",
"instance": "/api/v1/wallets/2a0ae7d8-2b17-4d05-94ab-02a1cc74606f/issuer-templates/no-such-template",
"status": 404,
"title": "Not Found"
}
error: GET https://wallet.acc.credenco.com/api/v1/wallets/2a0ae7d8-2b17-4d05-94ab-02a1cc74606f/issuer-templates/no-such-template returned 404: Issuer template not found
exit code: 4
$ CREDENCO_BASE_URL=https://wallet.acc.credenco.com CREDENCO_API_KEY=not-a-real-key credenco-cli wallet-management get-all-wallets
{
"error": "Unauthorized"
}
error: GET https://wallet.acc.credenco.com/api/wallets returned 401: Unauthorized
exit code: 3
Environment variables
Settings come from three places, each overriding the one before: the selected profile, then
CREDENCO_* environment variables, then flags.
| Variable | Purpose |
|---|---|
CREDENCO_PROFILE | stored profile to use (flag: --profile) |
CREDENCO_BASE_URL | Business Wallet base URL, for example https://wallet.acc.credenco.com |
CREDENCO_API_KEY | API-key authentication, sent as the x-api-key header |
CREDENCO_CLIENT_ID | OAuth2 client-credentials client id |
CREDENCO_CLIENT_SECRET | OAuth2 client secret |
CREDENCO_TOKEN_URL | Keycloak token endpoint |
CREDENCO_WALLET | default wallet external key (alias: CREDENCO_TENANT_KEY) |
Either CREDENCO_API_KEY or the OAuth2 client-credentials pair works for every command.
Read API Keys and Client ID for how to
obtain them.
CREDENCO_API_KEY and CREDENCO_CLIENT_SECRET have no flag equivalent. A flag would write
the secret into your shell history and expose it in the process table, where any local user can
read it with ps. Use credenco-cli login, your environment or a secret manager.
Stored credentials are only ever sent to the host they were stored for. Pointing the CLI somewhere
else drops them, so a key for one environment cannot leak into a request to another. Any of
--base-url, CREDENCO_BASE_URL, --token-url and CREDENCO_TOKEN_URL counts as pointing
somewhere else, so setting a token URL that differs from the stored one also drops the stored key
and the next command fails with "no credentials" and exit code 2. Credentials that came from the
environment are kept, since whoever set them also chose the host.
The CLI redacts Authorization and x-api-key everywhere it prints a request, including in
--dry-run output.
Next
- Usage examples walks a Bank Account credential from an empty wallet all the way through issuance and presentation, with the real terminal output of every step.
- Driving credenco-cli from an AI agent covers the same ground as a series of natural-language requests and the commands an agent turns them into.