Agent bootstrap
This guide shows the full lifecycle:
- Human creates a provisioning key once
- Agent self-provisions a standard key at runtime
- Agent verifies emails with the standard key
- Agent checks usage before large jobs
sequenceDiagram
participant H as Human
participant D as Dashboard
participant A as Agent
participant M as truval.dev API
H->>D: Create provisioning key in dashboard
D-->>H: Key shown once, store securely
A->>M: POST /v1/management/keys (Bearer mgmt key)
M-->>A: Standard verify key, cache for reuse
A->>M: POST /v1/email/verify (Bearer standard key)
M-->>A: Verification JSON
Note over A: Later runs reuse the cached standard key
(Provisioning keys use the sk_mgmt_… prefix; standard verify keys use sk_live_… or sk_test_… — omitted from the diagram so Mermaid does not treat underscores as italics.)
1) One-time human setup
Section titled “1) One-time human setup”- Create an account at dash.truval.dev
- Create one provisioning key (
sk_mgmt_...) - Store it in your runtime environment:
export TRUVAL_MGMT_KEY=sk_mgmt_...2) Agent bootstrap pattern
Section titled “2) Agent bootstrap pattern”On startup:
- Try loading a cached standard key
- If none exists, create one via
POST /v1/management/keys - Cache the key in your agent state / secret store
Before large batches:
- Call
GET /v1/management/usage/summary - Compare
calls_remainingwith workload size
On the free tier, calls_remaining is monthly verification quota headroom (same rules as the verify API). On paid tiers, it reflects included billable allowance minus billable use. You can also call GET /v1/management/account and use limits.monthly_calls and usage_this_month on free for the same quota picture. Details: Management API (usage/summary and usage sections).
3) Full TypeScript example
Section titled “3) Full TypeScript example”import { createClient, createManagementClient } from 'truval'
const mgmt = createManagementClient(process.env.TRUVAL_MGMT_KEY!)
let runtimeVerifyKey: string | null = null
async function getVerifyClient() { if (!runtimeVerifyKey) { const created = await mgmt.keys.create({ label: 'agent-runtime' }) runtimeVerifyKey = created.key } return createClient(runtimeVerifyKey)}
export async function verifyOne(email: string) { const client = await getVerifyClient() return client.verify(email)}
export async function verifyBatchSafely(emails: string[]) { const usage = await mgmt.usage.summary() if (usage.calls_remaining < emails.length) { throw new Error( `Insufficient remaining calls: need ${emails.length}, have ${usage.calls_remaining}`, ) }
const client = await getVerifyClient() return client.verifyBatch(emails)}4) MCP alternative (zero custom API wiring)
Section titled “4) MCP alternative (zero custom API wiring)”Use truval.dev MCP with both headers:
{ "mcpServers": { "truval": { "url": "https://mcp.truval.dev/mcp", "headers": { "Authorization": "Bearer ${TRUVAL_API_KEY}", "X-Truval-Provisioning-Key": "${TRUVAL_PROVISIONING_KEY}" } } }}Then your agent can call:
create_api_keylist_api_keysrevoke_api_keyget_usage_summaryget_accountget_usagecreate_billing_portal
without building raw HTTP wrappers.