Evidence pack
The evidence pack is one ZIP file for security, compliance or your auditor. It holds every policy decision of a date range, who approved what and when, who changed the rules, and the access changes Burnbound records. A manifest carries the SHA-256 of each file, and the SHA-256 of the manifest is recorded in the audit log, so anyone can check later that the pack was not changed.
It is taken from the audit log, which only grows. It helps you document controls; it is not a certification.
Who can download it?
Only an owner or an admin, signed in to the dashboard, on Team or Business.
- In the dashboard. Monthly report in the sidebar (
/app/informe), block Evidence package: pick the first and the last day and download. Other roles see one line saying only owners and admins can download it. - On the API.
GET /v1/reports/evidence.zip?from=YYYY-MM-DD&to=YYYY-MM-DDwith the session of an owner or admin. An org key or an agent key gets403.
The file is named burnbound-evidence-<from>-to-<to>.zip. The README.md inside is in the language of the person who exports it, English or Spanish.
Which dates does it cover?
| Rule | What happens |
|---|---|
| Days | from and to are UTC days, both included. Both are required, and the start must be on or before the end. |
| Length | 366 days at most. |
| Plan retention | The start is moved to the oldest moment your plan's audit retention keeps: 365 days before the export on Team, all of it on Business. The README says so, and window.effective.from in the manifest gives the exact instant. |
| One at a time | One export at a time per organization. A second one while the first runs is refused; the lock frees itself after 15 minutes at most. |
| Approvals | An approval asked in the window is followed up to the moment of the export, so its final state is today's. |
Errors on the API:
| Answer | Why |
|---|---|
400 invalid_range |
A missing or invalid day, or the start after the end. |
400 range_too_long |
More than 366 days. |
403 plan_limit_reached |
Free plan, with limit: "reports". |
503 export_busy |
Another export of the organization is running. |
503 report_unavailable |
The store failed before the download started. Try again. |
What is in the pack?
| File | What it holds |
|---|---|
decisions.csv |
Every policy decision on an x402 or MPP payment, a card authorization or an action such as a refund. |
approvals.csv |
One row per human approval asked in the window. |
policy-changes.csv |
Every change of a policy, a rule or the decision webhook settings. |
access.csv |
What Burnbound records about who can act for the organization. |
README.md |
The organization, the window, who generated it, what each file holds and which controls it helps to document. |
manifest.json |
The organization, the window asked for and the one used, the plan, the rows and the SHA-256 of every other file. |
The CSV files are UTF-8 with a byte order mark. decisions.csv and policy-changes.csv are oldest first; approvals.csv is in the order the approvals closed, then the ones still open; access.csv lists the audit rows, then the key rows, then the member rows, each oldest first. A text cell that starts with =, +, -, @, a tab or a carriage return gets a ' in front, so a spreadsheet shows it and never runs it. Everything comes from the redacted audit log, the payment records and the key and member records: no secrets, and of a key only its id, prefix and label.
What are the columns of decisions.csv?
One row per decision event: payment.authorized, payment.denied, payment.step_up_required, the card.authorization.* events and action.executed or action.failed.
createdAt,eventId,type, anddecision:allow,deny,step_up, or for cards and actionsreleased,captured,refunded,executed,failed.- Who:
agentId,agentName,personId,personEmail,teamId,teamName,costCenter. Person, sub-team and cost center are the ones stamped on the payment when it was reserved. A decision with no payment, such as a deny, shows the agent's assignment on the day of the export. - What:
intentId,method,host,payTo(or the card merchant),amountUsd,currency,originalAmountMinor(minor units of the original currency),asset,network. - Why:
codes(the reason codes, separated by spaces),matchedRules(ruleId:outcomeof each rule that matched) andpolicyVersion.
What are the columns of approvals.csv?
approvalId,requestedAt,agentId,agentName,intentId,amountUsd,host.reason(why it was asked,thresholdby default),policyVersion,matchedRules.decision(approvedordenied),decidedByUserId,decidedByEmail,decidedAt,secondsToDecision,note.finalStatus:denied,expired,consumed(used by the payment),approved(and not yet used) orpending.closedAtis when it was denied, expired or consumed.
What are the columns of policy-changes.csv?
createdAt, eventId, type, actor, actorUserId, actorEmail, agentId, agentName, scope (org or agent:<id>), ruleId, previousVersion, newVersion, and change: the redacted event as JSON.
It covers rules created, updated or deleted, caps, hosts, networks, the base policy and its settings, scope rules, hosts added from the catalog, rules added from chat, and the decision webhook created, updated, deleted or with its signing secret rotated. Calls and tests of the webhook change nothing and are left out.
What are the columns of access.csv?
createdAt, eventId, source, type, actorUserId, actorEmail, subjectUserId, subjectEmail, agentId, agentName, teamId, teamName, details (JSON).
source says where each row comes from:
source |
Rows |
|---|---|
audit |
Per-person budgets, a person moved to viewer, by hand or by a plan downgrade (member.role_demoted), sub-team membership, agents bound to people, plan changes, wallet connectors, and every evidence export. |
key_record |
Org and agent keys created or revoked (org_api_key.created, agent_key.revoked…), from the key records: details has the key id, its prefix and its label. |
member_record |
member.joined: people who joined in the window and are still members, from the member records, with roleToday in details. |
How do I check that a pack is intact?
- Compute the SHA-256 of each file and compare it with
filesinmanifest.json. - Compute the SHA-256 of
manifest.jsonand look for it in thereport.evidence_exportedevent of that export, in the fieldmanifestSha256.
The dashboard does step 2 for you: after the download it shows the manifest's SHA-256 and says whether it is already in the audit log. The Exports table in the same block lists every pack with its window, rows and manifest hash. On the API, the same events are in GET /v1/audit?type=report.evidence_exported.
From a terminal (macOS; on Linux use sha256sum instead of shasum -a 256):
unzip burnbound-evidence-2026-01-01-to-2026-06-30.zip -d evidence
cd evidence
jq -r '.files | to_entries[] | "\(.value.sha256) \(.key)"' manifest.json | shasum -a 256 -c
shasum -a 256 manifest.json
The first command prints OK for every file whose hash matches. The second prints the manifest's hash, which must be the manifestSha256 of the event.
A manifest.json looks like this (hashes shortened):
{
"evidenceFormat": 1,
"org": { "id": "…", "name": "Acme" },
"window": {
"requested": { "from": "2026-01-01", "to": "2026-06-30" },
"effective": {
"from": "2026-01-01T00:00:00.000Z",
"until": "2026-07-01T00:00:00.000Z"
},
"clippedToRetention": false,
"retentionDays": 365
},
"generatedAt": "2026-07-01T09:30:00.000Z",
"generatedBy": { "userId": "…", "email": "…", "role": "owner" },
"plan": "team",
"files": {
"README.md": { "rows": null, "bytes": 3120, "sha256": "…" },
"decisions.csv": { "rows": 1284, "bytes": 402113, "sha256": "…" },
"approvals.csv": { "rows": 58, "bytes": 14220, "sha256": "…" },
"policy-changes.csv": { "rows": 31, "bytes": 18904, "sha256": "…" },
"access.csv": { "rows": 17, "bytes": 5031, "sha256": "…" }
}
}
manifest.json is stored in the ZIP without compression, so the dashboard can read it out of the download. A new set of files or columns raises evidenceFormat.
The audit log only grows, so the hash recorded at export time cannot be changed afterwards. A download that fails or is cancelled records no event.
What does the pack not cover yet?
access.csv is not a full list of who had access. It shows only what Burnbound records today:
- Removals of people are not audited, so they do not show.
- Invitations are not audited.
- Role changes are not audited, except a move to viewer.
- Joins come from the member records: a person who joined and left since does not show, and the role is today's, not the one they joined with.
- Keys come from the key records: the keys of an agent deleted since do not show.
Which controls does it help to document?
The pack helps you show your auditor how the agents' spending is controlled. It does not certify anything: it is not an audit opinion, a certification or a guarantee of compliance with any standard or law.
| Framework | Control | Files |
|---|---|---|
| SOC 2 | CC6, logical access | access.csv, and the approvers in approvals.csv |
| SOC 2 | CC8, change management | policy-changes.csv |
| ISO/IEC 27001:2022, Annex A | 5.15 access control, 5.18 access rights | access.csv |
| ISO/IEC 27001:2022, Annex A | 8.15 logging | The four CSV files and the manifest |
| EU AI Act | Article 12, record-keeping | decisions.csv and policy-changes.csv |
| EU AI Act | Article 14, human oversight | approvals.csv, and the step_up rows of decisions.csv |
For the day-to-day spend export and the monthly report, see Concepts.