Drex guides

Authentication

Create, send, rotate, and revoke Nace API keys.

Every request to https://console.nace.ai carries an API key in the Authorization header. Keys spend the balance of the account that created them. This guide covers the key lifecycle from creation to revocation.

Create a key

  1. Sign in at console.nace.ai/login and open API Keys.
  2. Click Create key.
  3. Enter a name, such as the app or environment that will use the key, and click Create key.
  4. Copy the key from the dialog.

The full key appears once. After you close the dialog, the API Keys page shows only the key's prefix. If you lose a key, revoke it and create a new one.

A key looks like nace_sk_ followed by 43 URL-safe characters. An account can have at most 3 active keys. When you reach the limit, Create key is disabled until you revoke one.

Store the key

Put the key in an environment variable or a secret manager. Do not commit it to source control, and do not ship it in code that runs in a browser or a mobile app.

export NACE_API_KEY="nace_sk_..."

The Nace SDKs read NACE_API_KEY and NACE_BASE_URL when you don't pass explicit configuration, including for custom and on-prem deployments; see Python configuration or TypeScript configuration. Use the key for the deployment selected by the API root.

The CLI and MCP use NACE_API_KEY and NACE_BASE_URL directly for custom and on-prem deployments too; login is optional. Their environment values override the key and URL saved by nace login in ~/.nace/config.toml. Code that keeps the TypeSafe SDK reads TYPESAFE_API_KEY instead; see Migrate from TypeSafe.

Send the key

Send the key as a Bearer token on every request.

curl https://console.nace.ai/v1/models \
  -H "Authorization: Bearer $NACE_API_KEY"

Keep the key on the server

Only call Drex from code you control on a server. Anyone who loads a page can read a key shipped in its JavaScript. The /v1 routes also send no Access-Control-Allow-Origin header, so a page on another origin can't call them at all.

The TypeScript SDK enforces this. If NaceClient is constructed in a browser, the constructor throws a NaceError:

NaceClient is running in a browser, which would expose your API key to anyone using the page. Call the API from a server instead, or pass dangerouslyAllowBrowser: true if you understand the risk.

dangerouslyAllowBrowser: true only turns that check off. It doesn't make a cross-origin call work, and it ships your key to everyone who opens the page. For a web app, call Drex from your own backend and have the browser call your backend.

Rotate a key

To rotate a key without downtime:

  1. On API Keys, click Create key and create the replacement. If you already have 3 active keys, revoke an unused one first.
  2. Deploy the new key to your servers and confirm that requests succeed.
  3. Click Revoke next to the old key, then confirm with Revoke key.

Requests with the revoked key stop working within 5 seconds. Revocation cannot be undone.

To swap a key in one step, for example one that may have leaked, click Rotate on its row and confirm with Rotate key. Drex revokes the old key and shows a new one with the same name, once. This works even with 3 active keys. Requests with the old key stop working within 5 seconds, so they fail until you deploy the new key.

Revoke a key

To revoke a key you no longer need, or one that may have leaked, open API Keys, click Revoke on that row, and confirm with Revoke key. A revoked key stays in the list with the status Revoked so you can see when it was last used.

What a bad key returns

A missing, malformed, or revoked key returns 401 with the type authentication_error. This is a real capture from curl -i https://console.nace.ai/v1/models with no Authorization header. The request id varies per call.

HTTP/2 401
x-request-id: req_7c1e4a9b2d3f4e5a8b6c7d8e9f0a1b2c
x-typesafe-request-id: req_7c1e4a9b2d3f4e5a8b6c7d8e9f0a1b2c

{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key. Pass a nace_sk_ key as `Authorization: Bearer <key>`."
  },
  "request_id": "req_7c1e4a9b2d3f4e5a8b6c7d8e9f0a1b2c"
}

The SDKs raise this as AuthenticationError (TypeScript) or NaceAuthenticationError (Python) and don't retry it. Every response from /v1/systemone and /v1/models carries the same request id in the body and in both headers; the document routes send it as x-request-id, and in the body only on errors. Quote it when you contact support. Other error types are listed in Errors.

Check a key without spending funds

GET /v1/models needs a valid key but works when the account has no available funds, so you can use it to confirm that a key is active before you deploy it. The SDKs' client.models.list() makes this call: TypeScript returns the array of models, and Python a response whose models holds them. The CLI's nace models prints them, and nace login runs the same check before it saves a key.

curl https://console.nace.ai/v1/models \
  -H "Authorization: Bearer $NACE_API_KEY"

The response contains a models array and a request_id. Each model has a name, description, release_date and alias_for. A served version has alias_for: null; aliases and retired ids name the served version in alias_for. The list depends on availability to this API key in the target environment. See Models for the current catalog and retirement mappings.

A POST /v1/systemone call with a valid key and no available funds returns 402 with the type insufficient_credit. Top up or add a card on Billing to keep going. An account with an unpaid invoice gets 402 with the type payment_required until the invoice is paid on Billing. See Pricing.

On this page