Webhooks and the API
Signed HTTPS events when work is approved or money moves, plus token-authenticated endpoints.
Plans: Every paid plan, from $19 a month. Throughput scales by tier. See plans and pricing
When a client signs off, a change order moves, or an invoice is paid, Stria can tell your own systems
about it. Webhooks are HTTPS POSTs carrying the event, signed so you can prove they came from Stria
and not from someone who guessed your endpoint.
The events
Eleven, grouped by what they are about. The authoritative list is a database table, and the
TypeScript union and the settings UI are generated from it — so this set cannot drift from what
actually fires.
| Event | Fires when |
|---|---|
deliverable.sent | A deliverable is sent for review |
feedback.created | A client submits feedback |
signoff.recorded | A sign-off completes |
change_order.sent | A change order is sent for signing |
change_order.signed | A change order is signed |
change_order.declined | A change order is declined |
change_decision.sent | A change decision or milestone gate is sent |
invoice.sent | An invoice moves from draft to open |
invoice.paid | An invoice is paid, in full or in part |
invoice.overdue | An invoice passes its due date unsettled |
deposit.cleared | A deposit clears and the kickoff gate releases |
The money events fire from any source — Stripe, a manual mark-paid, recurring billing, a proposal
deposit — because they are emitted by database triggers on the state transition itself rather than by
one caller. Demo data never produces a delivery.
Verifying a delivery
Every request carries a Standard Webhooks signature: HMAC-SHA256 over the delivery id, the timestamp
and the raw body, base64, prefixed v1,. Signing the id and timestamp rather than only the body is
what makes a captured payload un-replayable and binds a signature to one delivery. Reject anything
older than about five minutes, verify against the raw body before any parse, and compare in
constant time.
A legacy hex signature over the body alone is still sent for receivers built before that scheme. It
will be retired with a Sunset header and 90 days' notice, not silently.
Rotation is not an outage
Rotating produces a new secret and keeps the previous one valid for an overlap window — 24 hours by
default. During the overlap two signatures arrive in one delivery, and the delivery is authentic
if either verifies. The new secret is listed first, so a verifier that stops at the first match stops
on the one that outlives the window.
Delivery, retries and duplicates
Delivery is at-least-once. No HTTP-based system can offer exactly-once, because a sender cannot
tell a lost request from a lost response. Duplicates are the contract, so deduplicate on the delivery
id — it is stable across every retry and across an admin-triggered replay, precisely so a correct
receiver ignores one.
- First attempt is immediate. Retries run 10s, 30s, 2m, 10m, 1h, 6h, 24h — eight attempts, about a
31-hour horizon, each delay fully jittered so a shared outage does not produce a synchronised burst
when it clears.
- Retryable:
5xx,408,429(Retry-Afteris honoured), and network or timeout failures. - Not retryable: any other
4xx. A400or422means you will never accept this payload, so it
is marked dead after one attempt and surfaced immediately rather than retried for 31 hours behind a
green-looking "still retrying".
- Timeout is five seconds per attempt. Return
2xximmediately and process asynchronously. - After 20 consecutive dead deliveries the endpoint is disabled automatically and the owner notified.
There is no ordering. Use the payload timestamp and resource state to discard stale events: an
invoice.sent arriving after an invoice.paid for the same invoice should be dropped, not applied.
Requirements for your endpoint
HTTPS only — plain HTTP is rejected at registration. Private, loopback and link-local addresses are
blocked, and the check runs on every attempt rather than only at registration, because a hostname
can be re-pointed between a first attempt and a retry six hours later.
Rate limits, by plan
API and webhook registration are included on every paid plan from $19 a month. What scales is
throughput: 60 requests a minute on the entry tier, 120 in the middle, 300 at the top, measured per
organisation. Free and trial workspaces cannot mint tokens.
Recovering from an outage does not need a replay — poll the matching list endpoint with
updated_since, which is correct regardless of what the queue did.
Full reference
Schemas, error bodies, the authentication model and the OpenAPI specification are in the
Partner API documentation: webhooks,
rate limits, authentication, and
Other connections
- Stria and Slack — Scope checks on the channels you nominate — and a consent screen with four scopes on it.
- Stria and Stripe — Your Stripe account, your money, your merchant relationship — Stria issues the invoice.
- Stria and Xero — Invoices and payments pushed to your ledger, and reconciliation read back.
- Stria and QuickBooks Online — Invoices and payments pushed to your ledger, and reconciliation read back.
- Stria and Asana or Linear — Push an approved item to the tracker your team already works in. One way, one item at a time.
Start your 14-day trial · See plans and pricing · Partner API reference