# Hanzo API: signing in

Every call takes one header: `Authorization: Bearer <credential>`. The credential is an API key (`sk-live-…`) or an access token from Hanzo's identity server, https://hanzo.id. That server runs every sign-in and mints every token; this API validates them and holds no password.

## An agent with a wallet and no person

1. `GET https://hanzo.id/v1/iam/web3/nonce?chain=evm&address=<address>`: a challenge for the wallet.
2. Sign the CAIP-122 message it describes with EIP-191 `personal_sign`.
3. `POST https://hanzo.id/v1/iam/web3/verify` (type `code`, PKCE `S256`): an authorization code. A first-seen wallet gets its own account and organization.
4. `POST https://hanzo.id/v1/iam/oauth/token`: the code for an access token.
5. `POST https://api.hanzo.ai/v1/account/keys`: an API key, shown once.

The whole recipe, every body included: https://hanzoskills.com/hanzo.md

## A terminal or a device with no browser

OAuth device authorization (RFC 8628): `POST https://hanzo.id/v1/iam/oauth/device` answers a code and a page; a person opens the page and enters the code while the device polls `POST https://hanzo.id/v1/iam/oauth/token` with `grant_type=urn:ietf:params:oauth:grant-type:device_code`. The CLI runs it: `hanzo auth login`.

## A person

Create and revoke API keys at https://console.hanzo.ai/api-keys.

## An app

OpenID Connect against https://hanzo.id: the authorization code flow with PKCE (`S256`). Metadata: https://hanzo.id/.well-known/openid-configuration.

## Scopes

`openid`, `profile`, `email`, `offline_access`. What a token may do is decided by its own user and organizations.

## Discovery

- Protected resource metadata (RFC 9728): https://api.hanzo.ai/.well-known/oauth-protected-resource
- Authorization server metadata (RFC 8414): https://hanzo.id/.well-known/oauth-authorization-server
- MCP: `POST https://api.hanzo.ai/v1/mcp` answers a tool call that carries no credential with 401 and a `WWW-Authenticate` header naming the resource metadata.
