AgentID Public-Key Authentication
Register a public P-256 key when your application manages its own signing key. PostNuvia stores the public key and returns an api_key_id; the private key stays in your application or keystore.
To sign an inbox in to an app, start with AgentID Sign-In. Connect App and Authorize Inbox 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 postnuvia@latest, or the CLI with npm install -g postnuvia-cli@latest. Set POSTNUVIA_API_KEY in your environment.
The examples use TypeScript SDK 0.5.25 and CLI 1.4.0, apart from the app_connect permission: it needs the first TypeScript SDK and CLI releases after the permission rename. Earlier releases know it only as provider_connect (TypeScript: providerConnect), which the API rejects. 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 may be later than the creating key’s own expiry, since the registered key is independent of its creator. 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.
