Skip to content

GuidesWorking with the API

Audit trail

Everything that happens to an envelope — created, sent, viewed, signed, voided — is recorded as an event. Events are hash-chained, so any change to the record shows.

Read the events

GET /v1/envelopes/{id}/events returns every event in the order it happened, in one answer. It needs envelopes:read.

curl https://api.skanything.io/v1/envelopes/env_4f9c2d7e1b8a4c6f9e2d3b7a1c5e8f02/events \
  -H "Authorization: Bearer $SA_API_KEY"
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "evt_10482",
      "object": "event",
      "type": "recipient_signed",
      "actor_type": "recipient",
      "actor_email": "sam@example.com",
      "recipient_id": "rcp_1a7c3e9b5d2f4a8c6e0b9d1f3a5c7e2b",
      "ip": "203.0.113.24",
      "occurred_at": "2026-11-04T16:46:03.120Z",
      "data": { "…": "…" },
      "hash": "3b6f0c2e9a…"
    }
  ]
}
  • type is the audit event, in snake_case (envelope_sent, recipient_viewed, recipient_signed, envelope_voided, …). These aren’t the webhook names, and their ids aren’t webhook event ids.
  • actor_type says who acted: a user, a recipient, the system, or api for a call made with a key.
  • hash is the event’s SHA-256, in lowercase hex. Each one covers the event and the hash before it.

Verify the chain

GET /v1/envelopes/{id}/events/verify recomputes the chain on our side and tells you whether it’s intact. Store head_hash with your own records: if it ever changes for a completed envelope, something changed.

{
  "valid": true,
  "events": 14,
  "head_hash": "9c1e7a3f5b2d…"
}

The certificate of completion (GET /v1/envelopes/{id}/certificate, and the last pages of the signed PDF) summarises the same trail for people.