The ngris API from your terminal
Overview
ngris api turns the whole ngris API into commands: your applications, endpoints and their users, domains, databases, firewall, account and more, with your API key or an account key. It needs ngris 0.5.0 or later.
- One command:
ngris api <resource> <action>, for examplengris api apps list. - The shell:
ngris apion its own, with tab completion and history. - Any API path:
ngris api request <METHOD> <path>, for anything without its own command, such as a file download.
The tunnel and app commands (ngris http, ngris deploy, ngris apps…) stay as they are: see the CLI reference.
$ ngris api apps list
UUID NAME TYPE SOURCE REQUESTS 24H CREATED
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1001 marketing-site static upload 1840 2026-10-12T09:30:00Z
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1002 orders-api managed git 5210 2026-09-30T14:02:00Z
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1003 docs static git 312 2026-08-21T08:15:00Z
Keys
ngris api calls ngris with an API key or an account key, the same key the app commands use. An auth token doesn't work here: it logs in tunnels only.
- Your API key (
ngk_, from User settings → API keys) acts as you, with your role, in your active account. - An account key (
nak_, from Account → Account keys) acts in its own account with the role it was created with, and keeps working when people leave. Use one in CI.
ngris auth --api-key saves the key: it asks for it and doesn't show what you type, or reads it from a pipe. Your auth token stays as it is. --api-key <key> works too, with a warning that the key is then in your shell history.
Each command takes the key from --api-key, else the NGRIS_API_KEY environment variable, else the saved key. A token given with --token or API_TOKEN works only when it is itself an API key or account key. Prefer NGRIS_API_KEY from a secret store: a key on the command line is visible in your shell history and the process list.
The API address is https://api.ngris.com/api/. --api-url or NGRIS_API_URL changes it; it must start with https:// (http:// works only for localhost). ngris api never follows a redirect, so your key only goes to the address you set, over HTTPS.
$ ngris auth --api-key
API key:
API key saved to /home/you/.config/ngris/config.yaml.
# Or pipe it in, for example from a password manager
$ echo "$KEY" | ngris auth --api-key
API key saved to /home/you/.config/ngris/config.yaml.
# Or set it for one command, from your secret store
$ NGRIS_API_KEY="$STAGING_ACCOUNT_KEY" ngris api apps list
$ ngris api apps list
error: ngris api needs an API key or account key: run `ngris auth --api-key` (create one under User → API keys, or Account → Account keys for CI), or set NGRIS_API_KEY
$ NGRIS_API_URL=http://api.example.com/api/ ngris api apps list
error: the API address must start with https://, so your key is never sent unencrypted (http:// is accepted only for localhost): "http://api.example.com/api/"
Commands
A command is a resource and an action: ngris api <resource> <action> [arguments] [flags]. Short names work too: apps for applications, ls for list. Arguments are the ids the path needs, in order; flags are the API's own fields, with hyphens (--page-size for page_size).
ngris api help shows what there is, at three levels:
ngris api help: every resource, with its short names.ngris api help <resource>: its actions and their arguments.ngris api help <resource> <action>: the action's arguments and flags, the API call it makes and the permission it needs. It also says when an account key can't use the action, when the action is a delete or another risky change, and when it returns a secret shown once.
--help after a command shows the same help, for example ngris api apps list --help.
$ ngris api help
ngris api: the ngris API from the terminal, with an API key (ngk_) or an account key (nak_).
Usage:
ngris api Interactive shell: the same commands, with history and tab completion
ngris api <resource> <action> [args] [flags] One command, e.g. ngris api applications list
ngris api request <METHOD> <path> [flags] Any API endpoint, e.g. ngris api request GET /v1/applications
ngris api help [<resource> [<action>]] Help for a resource or an action
Resources:
account-keys (account-key) The account's own API keys (nak_), each with …
accounts (account, acct) The accounts you belong to, and the one your commands act in.
applications (apps, app) Applications: static sites, backends, functions …
…
endpoint-users (endpoint-user) Users: the people and scripts that can sign in …
endpoints (eps, ep) Endpoints: the public hostnames that reach your …
…
$ ngris api help apps
applications (aliases: apps, app): Applications: static sites, backends, functions and WordPress sites, and their settings.
Usage: ngris api applications <action> [args] [flags]
Actions:
create (new) Create an application. Deploy to it next (deploys create, or a git push), …
delete (rm) <uuid> Delete an application with its deploys, environment variables, … [destructive]
get (show) <uuid> Show an application, its endpoints and its settings.
list (ls) List the active account's applications, newest first.
…
[destructive]: the shell asks first; elsewhere it needs --yes.
Run 'ngris api applications <action> --help' for an action's arguments and flags.
$ ngris api help apps list
Usage: ngris api applications list [flags]
Aliases: ls
List the active account's applications, newest first.
GET /v1/applications
Permission: endpoints:read
Paginated: one page by default; --all returns every item.
Flags:
--page <int> default 1, query The page to show, from 1.
--page-size <int> query How many applications per page.
--q <string> query Only applications whose name contains this text.
--source <upload|git> query Only applications deployed this way.
--status <live|deployed|no-deploy> query live: deployed and served by an endpoint; …
Output: --json, --jq <expr>, -q/--quiet (ids only), --all (every page), -y/--yes (no question)
Output and filtering
A list prints as a table; other answers print as their main fields, or as JSON when there is no table for them. Add a flag for something else:
--jsonprints the API's own answer.--jq '<filter>'picks what you need from the answer, with jq's syntax; strings print as plain text. No separate jq install is needed.--allfollows the pages of a list and prints every item. Without it you get one page, and the command tells you when there are more.--quiet(-q) prints ids only, one per line.
In a table, a limit of -1 reads unlimited, or default for limits whose -1 means the built-in default (such as rate_limit_rps). --json and --jq show the answer as the API sent it.
What ngris or a client sent is shown with control characters escaped on your terminal. Written to a file or a pipe, the output stays exact.
$ ngris api apps list --jq '.applications[].name'
marketing-site
orders-api
docs
$ ngris api apps list --quiet
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1001
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1002
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1003
$ ngris api apps list --page-size 2
UUID NAME TYPE SOURCE REQUESTS 24H CREATED
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1001 marketing-site static upload 1840 2026-10-12T09:30:00Z
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1002 orders-api managed git 5210 2026-09-30T14:02:00Z
Showing 2 of 3: add --all for every one.
$ ngris api apps list --page-size 1 --json
{
"applications": [
{
"uuid": "0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1001",
"account_uuid": "0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a4001",
"name": "marketing-site",
"type": "static",
"source": "upload",
…
"requests_24h": 1840,
…
"created_at": "2026-10-12T09:30:00Z",
"updated_at": "2026-10-12T09:30:00Z"
}
],
"page": 1,
"page_size": 1,
"total": 3
}
$ ngris api account entitlements
FEATURE ON LIMIT
custom_domains yes 10
max_endpoints yes unlimited
rate_limit_rps yes default
managed_database yes 3
sso no 0
$ ngris api endpoint-users list <endpoint-uuid>
UUID IDENTIFIER NAME STATUS LAST SEEN
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a3001 maria@example.com Maria Example active 2026-11-04T16:20:00Z
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a3002 ci-bot CI bot active 2026-11-05T07:45:00Z
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a3003 sam@example.com Sam Example invited
Any API path: ngris api request
ngris api request <METHOD> <path> calls any path of the API reference with your key, and prints the answer as JSON. Use it for anything without its own command, such as a file download.
--data '<json>'(-d) sends a JSON body;--data @file.jsonreads it from a file,--data @-from standard input.-f key=value(--field) adds one field to the body, or a query parameter withGETandDELETE. Repeat it for more.--jq '<filter>'picks what you need from the answer.- A
DELETE, or a call the API marks as risky, needs--yes(see Deletes and other risky changes).
The path starts with /, for example /v1/applications?page=2. A full URL is refused, so your key only goes to the API.
ngris api request GET /v1/applications
ngris api request GET /v1/applications --jq '.total'
ngris api request POST /v1/applications -f name=docs -f type=static
ngris api request PATCH /v1/applications/<uuid> --data '{"spa_fallback": true}'
ngris api request PUT /v1/applications/<uuid> --data @settings.json
ngris api request DELETE /v1/endpoints/<uuid> --yes
The interactive shell
ngris api on its own opens a shell with the same commands, without the ngris api in front.
- Tab completes resources, actions and flags; ↑/↓ recall earlier commands;
helplists the commands. - Ctrl-C clears the line you are typing.
exit,quitor Ctrl-D leaves. - The history is kept in
~/.ngris/api_history, readable only by you. A line that holds a key, a token, a password or another secret is never kept.
In a script, pipe commands to ngris api, one per line; blank lines and # comments are skipped. It stops at the first error.
$ ngris api
ngris api shell: the same commands as `ngris api <resource> <action>`. Tab completes, ↑/↓ recall, `help` lists the commands, `exit` or Ctrl-D leaves.
ngris> apps list --quiet
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1001
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1002
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a1003
ngris> exit
printf '%s\n' \
'apps list --quiet' \
'endpoint-users list <endpoint-uuid>' | ngris api
Deletes and other risky changes
Deletes, and changes that are hard to undo, are marked [destructive] in the help.
- In the shell, they ask first. Only a typed
yoryesruns it; anything else, including a pasted answer or Ctrl-C, answers no. - As one command or in a script, they need
--yes(-y). Without it, nothing is changed and the command says what to add.
ngris> endpoint-users delete <endpoint-uuid> <user-uuid>
endpoint-users delete is destructive: DELETE /v1/endpoints/<endpoint-uuid>/rbac/clients/<user-uuid>. Run it? [y/N] n
Not run.
$ ngris api endpoint-users delete <endpoint-uuid> <user-uuid>
error: `ngris api endpoint-users delete` is destructive (DELETE /v1/endpoints/<endpoint-uuid>/rbac/clients/<user-uuid>): run it again with --yes to confirm
$ ngris api endpoint-users delete <endpoint-uuid> <user-uuid> --yes
Secrets are shown once
An action that creates a key or a token, such as a new API key or the access token of an endpoint's user, shows it once. Copy it then: ngris doesn't keep it, and ngris api never writes it to a file. The help of such an action says so.
$ ngris api api-keys create --description ci-deploy
{
"key": "ngk_…",
"uuid": "0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a5001"
}
This is the only time the key is shown: copy it somewhere safe now. ngris doesn't keep it.
Accounts
Your API key acts in your active account. ngris api accounts list shows the accounts you belong to, and ngris api accounts switch --account-uuid <uuid> moves your key to another one. Every terminal, script and CI job that uses the same key moves with it, and the command says so each time.
An account key always acts in its own account: switching doesn't apply to it. Actions an account key can't use say so in their help (Account keys: can't use this command).
$ ngris api accounts list
UUID NAME ROLE ACTIVE DEFAULT
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a4001 Acme Owner yes yes
0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a4002 Acme Staging Admin no no
$ ngris api accounts switch --account-uuid 0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a4002
Switched to account 0192f0a0-7c1e-7d2a-9b3c-4d5e6f7a4002.
Every client that uses this personal API key now acts in this account, including other terminals, scripts and CI jobs.
Commands come from ngris
The list of commands comes from ngris itself, so a new API action is a new command without a CLI update. ngris api keeps that list in ~/.ngris, readable only by you. It never holds a key or a secret, and it grants nothing: ngris checks every call against your key and role.
When the list can't be loaded, ngris api request still works.
In CI
Use an account key kept in your CI's secret store, as NGRIS_API_KEY. Nothing else is needed: every ngris api command in the job picks it up. A job that also runs deploys uses the same key (see CI/CD & Docker).
Add --yes to deletes and other risky changes: without it, they change nothing and say what to add.
name: Nightly app report
on:
schedule:
- cron: "0 6 * * *"
jobs:
report:
runs-on: ubuntu-latest
env:
NGRIS_API_KEY: ${{ secrets.NGRIS_API_KEY }} # an account key (nak_…)
steps:
- run: curl -fsSL https://ngris.com/install.sh | sh
- run: ngris api apps list --all --jq '.applications[] | "\(.name) \(.requests_24h)"'