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 example ngris api apps list.
  • The shell: ngris api on 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.

A first command
$ 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.

Save a key
$ 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
Without a key
$ 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 (abridged)
$ 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 (abridged)
$ 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 (abridged)
$ 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:

  • --json prints 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.
  • --all follows 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.

--jq, --quiet, --all
$ 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.
--json (abridged)
$ 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
}
Plan limits and an endpoint's users
$ 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.json reads it from a file, --data @- from standard input.
  • -f key=value (--field) adds one field to the body, or a query parameter with GET and DELETE. 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
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; help lists the commands.
  • Ctrl-C clears the line you are typing. exit, quit or 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.

The shell
$ 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
Commands from a script
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 y or yes runs 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.
In the shell
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.
As one command
$ 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.

A new API key
$ 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).

Your accounts
$ 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
Switch accounts
$ 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.

GitHub Actions
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)"'
Was this helpful?