API reference

Event envelope

Every Fingerly webhook is an HTTPS POST with the same headers, the same signature scheme and the same versioned JSON envelope around its data.

Every webhook Fingerly sends has the same shape: four headers you can act on, and a JSON envelope whose data depends on the event type.

Event types

TypeSent whenEnvironments
identification.completedAny identification finishes.live, test
visitor.suspectAn identification reaches the high level.live, test
identification.refusedAn identify request is refused.live, test
billing.status_changedYour organization starts or stops accepting traffic.live
usage.daily_settledA day of usage is settled.live, test

webhook.test is sent only when you choose Send test event for an endpoint. You cannot subscribe to it, and its data holds only endpoint_id. Ignore event types you do not handle.

Headers

  • Content-Typestring
    application/json.
  • User-Agentstring
    Fingerly-Webhooks/1.0.
  • X-Fingerly-Event-IDstring
    The envelope's id.
  • X-Fingerly-Event-Typestring
    The envelope's type, so you can route before parsing.
  • X-Fingerly-Timestampstring
    Unix seconds when this attempt was signed. It changes on every retry.
  • X-Fingerly-Signaturestring
    sha256= followed by the lowercase hex HMAC-SHA256 signature. While a secret is rotated, one such value per secret, separated by commas.

Signature

The signature is an HMAC-SHA256 over the timestamp, a full stop, and the raw request body, keyed with the endpoint's signing secret. Use the whole secret, whsec_ prefix included, as the key.

Signature
signed_payload = X-Fingerly-Timestamp + "." + raw_body
signature      = "sha256=" + hex(hmac_sha256(signing_secret, signed_payload))
  • Compare signatures in constant time.
  • Split the header on commas and accept the delivery if any signature matches.
  • Reject a timestamp more than five minutes from your clock.
  • Verify the exact bytes you received. Parsing and re-serialising the JSON changes them.

Envelope

  • idstring
    The event's ID, a UUIDv7. The same on every retry: deduplicate on it. Also sent as X-Fingerly-Event-ID.
  • typestring
    Always <event type>.
  • versioninteger
    The envelope version, 1.
  • organization_idstring
    Your organization.
  • environmentstring
    live for production traffic, test for staging and development.
  • created_atstring
    When the underlying fact happened, RFC 3339 in UTC. Not when it was delivered.
  • dataobject
    The event's data. Its fields are listed on each event's page.

Compatibility

  • New fields may be added to data and to the envelope within version 1. Ignore fields you do not know.
  • New event types are only delivered to endpoints that subscribe to them.
  • Do not rely on the order of JSON keys.