---
title: Authentication
description: Agent reference for token scopes, pairing, claims, recovery, and revocation.
sidebar:
  order: 5
---

Charming's HTTP API uses Bearer tokens. MCP clients complete OAuth when they connect and do not handle these tokens directly. For HTTP request and response schemas, use the [REST API reference](/docs/reference).

## Choose a credential

Use the smallest scope that fits the task.

| Token | Scope | Use |
| --- | --- | --- |
| `chrm_app_*` | One app | Returned when an agent creates an anonymous app. It can read, update, and run that app. |
| `chrm_user_*` | One account | Used by HTTP agents that need the user's apps, sharing, secrets, or account settings. |
| `chrm_render_*` | One app at runtime | Minted by Charming for `window.charming`. Agents do not mint or manage it. |

See [Pricing and limits](/docs/capabilities/limits#token-ttls) for token lifetimes.

## Discovery

Do not hardcode auth metadata. Use these machine-readable sources:

- [OpenAPI contract](https://charm.ing/.well-known/openapi.json) for routes, schemas, security rules, and errors.
- [OAuth authorization server](https://charm.ing/.well-known/oauth-authorization-server) for sign-in and pairing endpoints.
- [OAuth protected resource](https://charm.ing/.well-known/oauth-protected-resource) for the API's authorization server.

## Anonymous app token

[Create an app](/docs/reference/operations/create-app) without an `Authorization` header to receive a `chrm_app_*` token. Keep it secret. It works only for the returned app and cannot list other apps.

An anonymous app expires unless a user claims it. Claiming the app revokes its `chrm_app_*` token. If an agent later uses that token, the 401 response includes a `recovery` block. Follow that block instead of creating a replacement app.

## User token

A signed-in user can mint a `chrm_user_*` token with [Create token](/docs/reference/operations/create-token). Charming returns the plaintext once. Use [List tokens](/docs/reference/operations/list-tokens) to inspect active tokens and [Revoke token](/docs/reference/operations/revoke-token) to revoke one.

An agent without a browser session should pair:

1. Call [Start pairing](/docs/reference/operations/start-pairing).
2. Show the returned `user_code` and `verification_url` to the user.
3. Poll with [Poll pairing](/docs/reference/operations/poll-pairing) at the returned interval.
4. Store the `chrm_user_*` token returned after approval. Charming returns it once.

The `device_code` is private to the agent. The `user_code` is safe to show to the user.

## Claim an anonymous app

There are two supported flows:

- Set `pair: true` when you create an anonymous app. Approval pairs the agent and claims the app in one flow.
- If you already have a `chrm_user_*` token, call [Claim app](/docs/reference/operations/claim-app) with the app's `chrm_app_*` token as proof.

Both flows revoke the app token after claim. Use the user token for later work.

## Send a token

HTTP agents send `Authorization: Bearer <token>`. Do not put a user or app token in a URL. Follow [build-http.md](/docs/build-http.md) for request examples.

Rendered apps use `window.charming.api()` instead of managing credentials. Charming attaches the render token.

## Recover from auth errors

- `401` means the request has no valid credential. Follow `error.recovery` when present.
- `403` means the credential is valid but lacks access to the app or action. Do not retry with the same scope.
- `token_revoked_post_claim` means an app was claimed. Pair for a user token, then retry.
- `token_expired` includes the next auth step in `error.recovery`.

The [OpenAPI contract](https://charm.ing/.well-known/openapi.json) defines every error field and reason.

## Revoke access

Users can review and revoke agent tokens at [Connected agents](https://charm.ing/account/agents). HTTP agents can use [List tokens](/docs/reference/operations/list-tokens) and [Revoke token](/docs/reference/operations/revoke-token).

Claiming an anonymous app revokes its app token. Render tokens rotate when Charming renders the app again.

## Related

- [Set up Charming with an agent](/docs/guides/use-charming-with-your-agent)
- [HTTP build guide](/docs/build-http.md)
- [Pricing and limits](/docs/capabilities/limits)
