> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nohead.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> The nohead CLI for developers, CI and coding agents - install, sign in, configure, and read its output.

`nohead` is the command-line interface for Nohead, for developers, CI and coding agents. It calls the public API through the TypeScript SDK, so it can do what an API key can, and every change it makes is recorded in history as made via the CLI. The [command reference](https://docs.nohead.io/cli/commands/global-options.md) lists every command; `nohead <command> --help` prints the same for one.

## Install

The CLI needs Node 26 or newer.

```bash theme={null}
npm install -g @nohead/cli    # or run it without installing: npx nohead
nohead --version              # the CLI's version, then the SDK's
```

> [!TIP]
>
> Pin a version in CI, such as `npx nohead@0.5`, so an upgrade is a change you choose. Until 1.0, any release may break scripts that use the CLI; its [releases](https://github.com/nohead-io/nohead-cli/releases) mark what under **Breaking**.

## Sign in

```bash theme={null}
nohead login    # opens the web app to approve: choose the project, scopes and expiry
nohead whoami   # the key, the project in use and its scopes
```

`nohead login` shows a code and opens the web app, where you check the code matches and choose the project, the [API key](https://docs.nohead.io/guides/api-keys.md)'s scopes and its expiry. The CLI then saves the new key, named after your machine, for its project, in a file only you can read. Over SSH or without a browser, open the link it prints on any device. In a folder linked with `nohead link`, or with `--project` or `NOHEAD_PROJECT`, the key is for that project: the page offers no other. Only approve a code your own terminal just showed: never approve a sign-in from a link someone sent you.

The saved key is for the CLI alone: the [SDKs](https://docs.nohead.io/sdks/overview.md) read `NOHEAD_API_KEY` from the environment, not the CLI's keys. For an app, create a key under **API keys** in the web app and set it as `NOHEAD_API_KEY` in the app's environment.

An API key belongs to one project, so to work on several, log in once for each: the keys are saved side by side. Approving another sign-in from the same machine for the same project replaces the key: the CLI saves the new one, and the earlier one is revoked. To save a key you already have, pipe it in: `echo "$NOHEAD_API_KEY" | nohead login`, or from the clipboard, `pbpaste | nohead login` on macOS (`wl-paste` or `xclip -o` on Linux, `Get-Clipboard` in PowerShell). `nohead logout` forgets the saved key of the project in use; the key itself stays valid until you revoke it in the web app, or approve another sign-in from that machine for that project.

## Projects

Choosing a project chooses its saved key. A command works in the first of:

1. `--project <id>`
2. `NOHEAD_PROJECT`
3. the project in the nearest `nohead.json`, in the current folder or a folder above it
4. the project of the only saved key

With keys saved for several projects and none chosen, a command exits with `2` and lists the projects and the ways to choose one. `nohead whoami` shows the project in use and where it came from.

```bash theme={null}
nohead link prj_...   # this folder and the folders below it use that project
```

`nohead link` writes `nohead.json`, `{ "project": "prj_..." }`, in the current folder. It holds no secret, so commit it: each teammate logs in once with a key of that project, and a coding agent working in the folder stays in its project too. To unlink a folder, delete its `nohead.json`.

In CI, or for an agent that should act with a key of its own, set `NOHEAD_API_KEY` instead of logging in. It wins over saved keys and works in its own project (or the one given with `--project` or `NOHEAD_PROJECT`); `nohead.json` doesn't apply to it.

## Configuration

Flags win over environment variables, which win over `nohead.json` and saved keys.

| Setting | Flag | Environment |
| - | - | - |
| API key | none | `NOHEAD_API_KEY` |
| Project | `--project <id>` | `NOHEAD_PROJECT` (default: the nearest `nohead.json`, then the only saved key; with `NOHEAD_API_KEY`, the key's project) |
| Change note | `--note <text>` | none: kept with record revisions, merges and schema changes |
| Idempotency | `--idempotency-key <key>` | none: the same key and request return the first result for 24 hours |

## Output and exit codes

Scripts and agents can rely on this:

* **stdout** carries only results. With `--json`, exactly one JSON document, the API's representation; `records export` writes JSON Lines.
* **stderr** carries errors, summaries and diagnostics. With `--json`, errors use the API's error envelope, `{ "error": { "type", "message", "request_id", "details" } }`.
* **Exit codes:** `0` success, `1` an API error (validation, authentication, permission, not found, a stale revision, a plan limit, import failures), `2` a usage error (bad arguments, no API key, unreadable files), `3` the API or storage unreachable, `4` an unexpected failure in the CLI (`NOHEAD_DEBUG=1` prints the stack).
* **Retries:** up to 3, reported on stderr. A `429` is retried after its `Retry-After` (up to 60 seconds); network failures and `500`, `502`, `503` and `504` with backoff. Every write carries an `Idempotency-Key`, so a retry never writes twice.
* Deleting a collection and discarding a draft need `--yes`; a discarded draft can't be restored. Everything else is soft-deleted and can be restored.

## Lists and filters

A list prints one page and ends with `More: --cursor <cursor>` when there are more. A page holds 100 (`audit`: 20), and `--limit n` sets another size, up to 100. `search` prints the top 20 results, or `--limit n` up to 100, without pages. `--cursor <cursor>` prints the next page, and `--all` follows the cursors and prints everything. With `--json`, a page prints as the API returns it (`data` and `meta.next_cursor`), and `--all` as `{ "data": [...] }`.

`--filter` takes `key=value`, `key!=value`, `key<value` (and `>`, `<=`, `>=`), `"key in a,b"` (`\,` for a comma in a value), `"key exists"` and `"key !exists"`. Several on one key combine:

```bash theme={null}
nohead records list products --filter "price>=10" --filter "price<50" --sort -price
nohead records list events --filter "starts_on>=today"
```

Dates take `today`, and dates with a time `now`. `records list --status published` (or `unpublished`) filters by `published_at`; across a whole project, `search` filters with `"published_at exists"` (or `!exists`). [Reading content](https://docs.nohead.io/guides/reading-content.md#filter) has how filters match.

## Records and drafts

Record data comes from `--set key=text`, `--set key:=json` (numbers, booleans, null, lists, objects), `--data '{...}'` and `--data-file <path|->`. `update` changes only the fields given; `--set key:=null` clears one.

```bash theme={null}
nohead records create testimonials --set name=Ada --set "quote=Great platform"
nohead records update rec_... --set company=Analytical --if-revision 1 --note "Add the company"
nohead records revert rec_... 1 --dry-run
```

`--if-revision n` refuses the change if someone changed the record since revision `n`. `records schedule` publishes or unpublishes later: a time is ISO 8601 with a time zone (`2026-10-01T09:00:00Z`), an offset from now (`+30m`, `+2h`, `+3d`, `+1w`), or `none` to clear one. `records scheduled <collection>` lists what is coming. A [draft](https://docs.nohead.io/guides/publishing.md#hold-changes-back-in-a-draft) holds changes until it is merged, now (`drafts merge`) or at `--merge-at`; `drafts create` and `update` take the same data flags as records.

## Fields and migrations

Field options are flags: `--description`, `--options a,b` (enum), `--target <collection>` (relation), `--max-length n`, `--min n` and `--max n`, `--include-time` and `--time-zone <zone>` (dates), `--format slug|url|email` and `--unique` (text), and `--searchable`, `--filterable`, `--sortable` (each with a `--no-` form). Field types accept `rich-text` or `rich_text`.

`fields migrate` changes a field in a way that rewrites record values: its type, single or multiple, a stricter configuration, or required with a backfill. Run it with `--dry-run` first to see how every record converts. Without `--no-wait` it waits for the migration and exits non-zero if it fails or is cancelled. While it runs, the collection's fields can't change, and once it is running its records can't either. [Field migrations](https://docs.nohead.io/guides/field-migrations.md) has the rules.

## Schema as code, export and import

`schema pull`, `schema diff` and `schema push` keep a collection's model in `nohead.schema.yaml` in your repository: [Schema as code](https://docs.nohead.io/guides/schema-as-code.md).

`export --output <dir>` writes a project's schema, records, drafts and asset metadata (`--include-history`, `--include-deleted`, and `--include-files` for the originals). `import <dir>` recreates them in another project: the schema first, then the records, relinking relations to the new IDs, then the drafts. Every request has an idempotency key derived from the export, so re-running an interrupted import within 24 hours doesn't duplicate anything. Imported records start a new history.

## Source

The CLI is open source, under the MIT license. Report issues and follow releases on GitHub:


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.