Evidence Chain
The Evidence Chain is a tamper-evident audit log of everything that happens in AutopayOS. Every intent, cart verification, payment, and policy decision is recorded with cryptographic hashes that ensure integrity.
Overview
Events are linked in a cryptographic chain:
| Event | Previous Hash | Current Hash |
|---|---|---|
| Event #1 | — | abc123 |
| Event #2 | abc123 | def456 |
| Event #3 | def456 | ghi789 |
Each event contains:
- Data: The event payload
- Previous hash: Hash of the previous event
- Current hash: SHA-256 hash of this event + previous hash
If any event is modified, the hash chain breaks, making tampering detectable.
Event types
| Event Type | Description | Triggered By |
|---|---|---|
INTENT_ISSUED | Intent mandate was approved | Intent creation |
INTENT_DENIED | Intent was rejected by policy | Intent creation |
INTENT_EXPIRED | Intent exceeded time limit | Expiration |
CART_VALIDATED | Cart verification passed | Cart validation |
CART_REJECTED | Cart verification failed | Cart validation |
PM_ISSUED | Payment mandate was created | Payment execution |
PAYMENT_AUTHORIZED | Payment was authorized by rail | Payment execution |
PAYMENT_CAPTURED | Funds were captured | Payment capture |
PAYMENT_FAILED | Payment failed | Payment failure |
ALERT_CREATED | Policy violation alert | Various |
AGENT_REVOKED | Agent was revoked | Admin action |
Query evidence
Get recent events
<tabs> <tab title="TypeScript">const evidence = await client.getEvidence({
last: 50,
});
console.log('Events:', evidence.events.length);
console.log('Chain valid:', evidence.chainValid);
for (const event of evidence.events) {
console.log(`${event.eventType} at ${event.createdAt}`);
}curl "https://api.autopayos.com/ap2/evidence/export?last=50" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"Response
{
"events": [
{
"id": "evt_abc123",
"seq": 1042,
"eventType": "INTENT_ISSUED",
"actorDid": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"contextId": "ctx_xyz789",
"data": {
"mandateId": "intent_abc123",
"amount": 50.00,
"currency": "USD",
"merchantDomain": "amazon.com"
},
"hashPrev": "sha256:abc123...",
"hashCurr": "sha256:def456...",
"createdAt": "2025-12-17T10:00:00Z"
},
{
"id": "evt_def456",
"seq": 1043,
"eventType": "CART_VALIDATED",
"actorDid": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"contextId": "ctx_xyz789",
"data": {
"intentId": "intent_abc123",
"cartHash": "sha256:cart123...",
"total": 38.85
},
"hashPrev": "sha256:def456...",
"hashCurr": "sha256:ghi789...",
"createdAt": "2025-12-17T10:00:05Z"
}
],
"chainValid": true,
"fromSeq": 1042,
"toSeq": 1043
}Search events
By event type
curl "https://api.autopayos.com/ap2/evidence/search?eventType=PAYMENT_AUTHORIZED" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"By agent
curl "https://api.autopayos.com/ap2/evidence/search?actorDid=did:key:z6Mk..." \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"By context
Context IDs link related events (e.g., all events for one shopping session):
curl "https://api.autopayos.com/ap2/evidence/search?contextId=ctx_xyz789" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"By time range
curl "https://api.autopayos.com/ap2/evidence/search?from=2025-12-17T00:00:00Z&to=2025-12-17T23:59:59Z" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"Transaction bundles
Get all evidence for a specific transaction:
<tabs> <tab title="TypeScript">const bundle = await client.getEvidenceBundle(transactionId);
console.log('Transaction:', bundle.transactionId);
console.log('Events:', bundle.events.length);
console.log('Chain valid:', bundle.chainValid);
console.log('Summary:', bundle.summary);curl "https://api.autopayos.com/ap2/evidence/bundle/txn_abc123" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"Response
{
"transactionId": "txn_abc123",
"events": [
{ "eventType": "INTENT_ISSUED", "seq": 1042 },
{ "eventType": "CART_VALIDATED", "seq": 1043 },
{ "eventType": "PM_ISSUED", "seq": 1044 },
{ "eventType": "PAYMENT_AUTHORIZED", "seq": 1045 },
{ "eventType": "PAYMENT_CAPTURED", "seq": 1046 }
],
"chainValid": true,
"summary": {
"agent": "did:key:z6Mk...",
"principal": "did:key:z6Mp...",
"merchant": "amazon.com",
"amount": 38.85,
"currency": "USD",
"status": "CAPTURED",
"startedAt": "2025-12-17T10:00:00Z",
"completedAt": "2025-12-17T10:00:15Z"
}
}Verify chain integrity
Check that the evidence chain hasn't been tampered with:
<tabs> <tab title="TypeScript">const verification = await client.verifyEvidenceChain({
fromSeq: 1000,
toSeq: 1100,
});
if (verification.valid) {
console.log('Chain integrity verified');
} else {
console.error('Chain broken at seq:', verification.brokenAt);
}curl "https://api.autopayos.com/ap2/evidence/verify?fromSeq=1000&toSeq=1100" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY"Verification response
{
"valid": true,
"fromSeq": 1000,
"toSeq": 1100,
"eventsVerified": 101,
"verifiedAt": "2025-12-17T10:30:00Z"
}Or if broken:
{
"valid": false,
"brokenAt": 1050,
"expectedHash": "sha256:abc123...",
"actualHash": "sha256:xyz789...",
"message": "Hash mismatch at sequence 1050"
}Export evidence
Export evidence for compliance or auditing:
JSON export
curl "https://api.autopayos.com/ap2/evidence/export?format=json&from=2025-12-01&to=2025-12-17" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY" \
-o evidence-export.jsonCSV export
curl "https://api.autopayos.com/ap2/evidence/export?format=csv&from=2025-12-01&to=2025-12-17" \
-H "Authorization: Bearer $AUTOPAYOS_API_KEY" \
-o evidence-export.csvReal-time streaming
Subscribe to evidence events via WebSocket:
const ws = new WebSocket('wss://api.autopayos.com/evidence/stream');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'subscribe',
token: apiKey,
filters: {
eventTypes: ['PAYMENT_AUTHORIZED', 'PAYMENT_FAILED'],
},
}));
};
ws.onmessage = (event) => {
const evidence = JSON.parse(event.data);
console.log('New event:', evidence.eventType);
};Event details
INTENT_ISSUED
{
"eventType": "INTENT_ISSUED",
"data": {
"mandateId": "intent_abc123",
"agentDid": "did:key:z6Mk...",
"principalDid": "did:key:z6Mp...",
"maxAmount": 100.00,
"currency": "USD",
"merchantDomain": "amazon.com",
"policyId": "pol_xyz789",
"policyVersion": 3,
"policyHash": "sha256:..."
}
}CART_VALIDATED
{
"eventType": "CART_VALIDATED",
"data": {
"intentId": "intent_abc123",
"cartHash": "sha256:cart...",
"merchant": "amazon.com",
"itemCount": 3,
"subtotal": 35.97,
"tax": 2.88,
"total": 38.85,
"currency": "USD",
"rail": "STRIPE"
}
}PM_ISSUED
{
"eventType": "PM_ISSUED",
"data": {
"mandateId": "pm_abc123",
"intentId": "intent_abc123",
"amount": 38.85,
"currency": "USD",
"merchant": "amazon.com",
"rail": "STRIPE",
"expiresAt": "2025-12-17T10:05:00Z"
}
}PAYMENT_AUTHORIZED
{
"eventType": "PAYMENT_AUTHORIZED",
"data": {
"mandateId": "pm_abc123",
"rail": "STRIPE",
"railTransactionId": "pi_3abc123...",
"amount": 38.85,
"currency": "USD",
"status": "authorized"
}
}Context tracking
Events are grouped by contextId for A2A sessions:
| Event | Context | Reference |
|---|---|---|
INTENT_ISSUED | ctx_abc123 | mandateId: intent_001 |
CART_VALIDATED | ctx_abc123 | intentId: intent_001 |
PM_ISSUED | ctx_abc123 | mandateId: pm_001 |
PAYMENT_AUTHORIZED | ctx_abc123 | mandateId: pm_001 |
Query all events for a session:
const sessionEvents = await client.getEvidence({
contextId: 'ctx_abc123',
});Compliance use cases
Audit trail
Generate a complete audit trail for a time period:
const audit = await client.generateAuditReport({
from: '2025-12-01T00:00:00Z',
to: '2025-12-31T23:59:59Z',
includeViolations: true,
includeSuccessful: true,
});Policy violation report
Find all policy violations:
const violations = await client.getEvidence({
eventTypes: ['INTENT_DENIED', 'CART_REJECTED'],
from: '2025-12-01',
});Agent activity report
Get all activity for a specific agent:
const agentActivity = await client.getEvidence({
actorDid: 'did:key:z6Mk...',
from: '2025-12-01',
});Best practices
1. Verify regularly
Periodically verify chain integrity:
// Daily verification job
const lastSeq = await getLastVerifiedSeq();
const currentSeq = await getCurrentSeq();
const result = await client.verifyEvidenceChain({
fromSeq: lastSeq,
toSeq: currentSeq,
});
if (!result.valid) {
await alertSecurityTeam(result);
}2. Store context IDs
Always track context IDs for correlation:
const contextId = `session_${Date.now()}_${agentDid}`;
const permission = await client.requestPermission({
...params,
contextId,
});
// Later: query all events for this session
const events = await client.getEvidence({ contextId });3. Export for compliance
Regularly export evidence for long-term storage:
// Monthly export
const evidence = await client.exportEvidence({
from: '2025-12-01',
to: '2025-12-31',
format: 'json',
});
await s3.upload({
Bucket: 'compliance-evidence',
Key: `evidence-2025-12.json`,
Body: evidence,
});Next steps
- Policy configuration — Define rules that generate evidence
- Webhooks — Real-time evidence notifications
- API Reference — Complete evidence endpoints