Skip to main content
haau3 is the platform API’s open-source command line, for developers and their coding agents. It checks that a project is ready to call the API, makes one call to each service, and puts an API key in the project’s env file without ever showing it. Its source is haau3/haau3-cli (MIT), and it runs with npx:
It needs Node.js 22 or later, whatever language the project is in. It makes its calls through the TypeScript SDK, and sends a key only to api.haau3.com, sandbox.haau3.com or this computer.

From nothing to a first call

1

Try it in the Sandbox

The Sandbox answers each operation’s documented example with no key and no account. From your project’s folder:
doctor says what the project still needs. With no key, test makes one call to each service in the Sandbox, which uses 9 of the 30 requests an hour each address gets there.
2

Make a live key

login prints a page and a short code. A person opens the page in any browser, signs in, picks or creates an organization, and approves. A new organization starts on the Developer plan, which is free. keys create then makes a live key and writes it to the project’s env file as HAAU3_API_KEY, and prints its prefix, name and id, never the key. Making a key ends the sign-in, so each key takes its own approval.
3

Load the key in your app

The SDKs read HAAU3_API_KEY from the environment, so the program loads the env file when it starts:
  • Next.js loads .env.local and .env into process.env itself.
  • Node.js: node --env-file=.env index.ts, or process.loadEnvFile(). Vite keeps an env file’s values out of process.env, so a Vite app’s server code loads the file this way too.
  • Python: python-dotenv’s load_dotenv(), or set -a; . ./.env; set +a in the shell before the program.
  • Go, or any program: set -a; . ./.env; set +a in the shell before the program.
Then npx haau3 doctor checks the key, its file, and a call that proves the key works.
A test key is optional: npx haau3 keys create --test makes one, which reaches the Sandbox only. It raises the Sandbox’s limit to your plan’s requests a minute, and its calls never count toward your plan’s month (see test and live keys).

doctor

Checks whether the project in the current folder is ready to call the API. It reads the key where the app will: the environment, then the project’s env files as its loader reads them (.env.local, then .env for Next.js or Vite; .env otherwise). --file <file> reads that env file instead. Each check passes, warns, fails, or is skipped when the check it waits on did not pass, and each carries the commands that fix it. doctor exits 1 when a check fails. It never prints the key or any part of it.

test

Makes one call to each service, the first operation of each in the published spec, read from the host the calls go to. Each call sends the operation’s own example request and nothing you type.
  • test <service> calls one service, and --all every operation of it. --all alone runs every operation of every service, with a key only.
  • With no key it calls the Sandbox with no key. A test key calls the Sandbox, a live key production.
  • Each call says what kind of answer came back, its request id and its time, and never prints the answer. A run stops at a 429, a refused key, a key in the wrong mode, an unreachable host or a timeout.
  • In production, Pharmacy Benefits answers that it is not yet open to customers, which test counts as a pass.
  • A call answered does not say a service is licensed, under an agreement or ready for production.
The services are scheduling, fhir-base, terminology, provider-directory, questionnaires, medical-benefits, pharmacy-benefits, medlist and structured-sig, each its tag in the API reference.

login

Signs in with the OAuth 2.0 device authorization grant (RFC 8628): it prints a page and a short code, which lasts 10 minutes, and a person approves in any browser and picks an organization. At a terminal it waits for the approval. With no terminal, as when a coding agent runs it, it prints the page and the code and exits, and login --complete waits:
login --complete waits at most 100 seconds and can be run again while it says approval-pending. A session lasts at most an hour, and a session can do only what its member can do on the dashboard. It is kept in the system’s credential store, or in a file only you can read with HAAU3_SESSION_STORE=file.

whoami

Who is signed in, the organization, its plan and this month’s use, and when the session ends.

logout

Ends the sign-in and the approval behind it.

keys create

Makes an API key for the signed-in organization and writes it to the project’s env file as HAAU3_API_KEY. It prints the key’s prefix, name and id, never the key. The key is live unless --test asks for a test key, and the dashboard’s API keys page lists it, marked as made from the command line, where it can be revoked like any other.
  • --name <name> names the key. By default the name says haau3 made it, for which folder and on which day.
  • --file <file> writes to that env file. By default it writes to the file that already holds the key, else .env.local, else .env, else a new .env.local for Next.js or Vite and .env otherwise. The flag is --file, never --env-file, which Node.js takes as its own.
  • --replace replaces a key the file already holds. The old key is not revoked.
In a git repository it writes only to a file git ignores. Otherwise it refuses, makes no key, and names the line to add to the .gitignore. Making a key ends the sign-in.

For coding agents

When a coding agent runs it, every command prints one JSON document on stdout and never waits on a person. An agent:
  1. Runs npx haau3 doctor --json first, branches on ok, and runs the commands each check names.
  2. With no account, calls the Sandbox: npx haau3 test --json, and HAAU3_ENVIRONMENT=sandbox for the app.
  3. For a live key, runs npx haau3 login, gives the person the page and the code it prints, then runs npx haau3 login --complete and npx haau3 keys create. The key goes into the env file, never through the chat, so the agent never asks for one and never prints the env file.
The haau3 skill tells an agent the same.

The JSON document

At a terminal haau3 prints readable text. Anywhere else, such as a pipe, a file or a coding agent, each command prints one JSON document, errors included, and never a prompt, a spinner or colour. --json asks for it at a terminal too, and HAAU3_OUTPUT=json or HAAU3_OUTPUT=text chooses either. An unknown command:
  • Branch on ok. Every field is always present. On failure data is null, except for doctor and test, whose report is in data either way.
  • error.code is what to branch on, and error.next, or data.next on success, lists the commands to run next.
  • When the API’s answer is the failure, error.problem carries its problem: its type, title, status, code and requestId.
  • formatVersion is the shape’s version. A new minor version only adds fields; refuse a major version you do not know.
Exit codes: 0, it worked; 1, it ran and something failed; 2, it was used wrongly.

What it never does

  • It never shows a key. No flag prints one, and none is in its output or its errors.
  • It never prints an answer’s body.
  • It sends only the spec’s own example requests, never a payload you give it.
  • It never edits a .gitignore.
  • It sends a key only to api.haau3.com, sandbox.haau3.com or this computer.

Environment variables