Application Patterns
Use one evidence record to preserve the facts your application consulted. These are application-owned patterns using Core’s HTTP API. Core does not supply provider connectors or execute the decisions shown here.
Billing, access and expiry extend the existing evidence scenarios. All values below are illustrative; the payload shapes and Evidence Lanes are optional.
On this page
Submission and retry recipe
Save one pattern’s payload as state_payload inside the envelope below. Use a specific application decision reference, its capture time and a fresh idempotency key. The complete access envelope is shown here so the example can be run against your local Quickstart service.
{
"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"
}
}# Set these to your local pilot service and service credentials.
CORE_URL='http://localhost:8080'
WRITE_KEY='YOUR_WRITE_KEY'
READ_KEY='YOUR_READ_KEY'
curl --fail-with-body -X POST "$CORE_URL/v1/snapshots" \
-H "Authorization: Bearer $WRITE_KEY" \
-H 'Idempotency-Key: access-customer-123-request-001' \
-H 'Content-Type: application/json' \
--data-binary @evidence.json
# Save the returned ID with your request/invoice reference.
SNAPSHOT_ID='PASTE_RETURNED_ID'
curl --fail-with-body "$CORE_URL/v1/snapshots/$SNAPSHOT_ID" \
-H "Authorization: Bearer $READ_KEY"
curl --fail-with-body "$CORE_URL/v1/snapshots/$SNAPSHOT_ID/verify" \
-H "Authorization: Bearer $READ_KEY"Each pattern below uses this submission flow. Retry the identical submission with the same key after an uncertain response. Use a new key for each new decision. Handle conflicting reuse explicitly; review cleanup timing and failure behavior. The application owns capture ordering and any durable retry mechanism.
Billing quantity
- Inputs
- Active subscription, ten billable seats, invoice period and the billing rule version.
- Decision
- The application calculates a ten-seat charge. Payment execution remains outside StateMirror.
{
"subject": "customer_123",
"invoice_ref": "invoice_001",
"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"
}Later investigation: Retrieve the saved snapshot when the invoice is disputed after seats drop to six. Inspect the historical quantity, period and rule version; verify integrity. Consult payment records separately to establish whether a charge executed.
Entitlement denial
- Inputs
- Active plan, ten occupied seats and a ten-seat entitlement.
- Decision
- The application denies an additional seat under its access rules.
{
"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 investigation: After a plan upgrade, retrieve by the original request reference and verify the submitted ten-of-ten seat count. Today’s plan does not establish the inputs used by the original request.
Trial expiry
- Inputs
- The expiry timestamp and the application’s evaluation time, both in UTC.
- Decision
- The application limits the account to basic features because the evaluation time is after expiry.
{
"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"
}Later investigation: After support extends the trial, retrieve and verify the original timestamps. Compare with the extension record. StateMirror preserves the application’s time observations; it does not establish clock accuracy.
External provider state
- Inputs
- The provider response actually consulted, its source version when known and when the application read it.
- Decision
- The application grants a subscription feature based on the active status it observed.
{
"subject": "customer_123",
"inputs": {
"subscription_status": "active",
"source": "billing-provider",
"source_updated_at": "2026-06-15T18:20:00.000Z",
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "subscription-rules@2026.06.12",
"decision": "grant_feature"
}Later investigation: If the provider later reports cancellation, inspect the preserved read time and source update time. The response may have been stale. Evidence proves neither provider truth nor that the response was fresh.
Rule versioning
- Inputs
- A configuration revision and the concrete threshold used by the application.
- Decision
- The application denies another seat under that revision.
{
"subject": "customer_123",
"inputs": {
"seats_used": 10,
"seat_limit": 10,
"configuration_revision": "entitlements-42"
},
"rule_version": "access-rules@2026.06.12",
"decision": "deny",
"reason": "seat_limit_reached"
}Later investigation: Compare the recorded revision and threshold with the rule artifact retained by your application team. StateMirror does not archive, execute or replay the referenced rule code.
A denial investigated 21 days later
Illustrative lifecycle, not a customer case study. It uses the same access evidence as the Quickstart and Workbench.
- Day 0: the application reads ten occupied seats against a ten-seat limit, denies another seat and submits the access envelope. It stores the returned snapshot ID with request_001.
- Day 21: the customer disputes the denial. Their plan has since been upgraded and a member removed. Current state permits access.
- Retrieve: support locates the saved ID. If only the original reference is available, query
GET /v1/snapshots?evidence_ref=access%3Acustomer_123%3Arequest_001with a read bearer key, then select the relevant returned ID. - Inspect and verify: inspect the ten-of-ten counts and rule version. Call the snapshot verification endpoint; in this intact example,
validistrue. If it fails, investigate preservation integrity before relying on the record. - Conclude: the application submitted facts showing its seat limit was reached at that moment. Check rule code and upstream records separately to assess whether those facts and the denial were correct.
The investigation avoids rebuilding the submitted context from current rows. It does not establish that ten seats were externally true or that enforcement succeeded.
Trace the evidence lifecycle → · Pilot one of your own decisions →