When an external party visits your sociedad-IA's website, they have no way to know if your audit log is clean. Telling them "I have a clean log, trust me" is the opposite of forensic. The badge embed solves this in 1 line: a 24px SVG that recomputes the verification state every 60s, server-side, against the same canonical-JSON + HMAC-SHA256 implementation the rest of the toolkit uses.
Use the playground below to try it with any session id, then copy the snippet for your README / landing.
Try it

<a href="https://ar-agents.vercel.app/dashboard/4f50ebf2-94ec-4c75-b94a-6e8e1f54f5bc"><img src="https://ar-agents.vercel.app/api/badge/4f50ebf2-94ec-4c75-b94a-6e8e1f54f5bc" alt="ar-agents audit" height="20"></a>
<iframe src="https://ar-agents.vercel.app/dashboard/4f50ebf2-94ec-4c75-b94a-6e8e1f54f5bc" width="100%" height="640" loading="lazy" sandbox="allow-scripts allow-same-origin" title="ar-agents audit log"></iframe>
curl https://ar-agents.vercel.app/api/play/audit/4f50ebf2-94ec-4c75-b94a-6e8e1f54f5bc?verify=1
curl https://ar-agents.vercel.app/api/play/audit/4f50ebf2-94ec-4c75-b94a-6e8e1f54f5bc/csv > audit.csv
Standard markdown badge
Renders inline in any markdown file: GitHub README, GitLab snippet, npm package page, BitBucket. The badge color updates live: blue when verified, red when tampered, gray when no HMAC is wired or the log is empty.
HTML img tag
<img
src="https://ar-agents.vercel.app/api/badge/{sessionId}"
alt="ar-agents audit"
height="20"
/>For HTML pages where markdown isn't available. Specify height="20" to match shields.io sizing exactly; the badge SVG is content-sized so width adapts to the verification state string.
Linked badge (click to dashboard)
<a href="https://ar-agents.vercel.app/dashboard/{sessionId}">
<img
src="https://ar-agents.vercel.app/api/badge/{sessionId}"
alt="ar-agents audit"
height="20"
/>
</a>Clicking the badge opens the full forensic dashboard with the timeline + tamper-test + share UI. Recommended pattern for marketing landings — it gives the visitor a path to dig deeper without committing to it.
Live audit-log iframe
<iframe
src="https://ar-agents.vercel.app/dashboard/{sessionId}"
width="100%"
height="640"
loading="lazy"
referrerpolicy="no-referrer"
sandbox="allow-scripts allow-same-origin"
title="ar-agents audit log"
></iframe>Embeds the full live dashboard with SSE streaming. Use this on an internal compliance dashboard so a finance / ops team can watch the sociedad-IA's tool calls in real time without leaving their tab. The dashboard sets X-Frame-Options: SAMEORIGIN; iframe-ing on a different origin requires the' site to set CSP frame-src https://ar-agents.vercel.app.
Verification report (programmatic)
curl https://ar-agents.vercel.app/api/play/audit/{sessionId}?verify=1
# returns:
# {
# "sessionId": "...",
# "backend": "vercel-kv",
# "count": 5,
# "entries": [...],
# "verification": {
# "total": 5,
# "verified": 5,
# "tampered": 0,
# "hmacWired": true
# }
# }For pipelines that want to assert audit-log cleanliness in CI (e.g., a deploy gate that fails if any entry is tampered) or in a daily compliance digest. See cookbook recipe 19 for the cron-driven pattern.
CSV export (for the contador)
curl https://ar-agents.vercel.app/api/play/audit/{sessionId}/csv > audit-2026-05.csv
# Pivot in Excel / Sheets / Numbers. One row per entry,
# columns: ts, tool, governance, durationMs, hmac, errored,
# input (JSON-stringified), output (JSON-stringified).Practical compliance: el contador can ingest the export, run any pivot, and reconcile against the bookkeeping. CSV format is RFC 4180 compliant — escapes embedded commas / quotes / newlines per spec. UTF-8 BOM included so Excel renders accents correctly without manual encoding setup.
Where the badge gets its data
The badge endpoint (GET /api/badge/{sessionId}) calls the same verifySession() primitive used by /verify and the dashboard. The state mapping:
- verified · N/M (blue) — every signature recomputes correctly.
- tampered · N (red) — at least one signature mismatches the canonical-JSON of its body.
- no entries (gray) — the session id is valid but no tool calls have been logged.
- no-hmac (gray) —
AUDIT_HMAC_SECRETisn't wired in the deploy. - invalid id (gray) — session id failed the regex validation.
Cache: public, max-age=60, s-maxage=60, stale-while-revalidate=300. Browsers refetch every 60s; CDN edges hold for 60s; stale state is allowed up to 5 more minutes while a fresh fetch is in flight. GitHub's Camo proxy for README badges hits at ~60s anyway, so the cache is calibrated to that.
Privacy + threat model
Audit-log entries are public-readable by design. The session id is the access token; pick one opaque enough that enumeration isn't a meaningful attack (UUID v4 from crypto.randomUUID()is fine; sequential integers are not). The endpoint serves anyone who knows the id; it doesn't require auth.
Don't log secrets / PII in the entry input/output — whatever lands in entry.input is queryable forever (or until KV TTL). The system prompt of the live agent explicitly refuses to log credentials; agents you build on top should follow the same discipline.
Full threat surface in /security and /architecture/audit-log.