Authentication & API keys
Session cookies for the web app, Bearer API keys for the CLI, MCP server, and automated integrations.
NTHMAP supports two authentication mechanisms, depending on how you're accessing the platform.
Session cookies (web app)
When you sign in at /app, the server sets a nthmap_session cookie that's HttpOnly, SameSite=Lax, and valid for 30 days. Every API call from the browser automatically includes it.
You don't need to do anything — this just works once you're signed in.
Bearer API keys (CLI / MCP / scripts)
For programmatic access from outside the browser — the CLI, the MCP server, your own scripts — use Bearer API keys.
Create a key
Keys are a Pro feature. Once you're signed in to the web app, either:
- Run
nthmap auth loginin the CLI and it will generate one for you interactively, or - POST directly to the API:
curl https://nthmap.com/api/keys/ \
-X POST \
-H "content-type: application/json" \
-b cookies.txt \
-d '{"name":"My laptop","scopes":["read"]}'
The response:
{
"id": 1,
"name": "My laptop",
"key_prefix": "ntm_live_a1b2c3d",
"scopes": ["read"],
"created_at": "2026-04-10T12:34:56Z",
"token": "ntm_live_a1b2c3d4E5fG6hJ7K8L9m0N1o2P3q4R5s6T7u8V"
}
⚠ The full token is only returned once. Copy it now. Only the
key_prefixis stored server-side for lookups — the full token is bcrypt-hashed and cannot be recovered.
Use a key
Pass it in the Authorization header:
curl https://nthmap.com/api/vessels \
-H "Authorization: Bearer ntm_live_a1b2c3d..."
Or set it as an environment variable for the CLI and MCP server:
export NTHMAP_API_KEY=ntm_live_a1b2c3d...
List your keys
curl https://nthmap.com/api/keys/ \
-H "Authorization: Bearer ntm_live_..."
You'll see each key's name, prefix, scopes, last_used timestamp, and created_at. The full token is never returned again after creation.
Revoke a key
curl https://nthmap.com/api/keys/<id> \
-X DELETE \
-H "Authorization: Bearer ntm_live_..."
Revocation is immediate. Any in-flight request with the revoked token will fail on the next call.
Scopes
API keys carry a scopes array. Currently supported:
read(default) — allGETendpointswrite— create/update/delete saved views, drawings, alerts, promptsadmin— admin endpoints (only valid for users withis_admin = true)
A key can only have scopes the underlying user is entitled to. A free-tier user cannot be issued a key at all (the /api/keys/ endpoint returns 402 Pro required).
Security best practices
- Never commit API keys to git. Use environment variables, a secret manager, or a local
.envfile that's.gitignored. - Create a separate key per deployment. Label them by machine, service, or environment so you can revoke surgically.
- Rotate keys periodically. Delete and recreate every 90 days for production integrations.
- Use read scope unless you need write. Principle of least privilege.
- Monitor
last_used. If a key hasn't been used in weeks, revoke it.
Session + API key precedence
If a request includes both a valid session cookie and a valid Authorization: Bearer header, the API key wins. This lets CLI tools running from the same machine as your browser authenticate correctly without accidentally picking up your logged-in session.
Token format
ntm_live_<40 url-safe characters>
ntm_identifies the systemlive_is the environment (future:test_for sandbox)- The remaining characters are a cryptographically-random 30-byte token encoded as URL-safe base64
The first 16 characters (ntm_live_ + 7 random chars) serve as the key_prefix used for database lookup. The full token is bcrypt-hashed with a 11-round work factor.
Rate limiting & abuse
See the API reference. API keys enforce per-key rate limits independently from the session cookie limits. Hitting a rate limit does not revoke your key.