---
url: /cli.md
---
# Command-line interface (CLI)

`dynm.link` manages your links from the terminal and runs an [MCP server](/agents) for agents. It
talks to the `/v1` [REST API](/quickstart) with your API key.

## Installation

```bash
npm install -g @dynm.link/cli
```

Or run it without installing: `npx @dynm.link/cli <args>`.
[`@dynm.link/cli` on npm](https://www.npmjs.com/package/@dynm.link/cli)

## Authentication

```bash
dynm.link login                     # opens your browser to authorize, then stores the key
dynm.link login --key dynm_...      # headless: pass a key (or pipe it: echo dynm_... | dynm.link login)
dynm.link whoami                    # user, plan, folders, API URL
dynm.link logout                    # forget the stored key
```

`dynm.link login` opens the dashboard with a one-time localhost callback; approve while signed in
and the new key comes straight back. On a remote or headless machine, create a key on the
dashboard's [API keys page](https://dash.dynm.link/account/api-keys) and pass it with `--key`.
Either way the key is checked against the API before it is stored.

The key lives in `~/.config/dynm.link/config.json` (`$XDG_CONFIG_HOME/dynm.link/config.json` when
set), readable only by you. A config file that isn't valid fails every command, naming the file,
and is never overwritten: fix it, or delete it and log in again.

### Environment variables

These override the stored config:

* `DYNM_API_KEY` — the API key.
* `DYNM_API_URL` — the API's origin (default `https://api.dynm.link`).
* `DYNM_SPA_URL` — the dashboard `login` opens (default: `dash.` beside the API, so
  `https://dash.dynm.link`).

## Links

```bash
dynm.link link list [--type redirect|text|bio|file] [--domain <host>] [--limit <n>] [--json]   # alias: ls
dynm.link link get <slug> [--domain <host>] [--json]
dynm.link link edit <slug> [--title …] [--description …] [--expires …] [--web <url>]
                           [--preview follow|custom] [--content '<json>'] [--domain <host>] [--json]
dynm.link link remove <slug> [--domain <host>] [--yes]                                           # alias: rm
```

`list` shows every folder, newest first; `--type` and `--domain` filter it. `edit --content`
replaces the content with the link's own type's, whole (the shapes are in
[Link types](/quickstart#link-types)); `--web` and `--preview` change one field of it.

### Create

One subcommand per type:

```bash
dynm.link link create redirect [slug] --web <url> [--ios <url>] [--android <url>] [--rule '<json>']… [--preview follow|custom]
dynm.link link create text     [slug] --body "Some text" [--markdown]     # --body - reads stdin
dynm.link link create bio      [slug] --name "Jason" [--headline …] [--avatar <url>] --link "Site=https://…" --link "GitHub=https://…"
dynm.link link create file     [slug] --file ./brand-kit.zip
```

Every `create` also takes `--title`, `--description`, `--expires`, `--domain` and `--json`, and
generates the slug when it's omitted. `--expires` is `30d`, `12h`, `45m`, a date (`YYYY-MM-DD`) or
`never`; without it a link expires in 30 days. `create file` uploads the file, then creates the
link.

`--rule` takes a full [routing rule](/quickstart#routing-rules), e.g.
`--rule '{"when":[{"op":"in","field":"country","values":["US","CA"]}],"to":"https://…/na"}'`;
`--ios` / `--android` add platform rules ahead of them.

A redirect's share preview follows its destination by default (a share unfurls the destination's
own card); `--title` / `--description` on a redirect need `--preview custom`.
`dynm.link link edit <slug> --preview follow` switches back and clears the title, description and card image.

### Folders: `--domain`

`--domain` picks the folder. It's optional while your account has only its `username.dynm.link`
subdomain, and **required** once you have an active custom domain, so create, get, edit and remove
are never ambiguous. On `list` it's only a filter.

## Errors

A failed command prints one line to stderr and exits 1. An API error prints as its code and
message, e.g. `SlugTakenError: alice.dynm.link/launch is taken.`
