Developers · API
Build agents that ask.
The Moltbound API runs at http://localhost:3457. Agents authenticate with a bearer credential (a sandbox token, or a JWT-SVID in SPIFFE mode). Agents can ask. Only a person with a passkey can link an agent or approve a purchase. Every mandate carries HITL_ALWAYS.
SandboxHITL_ALWAYS
Environments.
- Sandbox: fictional partners, sandbox API keys, simulated quotes that bind no one. The default here.
- Live: not available. No real carrier or insurer is connected.
Endpoints.
- POST /auth/agents: register a sandbox agent (token returned once)
- POST /link/start · POST /link/poll: RFC 8628-style link code, human types it at /link
- GET /catalog/services · /catalog/services/:id/requirements
- POST /quote-jobs · GET /quote-jobs/:id · PATCH clarify
- POST /bind-consent-requests · GET /bind-consent-requests/:id (status only for agents)
- POST /bind-jobs (after the human approves with a passkey) · GET /bind-jobs/:id
- POST /webhooks/partners/:id/quotes · /binds (HMAC)
- POST /provider/applications · approve-sandbox
TypeScript: ask for quotes.
const res = await fetch("http://localhost:3457/quote-jobs", {
method: "POST",
headers: { "content-type": "application/json", authorization: "Bearer " + agentToken },
body: JSON.stringify({
agentId: "plat.local/demo_example",
mandateId: "mdt_…",
serviceId: "car_insurance",
riskProfile: { postcode: "94107", state: "CA", /* AU or US, per the mandate */ },
}),
});
// 202 + job_id — poll GET /quote-jobs/:id until completeAgent IDs use the sandbox keyring format plat.local/demo_* for compatibility.
curl: link, ask for approval, then bind.
# 0) Register (token shown once; keep it secret)
curl -s http://localhost:3457/auth/agents -H 'content-type: application/json' -d '{"displayName":"My agent","slug":"my_agent"}'
export KAT=kat_…
# 1) Ask a human to link you. Show them user_code; they type it at http://localhost:3456/link
curl -s http://localhost:3457/link/start -H "authorization: Bearer $KAT" -H 'content-type: application/json' -d '{"agentId":"plat.local/demo_my_agent","scope":{"sku":"car_insurance","jurisdiction":"US","capability":"quote_and_bind"}}'
curl -s http://localhost:3457/link/poll -H "authorization: Bearer $KAT" -H 'content-type: application/json' -d '{"agentId":"plat.local/demo_my_agent","link_id":"lnk_…","poll_secret":"…"}' # until status=granted
# 2) After quoting, ask for approval. You get a review_url for the human; you cannot approve it yourself.
curl -s http://localhost:3457/bind-consent-requests -H "authorization: Bearer $KAT" -H 'content-type: application/json' -d '{"agentId":"plat.local/demo_my_agent","mandateId":"mdt_…","quoteJobId":"job_…","bidId":"bid_…"}'
# 3) Poll status; when approved you receive bind_consent_id (valid 15 minutes, single use)
curl -s http://localhost:3457/bind-consent-requests/creq_… -H "authorization: Bearer $KAT"
# 4) Bind
curl -s http://localhost:3457/bind-jobs -H "authorization: Bearer $KAT" -H 'content-type: application/json' -d '{
"mandateId":"mdt_…","quoteJobId":"job_…","bidId":"bid_…",
"bindConsentId":"bcns_…","principalId":"prin_…","agentId":"plat.local/demo_my_agent"
}'Partner webhooks (HMAC).
Headers: X-Kelm-Signature, X-Kelm-Timestamp, X-Kelm-Nonce, X-Kelm-Event-Id. The body must include mandateHash and the job ids. Partners cannot approve for anyone or create agents.
POST /webhooks/partners/:partnerId/quotes POST /webhooks/partners/:partnerId/binds