Skip to main content
Slate webhooks push event data to your server the moment something happens in our system, so you never need to poll for updates. When a subscribed event occurs, Slate sends an HTTP POST request to your registered endpoint with a JSON payload describing the event.

Getting started

1

Build a webhook endpoint

Create an HTTPS endpoint on your server that accepts POST requests and returns a 200 OK response. The endpoint must be publicly reachable and support TLS. Return a 2xx before performing any slow processing. If there is additional processing needed, use a queue internally if needed.
2

Register your endpoint with Slate

Send your endpoint URL to your Slate integration contact. We’ll provision your webhook and return a HMAC-SHA256 signing secret used to verify that every delivery came from Slate.
3

Verify signatures and process events

On each incoming request, verify the svix-signature header using your signing secret before trusting the payload. Then act on the event type and matter data in the body.

Receiving events

Slate delivers every event as an HTTP POST to your registered endpoint.

Request headers

Example delivery

Responding to deliveries

Return any HTTP 2xx status within 30 seconds. Any non-2xx response or timeout triggers a retry.

Event types

Each webhook delivery carries an event type that identifies what happened. The payload’s eventType field holds it, so read eventType first to decide how to handle the rest of the body. Your endpoint only receives the event types it’s subscribed to. Every payload includes these fields:

DOCUMENT_READY

Fired when a signed or processed document becomes available on a matter.

Wet-ink documents

If a document is signed in ink rather than electronically, wetInk is true. Which document you receive depends on your workflow:
  • If QC comes before signing, your workflow completes when the document is marked for wet-ink signing. downloadUrl and fileUUID point to the prepared, unsigned document. You sign it in ink outside Slate.
  • If QC comes after signing, you upload the signed wet-ink scan to Slate for QC. downloadUrl and fileUUID point to the signed scan.

QCR_COMPLETED

Fired when a reviewer approves or rejects a quality control request. Use approved to tell the two outcomes apart. This event carries no document. A document request’s document is only created once QC approves it. When it’s ready, you receive it in a separate DOCUMENT_READY event with the same fileRequestUUID.
A QC decision can be undone and made again, so you may receive more than one QCR_COMPLETED for the same qcrUUID. Each has a different svix-id. Use occurredOn to find the latest decision. Additional event types will be added over time. Your Slate contact will notify you when new events become available for your integration. Slate follows an additive-only policy: existing fields will not be removed or renamed in a breaking way, and new fields may be added to any event type. Build your handler to ignore unknown fields and unknown event types.

Verifying signatures

Always verify the signature before processing a payload. This confirms the request came from Slate and hasn’t been tampered with.

How it works

Slate constructs a signed string from three components, then signs it with HMAC-SHA256 using your signing secret that will be shared at the time your endpoint is registered with Slate:
The svix-signature header may contain multiple signatures (space-separated). A request is valid if any one of them matches — this supports secret rotation without downtime. Compare svix-timestamp to the current time and discard the request if the difference exceeds 5 minutes. Slate’s webhook delivery is powered by Svix, and Svix publishes official SDKs in Python, Node.js, Go, Java, Ruby, PHP, Rust, and more. The SDK handles signature verification, timestamp checking, and secret decoding in a single call.
Install: pip install svix

Manual verification — Python

Manual verification — Node.js

Retries and delivery

If your endpoint doesn’t return a 2xx within 30 seconds, Slate retries with exponential backoff: After 9 attempts the message is marked failed. Contact your Slate integration contact if you need a missed event replayed.

Idempotency

Because a delivery may be attempted more than once, your handler should be idempotent. Processing the same event twice should produce the same result as processing it once. Use the svix-id header as a stable unique key to deduplicate incoming events.

Ordering

Events are delivered in order on a best-effort basis. Retries and network conditions can cause reordering, so design your handler to tolerate out-of-order events if strict ordering matters to your use case.