Authentication

One key per account, sent in a header, rotated by regenerating.

What a key looks like

A key is 63 characters in two parts.

nv_live_0PS8BA2MQYX3pD7VtIW7yvtAy44IeROOxdd79N-6eRKHDNIbF_bkygk
        └─ key id ──┘└──────────────── secret ─────────────────┘

The key id is public: it identifies the key, carries no secret material, and is safe to paste into a support ticket or a log line. The secret half is stored only as a hash. It exists in full exactly once, in the response that created it.

Sending the key

Either header works. Bearer is the documented form; X-API-Key exists because some HTTP clients make custom Authorization headers awkward.

Authorization: Bearer nv_live_...
X-API-Key: nv_live_...

Keys are never accepted in the query string. Query strings end up in access logs, browser history and Referer headers, which is exactly where a credential should not be. A request that puts its key there is answered as if it had sent nothing.

Rotating

Regenerating issues a new key and revokes the old one immediately. There is no overlap window, so deploy the new key before you press the button. The old key then answers 401 with the code key_revoked, which is deliberately distinct from invalid_key so you can tell "you rotated this" from "this never existed".

Your IP allowlist carries over to the new key. Rotating a credential should not quietly widen who can use it.

Restricting by IP

You can limit your key to a set of source addresses or CIDR ranges. A request from anywhere else is refused with ip_not_allowed, whatever the key.

203.0.113.7, 198.51.100.0/24

An empty allowlist means no restriction, not "deny everything". If you set one, make sure it covers every machine that calls the API, including the ones you forget about, like a staging environment or a cron host.

Storing the key

Treat it like a password: environment variable or secret manager, never a committed config file, never client-side code. Anything that reaches a browser or a mobile app is public, no matter how it got there.