Skip to content
Docs / StateMirror
DOCUMENT / 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.

TYPE
Application evidence

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/snapshots with a write bearer key and a unique Idempotency-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"
  }
}
Application-submitted envelope. Copy the complete JSON.
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/snapshots with a write bearer key and a unique Idempotency-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"
  }
}
Application-submitted envelope. Copy the complete JSON.
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/snapshots with a write bearer key and a unique Idempotency-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"
  }
}
Application-submitted envelope. Copy the complete JSON.
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.