Authentication
Provenonce uses two types of credentials:
API Keys (pvn_ tokens)
Every registered agent receives an API key in the format pvn_<payload>.<signature>.
- Used for:
init,heartbeat,purchaseSigil,reissueProof,spawnendpoints - Passed as:
Authorization: Bearer pvn_...header - Stateless: HMAC-signed — the server verifies the signature without a database lookup
- Scope: Each key is bound to a specific agent hash
curl -X POST https://provenonce.io/api/v1/agent/init \
-H "Content-Type: application/json" \
-H "Authorization: Bearer pvn_eyJoIjoi..." \Registration Secret
Root agent registration can be gated by a secret (enforced on mainnet, optional on devnet):
curl -X POST https://provenonce.io/api/v1/register \
-H "Content-Type: application/json" \
-H "x-registration-secret: your-secret" \
-d '{"name": "my-agent", "action": "challenge"}'Child agent registration uses the parent’s API key instead:
curl -X POST https://provenonce.io/api/v1/register \
-H "Content-Type: application/json" \
-H "Authorization: Bearer pvn_PARENT_KEY..." \
-d '{"name": "child-agent", "parent": "0xPARENT_HASH..."}'Authenticated endpoints
| Endpoint | Auth | Status |
|---|---|---|
POST /api/v1/agent/init | API key | Active |
POST /api/v1/agent/heartbeat | API key | Active (v0.9.0) |
POST /api/v1/sigil | API key | Active |
POST /api/v1/agent/reissue-proof | API key | Active (v0.9.0) |
POST /api/v1/agent/spawn | API key | Active |
POST /api/v1/agent/checkin | API key | 410 Gone — use heartbeat |
POST /api/v1/agent/resync | API key | 410 Gone — market staleness |
Public endpoints (no auth)
These endpoints require no authentication:
| Endpoint | Purpose |
|---|---|
GET /api/v1/status/:hash | Agent status |
GET /api/v1/verify/:hash | Full verification with lineage |
GET /api/v1/agent/beat-status/:hash | Beat chain status |
GET /api/v1/beat/anchor | Latest global anchor |
POST /api/v1/beat/verify | VDF proof verification |
GET /api/v1/.well-known/authority-key | Registry Ed25519 authority public key |
GET /api/v1/fees | Current fee schedule |
Wallet keys (optional)
Wallets are optional. By default, register() creates an identity-only agent (no wallet). To add economic identity, opt in at registration:
// No wallet (default) — identity only
const creds = await register('my-agent', { registryUrl: '...' });
// Solana self-custody wallet (opt-in)
const creds = await register('my-org', {
registryUrl: '...',
walletModel: 'self-custody',
});
// Save these securely — cannot be recovered
creds.wallet.secret_key; // hex-encoded 32-byte Ed25519 seed
creds.wallet.address; // chain-native address
creds.wallet.chain; // "solana" or "ethereum"Supported chains: Solana (Ed25519) and Ethereum (secp256k1). The private key is generated client-side and never sent to the server. Note: the key resides in the agent’s process memory, which the host operator can access. True hardware-isolated self-custody requires TEE attestation (not yet implemented).
Post-registration wallet linking (BYO upgrade)
If an agent was registered in no-wallet mode (wallet: null), it can be upgraded later for paid routes:
POST /api/v1/agent/walletwith{"action":"challenge"}- Sign challenge message
POST /api/v1/agent/walletfinalize payload
Paid routes (/api/v1/sigil, /api/v1/agent/heartbeat, /api/v1/agent/reissue-proof) return 403 for api-sponsored wallets when BYO policy is enforced.