This guide walks through every integration point: SDK installation, API key management, middleware wiring, webhook delivery, and verification endpoints. It assumes you have a Kakunin account and at least one agent registered.
For conceptual background on KYC principles for agents, see KYC for AI Agents. For a quickstart with a trading bot, see MiCA Trading Bot Quickstart.
Every API call requires a key issued from your dashboard. Keys are scoped to a project.
# Dashboard → Project Settings → API Keys → Create key
# Prefix: sk_live_ (production) / sk_test_ (sandbox)
KAKUNIN_API_KEY=sk_live_xxxxxxxxxxxxxxxx
KAKUNIN_PROJECT_ID=proj_1234567890
Keys are validated in Kakunin edge middleware — they never touch your application code. Pass the key as a Bearer token:
GET /v1/agents HTTP/1.1
Host: api.kakunin.ai
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx
Rotate keys from the dashboard any time. Revocation propagates in < 500 ms across all edge nodes.
npm install @kakunin/sdk
// lib/kakunin.ts
import { KakuninClient } from '@kakunin/sdk';
export const kakunin = new KakuninClient({
apiKey: process.env.KAKUNIN_API_KEY!,
projectId: process.env.KAKUNIN_PROJECT_ID!,
baseUrl: 'https://api.kakunin.ai', // omit for default
});
Export one singleton from lib/kakunin.ts — never instantiate per-request.
import { kakunin } from '@/lib/kakunin';
const agent = await kakunin.agents.create({
name: 'invoice-processor-v2',
metadata: {
version: '2.0.0',
model: 'claude-3-5-haiku',
framework: 'vercel-ai-sdk',
operator: 'Acme Ltd',
},
});
console.log(agent.id); // agent_abc123
const cert = await kakunin.agents.getCertificate(agent.id, {
validityDays: 90, // MiCA minimum 90 days
scope: {
actions: ['invoice:read', 'payment:initiate'],
maxTransactionValue: 10000, // EUR
},
});
// Store these — never log or hardcode
const { certificate_pem, kms_key_arn, serial_number } = cert;
const verification = await kakunin.certificates.verify(certificatePem);
if (!verification.valid) {
throw new Error(`Invalid cert: ${verification.reason}`);
}
console.log(verification.agent_id); // agent_abc123
console.log(verification.scope); // { actions: [...], ... }
pip install kakunin
# lib/kakunin_client.py
from kakunin import KakuninClient
import os
client = KakuninClient(
api_key=os.environ["KAKUNIN_API_KEY"],
project_id=os.environ["KAKUNIN_PROJECT_ID"],
)
agent = client.agents.create(
name="data-pipeline-agent",
metadata={
"version": "1.4.2",
"framework": "langchain",
"operator": "DataCo GmbH",
},
)
cert = client.agents.get_certificate(
agent_id=agent.id,
validity_days=365,
scope={"actions": ["db:read", "report:write"]},
)
print(cert.serial_number)
verify_agent_scope decoratorfrom kakunin.integrations.scope import verify_agent_scope
@verify_agent_scope(required_scope="payment:initiate")
async def initiate_payment(agent_cert: str, amount: float):
# Only executes if cert is valid + scope matches
...
Add Kakunin verification to your API routes via Next.js edge middleware. This runs before route handlers — zero overhead in application code.
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { verifyKakuninCert } from '@kakunin/sdk/edge';
export const config = {
matcher: ['/api/v1/:path*'],
};
export async function middleware(req: NextRequest) {
const cert = req.headers.get('x-agent-certificate');
if (!cert) {
return NextResponse.json({ error: 'missing agent certificate' }, { status: 401 });
}
const result = await verifyKakuninCert(cert, {
apiKey: process.env.KAKUNIN_API_KEY!,
});
if (!result.valid) {
return NextResponse.json({ error: result.reason }, { status: 401 });
}
// Forward agent identity to route handlers via header
const res = NextResponse.next();
res.headers.set('x-agent-id', result.agent_id);
res.headers.set('x-agent-scope', JSON.stringify(result.scope));
return res;
}
Read the forwarded values in your route handler:
// app/api/v1/payments/route.ts
export async function POST(req: NextRequest) {
const agentId = req.headers.get('x-agent-id')!;
const scope = JSON.parse(req.headers.get('x-agent-scope')!);
if (!scope.actions.includes('payment:initiate')) {
return NextResponse.json({ error: 'insufficient scope' }, { status: 403 });
}
// ... business logic
}
Send behavioral events to Kakunin's risk engine after each agent action:
await kakunin.events.ingest({
agent_id: agentId,
action_type: 'payment.initiate', // must match your event schema
payload_hash: sha256(payloadJson), // hash, not raw payload
metadata: {
amount_eur: 4500,
counterparty: 'vendor_xyz',
latency_ms: 34,
},
timestamp: new Date().toISOString(),
});
The risk engine scores each event against the agent's behavioral baseline. Scores ≥ 0.75 trigger a pre-revocation warning to /api/v1/notifications. Scores ≥ 0.85 trigger automatic revocation.
Supported action_type values: payment.initiate · trade.execute · data.read · data.write · api.call.external · authentication.attempt · configuration.change · file.access
Kakunin pushes compliance events to your endpoint. Register one:
const webhook = await kakunin.webhooks.create({
url: 'https://yourapp.com/api/webhooks/kakunin',
events: ['certificate.issued', 'certificate.revoked', 'risk.alert'],
});
// Store the webhook secret — used to verify signatures
console.log(webhook.secret); // whsec_xxxxxxxx
// app/api/webhooks/kakunin/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { verifyWebhookSignature } from '@kakunin/sdk';
export async function POST(req: NextRequest) {
const body = await req.text();
const signature = req.headers.get('kakunin-signature')!;
const isValid = verifyWebhookSignature({
payload: body,
signature,
secret: process.env.KAKUNIN_WEBHOOK_SECRET!,
});
if (!isValid) {
return NextResponse.json({ error: 'invalid signature' }, { status: 400 });
}
const event = JSON.parse(body);
switch (event.type) {
case 'certificate.revoked':
await handleRevocation(event.data.agent_id);
break;
case 'risk.alert':
await handleRiskAlert(event.data);
break;
}
return NextResponse.json({ received: true });
}
Kakunin retries failed webhook deliveries up to 3 times with exponential backoff (5 s, 25 s, 125 s).
Any party can verify an agent certificate against Kakunin's public verify endpoint — no API key required:
curl -X POST https://kakunin.ai/api/v1/verify \
-H "Content-Type: application/json" \
-d '{"certificate_pem": "-----BEGIN CERTIFICATE-----\n..."}'
Response:
{
"valid": true,
"agent_id": "agent_abc123",
"serial_number": "F1D4E8C7B2A9F3E6",
"status": "active",
"scope": { "actions": ["payment:initiate"], "maxTransactionValue": 10000 },
"issued_at": "2026-05-28T00:00:00Z",
"expires_at": "2026-08-26T00:00:00Z"
}
Build this into any counterparty integration: before accepting a signed payload from an agent, verify its certificate is active.
Use sk_test_ keys and the sandbox environment for all pre-production testing:
KAKUNIN_API_KEY=sk_test_xxxxxxxxxxxxxxxx
KAKUNIN_BASE_URL=https://sandbox.kakunin.ai
Sandbox certificates are real X.509 certificates with the same cryptographic properties as production, but they are marked with the OID 1.3.6.1.4.1.99999.sandbox and cannot be used to authenticate against production endpoints.
Trigger risk scenarios programmatically in the sandbox:
// Force a specific risk score for testing revocation flows
await kakunin.sandbox.setRiskScore(agentId, 0.9);
// Trigger a pre-revocation warning notification
await kakunin.sandbox.triggerAlert(agentId, 'risk.alert');
# Required
KAKUNIN_API_KEY=sk_live_xxxxxxxxxxxxxxxx
KAKUNIN_PROJECT_ID=proj_1234567890
# Optional
KAKUNIN_BASE_URL=https://api.kakunin.ai # override for sandbox
KAKUNIN_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxx # from dashboard
AWS_REGION=eu-west-1 # KMS region (GDPR)
All secrets go through Doppler (or your secrets manager). Never commit to git.