CommCare Nova Docs

API keys

Connect a tool to Nova without going through a browser sign-in.

API keys are the alternative to signing into Nova through your browser. Mint one in settings, paste it into your tool's config, and it stays connected.

When to use one

Use OAuth (the default) for the everyday case: a person, a browser, one tool at a time. You sign in once and the tool stays connected until you revoke it.

Pick an API key when you want any of these:

  • An unattended pipeline that runs while you're not at the computer.
  • Multiple parallel tools or agents using the same Nova account at the same time.
  • A shared bot account that several scripts speak through.

OAuth's sign-in needs a person at a browser, and parallel tools sharing one OAuth sign-in fight each other every time their connection refreshes. API keys don't have either problem.

Mint a key

Open Settings → API keys on commcare.app, signed in as the account that should own the key.
Click + New key and pick a name. The name only shows up in your keys list — it doesn't affect what the key can do.
Pick the scopes. Read and Write are required. Add the HQ scopes if your tool needs to upload finished apps to CommCare HQ.
Pick an expiry. 1 year is the default. Pick shorter if you want tighter rotation, or Never expires for credentials you'll rotate manually on your own schedule.
Click Mint key. The next screen shows the full key once — copy it now. Nova hashes it after that, so if you lose the full value you'll have to mint a new one.

Use it with Claude Code

The setup depends on whether you have the Nova plugin installed.

With the plugin

The plugin reads NOVA_API_KEY from your environment. Set it to your key value and the plugin authenticates with it automatically — no extra commands, no second server entry:

export NOVA_API_KEY="sk-nova-v1-YOUR_KEY_HERE"

Replace sk-nova-v1-YOUR_KEY_HERE with your actual key value. Put the export line in your shell profile (~/.zshrc, ~/.bashrc) so it's set every time Claude Code starts.

Leave NOVA_API_KEY unset to use browser sign-in instead — the plugin falls back to the OAuth flow on its own.

Stuck on Needs authentication even with a key set? If an earlier sign-in failed, Claude Code remembers that failed state and keeps skipping the connection — even once the key is valid. Clear it by deleting ~/.claude/mcp-needs-auth-cache.json, then restart Claude Code. (The /mcp → Clear authentication option doesn't clear this one.)

Without the plugin

Add the server directly. Drop a config block in your project's .mcp.json or a user-scope file at ~/.claude.json, with the full key value in the Authorization header:

{
  "mcpServers": {
    "nova": {
      "type": "http",
      "url": "https://mcp.commcare.app/mcp",
      "headers": {
        "Authorization": "Bearer sk-nova-v1-YOUR_KEY_HERE"
      }
    }
  }
}

Replace sk-nova-v1-YOUR_KEY_HERE with your actual key value.

To keep the key out of a committed file, set it in your environment and reference it as "Bearer ${NOVA_API_KEY}" — Claude Code fills it in at startup. The variable has to be set: if it's missing, Claude Code won't start the nova server and tells you which variable is unset (a hand-added entry like this has no OAuth fallback to catch you). Want browser sign-in instead? Omit the Authorization header entirely and Claude Code runs the OAuth flow.

Scopes

Each key can have any combination of these:

ScopeWhat it grants
nova.readList, read, and search apps in your account. Required.
nova.writeCreate and edit apps. Required.
nova.hq.readLook up which CommCare HQ project spaces your stored API key can reach.
nova.hq.writeUpload finished apps to CommCare HQ.

Set scopes when you mint, change them later from the kebab menu → Edit scopes. Read and write are the floor; nothing in Nova works without them.

Rotating and revoking

Every key in the list shows when it was last used and when it expires. To rotate, mint a new key, point your tool at the new value, then revoke the old one — there's no in-place rotation, because Nova only keeps the hash.

To revoke, click the kebab on the row → Revoke → confirm. The next call from that key fails immediately.

API keys and OAuth sign-ins are independent. Minting a key doesn't disturb any browser sign-ins on the same account, and revoking either kind doesn't touch the other.