Skip to content

Command-line interface (CLI) ​

dynm.link manages your links from the terminal and runs an MCP server for agents. It talks to the /v1 REST API 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

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 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).
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); --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, 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.

One short link: redirect, page, file, or QR.