Command line
Sign in and choose a company
Connect the CLI to the hosted Oatmilk or your own, with your browser, another device or an API key.
The CLI signs in the way an AI app does: you approve it in your browser, and it acts as you. Your role in each company still decides what it can see and do. For scripts and CI, an API key works instead.
1. Choose the Oatmilk to connect to
Without --host, the CLI talks to the hosted Oatmilk at https://app.getoatmilk.com. For any other Oatmilk, pass its address once when you sign in; the CLI remembers it for later commands.
| Oatmilk | Address |
|---|---|
| The hosted Oatmilk | Nothing to add |
| Your own, on this computer | --host https://oatmilk.localhost |
| Your own, on a server | --host https://books.example.com |
A development server from bun run dev | --host localhost:3000 |
The address is read from --host first, then the OATMILK_HOST environment variable, then the last address you signed in to. Addresses must use https; plain http is allowed only for localhost.
2. Sign in with your browser
oatmilk login
# or, for your own Oatmilk:
oatmilk login --host https://books.example.com- Your browser opens Oatmilk's sign-in page. Sign in if you aren't already.
- Oatmilk shows what the CLI asks for. Choose Allow.
- The page says you're signed in. Go back to the terminal: it shows your email, company and role.
The browser sends the sign-in back to a one-time address on your own computer (http://localhost:<port>/callback), so nothing to copy. If no browser opens, the CLI prints the address to open; --no-browser or OATMILK_NO_BROWSER=1 always prints it instead.
Sign in on another device
Over SSH, in a container, or on a machine without a browser:
oatmilk login --device- The CLI prints an address. Open it on any device: your laptop or your phone.
- Sign in and choose Allow.
- Oatmilk shows a code with a Copy code button. Paste it into the terminal.
The code only works for the terminal that asked for it, and only once.
Sign in with an API key
An API key belongs to one company and keeps exactly the permissions it was given, so it suits scripts, CI and shared machines. Create one in Developers › API keys in Oatmilk, then:
oatmilk login --api-key # asks for the key without showing it
echo "$KEY" | oatmilk login --api-key # or pipe it inFor a single command or a CI job, skip login and set the key in the environment. OATMILK_API_KEY and OATMILK_TOKEN (an OAuth access token) win over a saved sign-in.
OATMILK_API_KEY=oat_live_… oatmilk whoami3. Check who you are
oatmilk whoami
oatmilk whoami --jsonIt shows your email, the company, your role, the address and how you signed in. With an API key it also lists the key's permissions.
4. Choose a company
A browser sign-in can open every company you belong to. The CLI works in one at a time, and oatmilk whoami shows which.
oatmilk orgs # the companies you can open; ● marks the current one
oatmilk orgs use "Contoso" # switch by name or ID
oatmilk api entries.list --org org_2abc… # one command in another companyOATMILK_ORG sets the company for every command. An API key always works in its own company, so orgs use asks you to sign in with the browser instead.
Your own Oatmilk
A self-hosted Oatmilk signs you in through its own accounts, with the same steps. Two things differ on this computer's *.localhost address:
- The certificate. Oatmilk's local HTTPS certificate comes from its own certificate authority, which Node.js doesn't trust by default. Point
NODE_EXTRA_CA_CERTSat the filebun run self-host certsaves, in every terminal that runs the CLI:
export NODE_EXTRA_CA_CERTS="$HOME/oatmilk/self-host/oatmilk-local-ca.crt" # where your Oatmilk checkout is
oatmilk login --host https://oatmilk.localhost- The name.
*.localhostnames always mean this computer. The CLI knows that without an/etc/hostsentry.
A server with a real domain and a Let's Encrypt certificate needs neither.
Sign out
oatmilk logout # this address
oatmilk logout --all # every address you signed in toSigning out revokes the browser sign-in, so the saved token stops working everywhere. To stop an API key, delete it in Developers › API keys.
Where sign-ins are saved
Sign-ins live in credentials.json in ~/.config/oatmilk ($XDG_CONFIG_HOME/oatmilk when that is set, %APPDATA%\oatmilk on Windows). Only your user can read it. OATMILK_CONFIG_DIR moves it, for example to keep a separate sign-in per project. Browser sign-ins refresh themselves; run oatmilk login again if one stops working.
When it goes wrong
| Message or exit code | What to do |
|---|---|
Exit code 3, "You're not signed in" | Run oatmilk login, or set OATMILK_API_KEY. |
| "Oatmilk addresses must use https" | Use https://…. Only localhost may use http. |
| "That isn't an Oatmilk API key" | Keys start with oat_. Copy the whole key again. |
A certificate error on *.localhost | Set NODE_EXTRA_CA_CERTS as shown in Your own Oatmilk. |
Exit code 4, not allowed | Your role, or the key's permissions, don't allow that action. Check with oatmilk whoami. |
| The browser never comes back | Cancel with Ctrl+C and use oatmilk login --device. |