> For the complete documentation index, see [llms.txt](https://docs.nansen.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nansen.ai/getting-started/authentication.md).

# Authentication

### Overview

The Nansen API uses API key authentication. All requests must include your API key in the `apikey` header, unless you pay per request with [Agentic Payments](/getting-started/agentic-payments.md) (x402 or MPP). The OpenAPI specification lists those payment rails as security alternatives on each eligible operation.

### Getting Your API Key

1. Log in to your [Nansen Account](https://app.nansen.ai/auth/agent-setup)
2. Generate a new API key

### Using Your API Key

#### Header Format

```
apikey: YOUR_API_KEY
```

HTTP header names are case-insensitive, but Nansen docs use lowercase `apikey` as the canonical form.

#### curl Example

```bash
curl -X POST 'https://api.nansen.ai/api/v1/smart-money/holdings' \
  -H 'Content-Type: application/json' \
  -H 'apikey: YOUR_API_KEY' \
  -d '{"chains": ["ethereum"]}'
```

#### Python Example

```python
import httpx

headers = {
    "Content-Type": "application/json",
    "apikey": "YOUR_API_KEY"
}

response = httpx.post(
    "https://api.nansen.ai/api/v1/smart-money/holdings",
    headers=headers,
    json={"chains": ["ethereum"]}
)
```

#### Python with Environment Variable

```python
import os
import httpx

API_KEY = os.environ.get("NANSEN_API_KEY")

headers = {
    "Content-Type": "application/json",
    "apikey": API_KEY
}

response = httpx.post(
    "https://api.nansen.ai/api/v1/smart-money/holdings",
    headers=headers,
    json={"chains": ["ethereum"]}
)
```

### Authentication Errors

Authentication failures handled by the API use the standard error envelope described in [Error Handling](/getting-started/error-handling.md). A key rejected by the gateway is the exception described below.

#### 401 Unauthorized

Returned when the API key is missing, invalid, or revoked. There are two bodies to expect.

A keyless request to an API-key-only endpoint returns the full envelope, with `code` set to `unauthenticated`:

```json
{
  "error": "Unauthorized",
  "message": "API key required. This endpoint does not support paid access.",
  "code": "unauthenticated",
  "status": 401,
  "request_id": "ea100706f73d3b63e4451a38ece4014f",
  "doc_url": "https://docs.nansen.ai/getting-started/error-handling#unauthenticated"
}
```

A key that is present but not recognised is rejected up front, before the request is processed, so that response carries a `message` only and no `code`:

```json
{
  "message": "Invalid API key. Manage your keys at https://app.nansen.ai/api?tab=api"
}
```

Branch on the HTTP status first — a 401 always means authentication failed — and read `code` only when it is present.

Endpoints that accept [Agentic Payments](/getting-started/agentic-payments.md) answer a keyless request with `402 Payment Required` and a payment challenge rather than a 401.

**Solutions:**

* Verify your API key is correct
* Ensure the header name is `apikey` (lowercase)
* Check that the key hasn't been revoked

#### 403 Forbidden

Returned when the API key is valid but not permitted to call the endpoint. The body is the same envelope shown above with `"status": 403`; the `code` field names the specific reason — `forbidden`, `plan_upgrade_required`, `insufficient_credits`, or `insufficient_scope` (the key lacks a permission). See [Error Handling](/getting-started/error-handling.md) for what each one means.

**Solutions:**

* Verify your subscription tier includes access to this endpoint
* Check the key's permissions on the [API page](https://app.nansen.ai/api)
* Contact support to upgrade your plan

### Key Permissions

Each key can be limited to what the application using it needs:

| Permission | Endpoints                                                                                 |
| ---------- | ----------------------------------------------------------------------------------------- |
| `data`     | Read-only data endpoints (Token God Mode, Profiler, Smart Money, screeners, and the rest) |
| `trading`  | Spot trading and bridging (`/api/v1/trade/*`) and Hyperliquid perps (`/api/v1/perp/*`)    |
| `account`  | Changing account state through the API, such as smart alerts (`/api/v1/smart-alert*`)     |

`GET /api/v1/account` and `POST /api/v1/sanctions/screen` work with any key. The agent endpoints (`/api/v1/agent/*`) need a key with the `data` and `account` permissions: the agent answers with Nansen data and can create or change your smart alerts. It can't trade through the API, so `trading` isn't needed. A key created before permissions existed has all three.

Permissions only narrow what a key can do. Your account's own limits still apply on top: plan features (such as Pro-only options), regional restrictions on trading, and your credit balance. A key with every permission can do exactly what your account can, and no more.

A call the key isn't permitted to make returns `403` with code `insufficient_scope`; `required_scope` names a missing permission and `required_scopes` lists every permission the endpoint needs. Permission changes apply within about 30 seconds.

### Key Management

If your key is compromised:

1. Immediately revoke it in your dashboard
2. Generate a new key
3. Update all applications using the old key

### Per-key credit limits

Each key can have an optional daily and monthly credit cap, configured on the [API page](https://app.nansen.ai/api). Limits are positive whole credits; leaving a limit unset means unlimited. Daily limits reset at midnight UTC and monthly limits on the first day of the UTC calendar month. Existing keys remain unlimited until you set a cap.

A request that would exceed either cap is blocked before it runs with HTTP `429` and code `api_key_credit_limit_reached`. The body includes `limit_period`, `credit_limit`, `credits_used` (including in-flight reservations), and `resets_at`; `Retry-After` gives the wait in seconds. A request that costs more than the cap itself has no `Retry-After`, since waiting cannot help. The limit applies to that key, so other keys on the account can continue. Free requests remain free. Account balance and plan requirements still apply.

Concurrent requests reserve their quoted credits before running. A charged call counts against the UTC day and month when it was admitted, including calls that finish after midnight. Failed or uncharged calls release their reservation. In the rare case that a charge's outcome cannot be confirmed, its reservation stays counted until that window resets. Changing or removing a cap does not erase the key's current-window usage; this tracking begins when credit limits are deployed.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.nansen.ai/getting-started/authentication.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
