# Claude Managed Agents

kenari forwards the Anthropic APIs it does not translate straight to Anthropic: Managed Agents, Files, Skills and Message Batches. You keep one base URL and one `kn-` key. Anthropic bills the Anthropic Console organization behind your key, so a Max or Team API credit is spent here too. kenari does not meter it. For chat requests, see [Messages](/en/docs/messages).

This is a plain passthrough. kenari does not read, change or translate the request or the response body. For what each endpoint accepts and returns, see Anthropic's documentation.

## Before you start

- You need an active plan. See [Members only](#members-only).
- You need an Anthropic API key saved in kenari. Add it under **Providers & Routes**, tab **Providers**. See [Providers](/en/docs/byok).
- You need a `kn-` key from your own account. See [Keys](#keys).

## Base URL and paths

Use `https://kenari.id` as the base URL, without `/v1`, and the same paths as Anthropic. These paths are forwarded, each with every path below it:

| Path | What it is |
| --- | --- |
| `/v1/agents` | Agents |
| `/v1/environments` | Environments |
| `/v1/sessions` | Sessions and their events |
| `/v1/vaults` | Vaults |
| `/v1/deployments` | Deployments |
| `/v1/deployment_runs` | Deployment runs |
| `/v1/memory_stores` | Memory stores |
| `/v1/files` | Files |
| `/v1/skills` | Skills |
| `/v1/messages/batches` | Message Batches |

`GET`, `POST`, `PUT`, `PATCH` and `DELETE` are forwarded. A request path that contains `..`, an encoded slash or a backslash is refused with `400` and `invalid_path`.

The official Anthropic SDKs work with this base URL. Set `ANTHROPIC_BASE_URL=https://kenari.id` and use your `kn-` key as the API key, or pass them to the client. The SDK sends the key in `x-api-key`, and kenari accepts it there. The SDK also sets the `anthropic-beta` header for Managed Agents on its own.

## Keys

Send your `kn-` key as `x-api-key: kn-...` or `Authorization: Bearer kn-...`. See [Authentication and API keys](/en/docs/authentication).

The passthrough opens your whole Anthropic organization to whoever holds the key, and kenari's caps cannot see this traffic. So these keys are refused with `403`:

- A shared API key, with `shared_key_not_allowed`.
- A key with a model scope, a spend cap or a token cap, with `restricted_key_not_allowed`.

Use a key from your own account with no restrictions.

## Members only

The passthrough needs an active plan. A trial or a gifted plan counts. Without one, the request fails with `403` and `subscription_required`. See [Subscriptions](/en/docs/subscriptions).

## Which Anthropic key is used

kenari uses only an Anthropic API key you saved yourself. It never uses a key of its own, and it never uses a key that points at a custom base URL. A key counts when it is active, not paused, and has not used up its Claude credit with auto-stop on. See [Providers](/en/docs/byok#credit-estimate-and-auto-stop).

| Your account has | What happens |
| --- | --- |
| One such key | kenari uses it automatically. |
| None | `409` and `anthropic_credential_required`. Add a key on the **Providers** tab. |
| Two or more | `409` and `credential_required`, until you name one with the `x-kenari-credential` header. |

```bash
curl https://kenari.id/v1/agents \
  -H "x-api-key: $KENARI_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "x-kenari-credential: $ANTHROPIC_KEY_ID"
```

To get the id, open **Providers & Routes**, tab **Providers**, open the menu on the Anthropic key's row and choose **Copy key ID**. A value that is not an active Anthropic key of your account returns `404` and `credential_not_found`. If the key you name has used up its Claude credit with auto-stop on, the request returns `409` and `credit_limit_reached`. Raise the credit, turn auto-stop off or wait for the renewal day. kenari never falls back to another key, because an agent, session or file created in one organization cannot be used from another. If you would rather not send the header, keep one active Anthropic key and disable the others on the **Providers** tab.

## What is forwarded

kenari sends Anthropic only these request headers: `anthropic-version`, `anthropic-beta`, `content-type`, `accept` and `last-event-id`. Your `kn-` key is never sent. kenari adds the Anthropic key itself.

From the answer you get the status, the body, and these headers: `content-type`, `retry-after`, `cache-control` and every `anthropic-ratelimit-*` header. Anthropic's request id arrives as `anthropic-request-id`. The `x-request-id` and `request-id` headers are kenari's own.

Bodies stream in both directions without buffering, so server-sent event streams, such as a session's event stream, arrive as Anthropic sends them.

## Examples

### List agents

```bash
curl https://kenari.id/v1/agents \
  -H "x-api-key: $KENARI_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01"
```

### Create a session

Create the agent and the environment first. Then start a session that uses them. Replace the ids with your own.

```bash
curl https://kenari.id/v1/sessions \
  -H "x-api-key: $KENARI_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "content-type: application/json" \
  -d '{
    "agent": {"type": "agent", "id": "agent_abc123"},
    "environment_id": "env_abc123"
  }'
```

The response is Anthropic's own, with the session `id`.

## Limits

- A request body can be up to 100 MB. A larger one fails with `413` and `request_too_large`.
- Your account's per-minute request limit applies. See [Rate limits](/en/docs/rate-limits).
- kenari serves a limited number of passthrough requests at the same time for all accounts together. A long event stream holds its place until it ends. When kenari is full, the request fails with `429` and `passthrough_busy`. Try again shortly.

## Billing

kenari does not charge for this traffic, and it records no token usage for it. Anthropic bills the organization behind the key, which is why a Max or Team API credit is spent here. A spend limit set in the Claude Console applies as usual.

## Errors

Errors from kenari use the Anthropic envelope, an object with `"type": "error"` and an `error` object that holds `type`, `message` and `code`. When Anthropic itself answers with an error, you get its status and body unchanged, and that body has no `code`. Branch on `code` when it is there and on `error.type` when it is not. Only the errors specific to this page are listed here. The rest are in [Errors](/en/docs/errors).

| Status | Code | When |
| --- | --- | --- |
| 400 | `invalid_path` | The path contains `..`, an encoded slash or a backslash. |
| 401 | `auth_failed` | The `kn-` key is missing, wrong, expired or revoked. Unlike other endpoints, the body is JSON. |
| 403 | `subscription_required` | The account has no active plan. |
| 403 | `shared_key_not_allowed` | A shared API key was used. |
| 403 | `restricted_key_not_allowed` | The key has a model scope, a spend cap or a token cap. |
| 404 | `credential_not_found` | The `x-kenari-credential` value is not an active Anthropic key of your account. |
| 409 | `anthropic_credential_required` | No Anthropic API key is saved, or none is active. |
| 409 | `credential_required` | Two or more Anthropic keys are active and no `x-kenari-credential` header was sent. |
| 409 | `credit_limit_reached` | The key named in `x-kenari-credential` has used up its Claude credit, and auto-stop is on. |
| 413 | `request_too_large` | The request body is over 100 MB. |
| 429 | `passthrough_busy` | Too many passthrough requests are in progress. |
| 429 | `rate_limit_exceeded` | The account's per-minute request limit is used up. |
| 500 | `auth_failed` | kenari could not look up the `kn-` key. Try again. |
| 500 | none | Something else failed inside kenari. The body is the plain text `internal error`, not JSON. Try again. |
| 503 | `upstream_error` | kenari could not reach Anthropic, or Anthropic returned a gateway error. |

## See also

- [Providers](/en/docs/byok)
- [Messages](/en/docs/messages)
- [Authentication and API keys](/en/docs/authentication)
- [Subscriptions](/en/docs/subscriptions)
