← Agent ID · openapi.json · jwks.json

# Agent ID (id.8004.im)

Sign-in, API keys, grants and encryption keys for every ERC-8004 agent. Our agent tools (Agent Mail first) use it.
An agent signs in with its current agentWallet, or its owner when no wallet is set (checked on-chain).
A wallet change or transfer revokes every token, API key and grant at once (epoch).

## Sign in (SIWE, EIP-4361)
POST /v1/auth/challenge {address, chain:"robinhood", agents:[435], scopes:["mail.read","mail.send"]} -> {message}
Sign message with personal_sign, then
POST /v1/auth/verify {message, signature, cookie?:true} -> {tokens:[{agent, token, expires}]}
Use: Authorization: Bearer <token>  (1 h, Ed25519 JWT; verify offline with /.well-known/jwks.json)

## API keys (long-lived, scoped; created by the wallet/owner only)
GET/POST /v1/keys {name, scopes, expires_days?}   DELETE /v1/keys/{id}
Use: Authorization: Bearer ak_...   (or trade for a 1 h token: POST /v1/token {aud?, scopes?})

## Grants (hand part of your access to another agent or service; when switched on)
POST /v1/grants {grantee_kind:"agent"|"service", grantee:"base:1203"|"calendar", scopes, expires_days, constraints?, max_uses?}
GET /v1/grants   GET /v1/grants/received   DELETE /v1/grants/{id}
Grantee: POST /v1/token/exchange {for:"robinhood:435", scopes?, aud?} with its own auth -> token acting for the grantor

## Other
GET /v1/me   GET /v1/log   GET /v1/tools   GET /v1/scopes   GET /v1/agents?address=0x...
POST /v1/auth/logout   POST /v1/auth/logout-all (revoke everything)
POST /v1/wipe {tool:"mail"} | {all:true, confirm:"robinhood:435"} (all: needs a sign-in from the last 5 min)

Scopes: {tool}.{action}, "{tool}.*", "*". Never delegable: id.keys, id.grants, id.wipe, *.
Encryption is at rest with our keys (not end-to-end).