Docs / StateMirrorDOCUMENT / STATEMIRROR
Three decisions to investigate later
StateMirror accepts application-defined JSON; this site uses one consistent example shape for demonstration. The access scenario uses the same payload as the quickstart. Billing and expiry retain their own inputs.
Billing / subscription dispute
- Before
- The application reads an active subscription and a ten-seat billable quantity for the invoice period.
- Decision
- The application declares a charge for ten seats under its billing rule version.
- Evidence
- Submit this envelope to
POST /v1/snapshotswith a write bearer key and a uniqueIdempotency-Key.
EXAMPLE / BILLING / JSONTX_EVIDENCE
{
"evidence_ref": "billing:customer_123:request_001",
"evidence_type": "billing_decision",
"captured_at": "2026-06-15T18:22:31.000Z",
"state_payload": {
"subject": "customer_123",
"inputs": {
"subscription_status": "active",
"billable_seats": 10,
"period": "2026-06",
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "billing-rules@2026.06.12",
"decision": "charge_ten_seats",
"correlation_id": "request_001"
}
}- Later
- The customer reduces their seats to six and disputes the earlier invoice.
- Investigation
- Which quantity and subscription state did the application use for this invoice?
- Result
- Retrieve the submitted ten-seat quantity, period, rule version and declared charge. This evidence describes the application’s inputs; it does not prove payment execution. Verify the stored payload hash and chain linkage through the snapshot verification endpoint.
Access / entitlement denial
- Before
- The plan is active, but the application reads ten occupied seats against a ten-seat entitlement.
- Decision
- The application denies an additional seat under its access rules.
- Evidence
- Submit this envelope to
POST /v1/snapshotswith a write bearer key and a uniqueIdempotency-Key.
EXAMPLE / ACCESS / JSONTX_EVIDENCE
{
"evidence_ref": "access:customer_123:request_001",
"evidence_type": "access_decision",
"captured_at": "2026-06-15T18:22:31.000Z",
"state_payload": {
"subject": "customer_123",
"inputs": {
"plan_status": "active",
"seats_used": 10,
"seat_limit": 10,
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "access-rules@2026.06.12",
"decision": "deny",
"reason": "seat_limit_reached",
"correlation_id": "request_001"
}
}- Later
- An administrator removes a member and upgrades the account. The current entitlement now allows another seat.
- Investigation
- Why did the application deny access while the subscription was active?
- Result
- Retrieve the submitted seat count and limit, read time and declared denial. Those values explain the recorded rule inputs without relying on today’s entitlement row. Verify the stored payload hash and chain linkage through the snapshot verification endpoint.
Expiration / downgrade decision
- Before
- The application reads a trial expiry of 18:00 UTC and evaluates the request at 18:22 UTC.
- Decision
- The application limits the account to its basic feature set.
- Evidence
- Submit this envelope to
POST /v1/snapshotswith a write bearer key and a uniqueIdempotency-Key.
EXAMPLE / EXPIRY / JSONTX_EVIDENCE
{
"evidence_ref": "expiry:customer_123:request_001",
"evidence_type": "expiry_decision",
"captured_at": "2026-06-15T18:22:31.000Z",
"state_payload": {
"subject": "customer_123",
"inputs": {
"expires_at": "2026-06-15T18:00:00.000Z",
"evaluated_at": "2026-06-15T18:22:30.000Z",
"signal": "expired"
},
"rule_version": "expiry-rules@2026.06.12",
"decision": "downgrade_to_basic",
"correlation_id": "request_001"
}
}- Later
- Support extends the trial. The current expiry timestamp is later than the original request.
- Investigation
- Which expiry and evaluation time led to the downgrade before the extension?
- Result
- Retrieve the submitted expiry, evaluation time and declared downgrade. Inspect those historical values alongside the later extension record. Verify the stored payload hash and chain linkage through the snapshot verification endpoint.
Retrieve and verify
Keep the returned snapshot ID with your application’s request or invoice reference. Use GET /v1/snapshots/{snapshot_id} to retrieve the payload and GET /v1/snapshots/{snapshot_id}/verify to check its integrity. Both require a service bearer token.
Verification does not establish that the inputs were accurate, the decision was correct or an external action succeeded. A missing snapshot cannot establish an outcome.