Docs

Events

Events record every significant change in your Stile account, with API delivery state for reconciliation.

Every time something significant happens — a session is verified, a review is resolved, a trust-reuse grant changes — Stile creates an event. Webhooks and the Events API share the core id, object, type, data, and created envelope. The API enriches that envelope with version and delivery state for reconciliation; those API-only fields are not included in webhook POST bodies. Treat webhook delivery as the source of truth — poll this API on cold start or for reconciliation.

Examples show cURL, Python, Go, and Node.js. Approved preview users can also use the private-preview Node.js SDK as a typed convenience wrapper for the full event catalog.

The event object

{
  "id": "evt_abc123",
  "object": "event",
  "type": "verification_session.verified",
  "api_version": "2025-01-01",
  "livemode": true,
  "created": 1741564800,
  "pending_webhooks": 1,
  "data": {
    "object": {
      "id": "vks_xyz789",
      "object": "verification_session",
      "status": "verified",
      "type": "identity",
      "client_reference_id": "order_123",
      "current_method": "document_capture",
      "age_tier": "min_age_21",
      "jurisdiction": "US-CA",
      "jurisdiction_audit_declared": "US-CA",
      "jurisdiction_audit_ip_derived": "US-CA",
      "jurisdiction_audit_resolved": "US-CA",
      "jurisdiction_audit_source": "input_field",
      "jurisdiction_audit_mismatch": false,
      "verification_path": null,
      "workflow_version_id": "wfv_abc123",
      "livemode": true,
      "completed_at": 1741564800,
      "created": 1741561200,
      "verification_result": {
        "method": "document_capture",
        "confidence": 0.98,
        "age_verified": true,
        "age_estimate": 29,
        "identity_verified": true,
        "face_match_passed": true,
        "barcode_cross_ref_match": true,
        "liveness_score": 0.97
      }
    }
  },
  "delivery_summary": {
    "total": 1,
    "delivered": 1,
    "failed": 0,
    "pending": 0
  }
}
ParameterTypeDescription
idstringUnique event identifier (evt_...). Stable across webhook retries — deduplicate on this value.
objectstringAlways "event".
typestringThe event type, e.g. "verification_session.verified". See the full catalog below.
api_versionstring | nullAPI version stored with the event. Events API only; omitted from webhook POST bodies.
livemodebooleanWhether the event belongs to live mode (true) or test mode (false). Events API only; omitted from webhook POST bodies.
creatednumberUnix timestamp (seconds) when the event was created.
pending_webhooksnumberNumber of endpoint deliveries queued when the event was dispatched. Events API only. This is not a live completion counter; use delivery_summary for current delivery state.
dataobjectEnvelope containing data.object, a snapshot of the resource that caused the event. For verification_session.* events, data.object is the session. Retrieve the resource for its current state.
delivery_summaryobject | nullLive delivery counts: total, delivered, failed, and pending. Events API only; webhook POST bodies do not include it.
deliveriesWebhookDelivery[]Current delivery record for each subscribed endpoint. Included only by GET /v1/events/:id, not list responses or webhook POST bodies.

Events are snapshots

The data.object payload reflects the compact session event snapshot as it was when the event fired, not the full verification-session response. It omits secrets, metadata, collected data, expires_at, URLs, and the full results array. If you need the current full state — for example after processing a backlog — retrieve the session via the Verification Sessions API.

Retrieve an event

GET/v1/events/:id
curl https://api.stile.id/v1/events/evt_abc123 \
  -H "Authorization: Bearer stile_sk_..."
import requests

res = requests.get(
    "https://api.stile.id/v1/events/evt_abc123",
    headers={"Authorization": "Bearer stile_sk_..."},
)
event = res.json()
print(event["type"])  # "verification_session.verified"
req, _ := http.NewRequest("GET", "https://api.stile.id/v1/events/evt_abc123", nil)
req.Header.Set("Authorization", "Bearer stile_sk_...")
res, _ := http.DefaultClient.Do(req)
const event = await stile.events.retrieve("evt_abc123");
console.log(event.type);  // "verification_session.verified"
console.log(event.data.object); // The verification-session event snapshot

List events

GET/v1/events

Returns a paginated list of events. Filter by type, time window, or session to reconcile your records against what Stile recorded.

ParameterTypeDescription
limitnumber= 10Number of events to return. Between 1 and 100.
starting_afterstringReturn older events that follow this ID in the newest-first list.
ending_beforestringReturn newer events that precede this ID in the newest-first list.
typestringFilter by event type (e.g. "verification_session.verified").
created_afternumberUnix timestamp. Only return events created after this time.
created_beforenumberUnix timestamp. Only return events created before this time.
session_idstringFilter events related to a specific verification session.

Use only one cursor per request: starting_after moves toward older events and ending_before moves toward newer events.

curl "https://api.stile.id/v1/events?limit=50" \
  -H "Authorization: Bearer stile_sk_..."
import requests

res = requests.get(
    "https://api.stile.id/v1/events",
    headers={"Authorization": "Bearer stile_sk_..."},
    params={"limit": 50},
)
data = res.json()
req, _ := http.NewRequest("GET", "https://api.stile.id/v1/events?limit=50", nil)
req.Header.Set("Authorization", "Bearer stile_sk_...")
res, _ := http.DefaultClient.Do(req)
const { data } = await stile.events.list({ limit: 50 });

for (const event of data) {
  console.log(event.type, event.created);
}

Event types

The complete catalog. Events cover three areas: the verification session lifecycle (verification_session.*), manual review outcomes (session_review.*), and trust-reuse grants (trust_reuse_grant.*, trust_reuse_consent.*). Subscribe per endpoint via enabled_events — or use ["*"] to receive everything (see Webhook Endpoints).

Event typeTrigger
verification_session.createdA new verification session was created.
verification_session.verifiedThe session completed successfully.
verification_session.failedAll verification methods were exhausted.
verification_session.cancelledThe session was cancelled.
verification_session.expiredThe session expired without completion.
session_review.flaggedA session was routed to manual review by policy or fraud signals.
session_review.approvedA reviewer approved a flagged session.
session_review.rejectedA reviewer rejected a flagged session — treat it as not verified.
session_review.escalatedA flagged session was escalated for senior review.
trust_reuse_grant.createdA returning user reused a verification at another Stile operator.
trust_reuse_grant.revokedA trust-reuse grant was revoked. See Trust Reuse.
trust_reuse_consent.revoked_by_userA user withdrew their trust-reuse consent.

Delivery status

pending_webhooks records how many endpoint deliveries were queued when the event was dispatched. It is retained for compatibility and does not decrement as deliveries finish.

Use delivery_summary.pending for the current number of unresolved deliveries. delivery_summary is computed from delivery records whenever you list or retrieve events. Inspect each endpoint's current delivery state with the deliveries API.

Deduplication

One event can produce multiple webhook delivery records — exactly one per subscribed endpoint. Retries update the original record rather than creating attempt-history rows. The event id is the stable identity across every endpoint delivery.

Dedupe on the event id, not the delivery id

Record processed event IDs and skip events you've already handled. Automatic retries of one delivery keep both the event id and Stile-Webhook-Id; a second subscribed endpoint has its own delivery record for the same event. Manual retries also reuse the original delivery record. The event ID is therefore the stable business-level deduplication key. See handling duplicates for a worked example.

Next steps

On this page