AgentID Public-Key Authentication
Register a public P-256 key when your application manages its own signing key. AgentMail stores the public key and returns an api_key_id; the private key stays in your application or keystore.
For provider sign-in, start with AgentID Sign-In. Connect and authorize create sign-in keys for you. This guide covers registering and managing keys you generate yourself.
Before you start
Use a bearer API key with api_key_create to register keys. Reading, updating, and deleting keys require api_key_read, api_key_update, and api_key_delete, respectively.
Install the TypeScript SDK with npm install agentmail@latest, or the CLI with npm install -g agentmail-cli@latest. Set AGENTMAIL_API_KEY in your environment.
The examples use TypeScript SDK 0.5.25 and CLI 1.4.0. Python SDK 0.5.10 still exposes the previous public-key endpoints. The Python example uses the current HTTP route with httpx; install its dependencies with pip install httpx cryptography.
Generate and store private keys in trusted code or a keystore. Keep private key material out of model context, tool output, and logs. Register only the four public JWK fields: kty, crv, x, and y.
Generate and register a key
The following examples generate a P-256 key and register it for one inbox. They keep the private key in memory to demonstrate key generation; persist it securely before registration in production.
To register an existing public JWK with the CLI, put only those four public fields in public-jwk.json:
The response has type: "public_key", an api_key_id, and the public key’s server-computed fingerprint. It does not contain a bearer secret. Registered keys have no status; sign-in keys created by connect or authorize do.
The API rejects private JWK fields such as d, extra JWK members, other curves, and invalid P-256 coordinates.
Choose the scope
The route determines the key’s scope:
Include public_key in the request (TypeScript: publicKey; CLI: --public-key) to register a public key. A request without it creates a bearer key. The target scope must be accessible to the creating key; pod_id and inbox_id in the response identify the resulting scope.
Permissions, expiry, and client IDs
permissionsdefaults to the creating key’s permissions. Explicit grants cannot exceed what that key holds.expires_atdefaults to the creating key’s expiry. An explicit expiry must be in the future and cannot exceed the creator’s expiry. If the creator has no expiry and none is supplied, the registered key does not expire.- Registered public keys are independent of their creator afterward. Changing or deleting the bearer key does not change or revoke them.
- Update
nameandpermissionswithPATCH /v0/api-keys/{api_key_id}. Key material, type, scope, and expiry are immutable. - An optional
client_idis a caller-chosen alias, unique within the organization. It must be URL-safe and contain no slash or@. You can use it instead ofapi_key_idto get, update, or delete a public key. - Registration with the same
client_idand matching key returns the existing credential; a conflicting registration returns409. Persist and reuse the key pair when retrying registration, rather than generating a new key for the same alias.
List, update, and revoke
Use the same API Keys endpoints for bearer keys, registered public keys, and sign-in keys:
Follow next_page_token until it is absent, including when a page is empty. Pass it as page_token in HTTP, pageToken in TypeScript, or --page-token in the CLI.
To rotate a key, generate and persist a replacement, register it with a new client_id, deploy and verify it, then delete the old key. To revoke multiple keys, list the intended credentials and delete each one individually.
See the API Keys reference for complete request and response fields.
