> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shodai.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticate API requests with an API key and understand access scopes, entitlements, and auth failures.

For the complete documentation index, see [llms.txt](https://docs.shodai.network/llms.txt).

API requests use the `X-API-Key` header as the canonical credential shape. The TypeScript SDK sends that header when you pass `apiKey` to `ApiClient`.

Hosted MCP uses the same API key as `Authorization: Bearer cns_pk_...` because remote MCP clients commonly support bearer-style auth. This is an API-key compatibility alias only. OAuth bearer tokens, JWT bearer tokens, and non-API-key bearer values are not supported.

For testnet access, you can self-onboard at [developers.shodai.network/portal](https://developers.shodai.network/portal) and create an API key. You can use that key in your own integration or try it immediately in the [Agreements API Playground](https://developers.shodai.network/api-playground).

Production API keys are provisioned by your API operator, who hands the plaintext key to the recipient once.

<Warning>
  Store the plaintext key when it is issued. The API stores only the hashed key afterward.
</Warning>

## Send the API key

For [Quickstart with TypeScript SDK](/sdks/quickstart-with-typescript-sdk), pass the key when constructing the client:

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { ApiClient } from '@shodai-network/agreements-api-client';

const client = new ApiClient({
  environment: 'testnet',
  apiKey: process.env.API_KEY,
});
```

For [Quickstart with MCP](/sdks/quickstart-with-mcp), configure the hosted server with a bearer-style API key:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
Authorization: Bearer cns_pk_...
```

For raw HTTP debugging, send the same value as `X-API-Key`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS "$BASE_URL/v0/agreements" \
  -H "X-API-Key: $API_KEY"
```

For clients that cannot set custom API-key headers, the bearer-style alias also works:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS "$BASE_URL/v0/agreements" \
  -H "Authorization: Bearer $API_KEY"
```

## Scopes and entitlements

API access is controlled by entitlements on the API principal. Testnet keys created through the Developer Portal are intended to include the default agreement and webhook read/write scopes. Manually provisioned principals should be checked for the scopes your integration needs.

| Scope              | Use                                                      |
| ------------------ | -------------------------------------------------------- |
| `agreements.read`  | Read agreement records, state, and input history.        |
| `agreements.write` | Validate, deploy, and submit agreement inputs.           |
| `webhooks.read`    | List and inspect webhook subscriptions.                  |
| `webhooks.write`   | Create, update, disable, and test webhook subscriptions. |
| `agreements.*`     | Wildcard access for agreement scopes.                    |
| `webhooks.*`       | Wildcard access for webhook scopes.                      |
| `*`                | Broad wildcard access. Use only for internal testing.    |

Entitlement modes are:

| Mode             | Result                                                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `free_allowlist` | Allows the scoped operation.                                                                                              |
| `blocked`        | Returns `403 Forbidden` for the scoped operation.                                                                         |
| `paid_required`  | Returns `402 Payment Required`; per-call x402 settlement is not implemented. Treat this as an entitlement/operator issue. |

If the principal has no active entitlement for the requested scope, the API returns `403 Forbidden`.

## Common authentication failures

| Status | Meaning                                                                                                                                    | What to check                                                                                                                                    |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `401`  | Missing, invalid, revoked, disabled, or unsupported API credential.                                                                        | Confirm `X-API-Key` is present with the current plaintext key, or use `Authorization: Bearer cns_pk_...` only as an API-key alias.               |
| `402`  | The authenticated API principal has `paid_required` entitlement mode for the requested scope. Per-call x402 settlement is not implemented. | Treat this as an entitlement/operator issue and ask your API operator to review the requested scope.                                             |
| `403`  | The key is authenticated but not allowed for this scope or resource.                                                                       | Confirm the principal has the required agreement or webhook scope, a matching wildcard scope, or `*`, and that no `blocked` entitlement applies. |

## Header casing

API auth header names are case-insensitive at the HTTP layer, but examples use `X-API-Key` consistently.

## Related pages

* [Quickstart with TypeScript SDK](/sdks/quickstart-with-typescript-sdk)
* [Quickstart with MCP](/sdks/quickstart-with-mcp)
* [TypeScript client reference](/sdks/typescript-client)
* [Errors and troubleshooting](/reference/errors-and-troubleshooting)
* Use the API Reference group in the sidebar for generated request and response details.
