POST requests to your configured endpoints when specific events occur in Stora. When an event happens — such as an invoice being paid or a unit becoming occupied — Stora immediately notifies all endpoints subscribed to that event type.
Getting started
Create a webhook endpoint
Use the Webhook Endpoints API to register a publicly accessible HTTPS URL, the event types you want to subscribe to, and the API version.
Store your secret key
When you create an endpoint, Stora generates a secret key. Store it securely — you’ll use it to verify incoming requests.
Payload structure
Every webhook delivers a JSON payload with this structure:| Field | Description |
|---|---|
event.id | Unique identifier for the event — use this for idempotency |
event.type | The event type (e.g. invoice.paid, contact.created) |
event.api_version | Matches your endpoint’s API version — determines the data structure |
event.created_at | ISO 8601 timestamp of when the event occurred |
event.data | The resource that triggered the event, keyed by resource type |
Headers
Every webhook request includes these headers:| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | Stora-Webhooks/1.0 |
X-Stora-Signature | HMAC signature for verification (see below) |
X-Stora-Request-Id | Unique ID for this delivery attempt — useful for debugging |
Signature verification
All webhook requests are signed using HMAC SHA256. Always verify the signature before processing. The signature is in theX-Stora-Signature header:
- Extract the timestamp (
t) and signature (v1) from the header - Reconstruct the signed payload:
{timestamp}.{raw_request_body} - Compute the HMAC SHA256 using your endpoint’s secret key
- Compare the computed signature with
v1 - Optionally, check the timestamp is recent to prevent replay attacks
Retries
Stora automatically retries failed deliveries up to 6 times:| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 6 hours |
| 6th retry | 12 hours |
2xx status code, a network error occurs, or the request times out (20-second limit).
After 6 failed attempts, the delivery is marked as failed. If the endpoint is deleted or disabled before a scheduled retry, pending retries are cancelled.
Best practices
- Implement idempotency — use
event.idto ensure you don’t process the same event twice. Store processed event IDs and check before processing. - Process asynchronously — for time-consuming operations, queue the webhook for background processing after returning a success response.
- Log the request ID — use
X-Stora-Request-Idto correlate retry attempts when debugging. - Validate signatures — always verify the HMAC signature before processing.
- Monitor your endpoint — extended downtime may exhaust all retry attempts.
Available events
Contact
Contact
| Event | Description |
|---|---|
contact.created | Triggered when a contact is created. |
contact.updated | Triggered when the contact is updated. |
Contract
Contract
| Event | Description |
|---|---|
contract.created | Triggered when a contract is created. |
contract.signed | Triggered when a contract is signed. |
Coupon
Coupon
| Event | Description |
|---|---|
coupon.created | Triggered when a coupon is created. |
coupon.updated | Triggered when the coupon is updated. |
Credit Note
Credit Note
| Event | Description |
|---|---|
credit_note.created | Triggered when a new credit is created. |
credit_note.updated | Triggered when a credit note is updated. |
Deal
Deal
| Event | Description |
|---|---|
deal.created | Triggered when a deal is created. |
deal.lost | Triggered when a deal is lost. |
deal.reopened | Triggered when a deal is reopened |
deal.updated | Triggered when a deal is updated. |
deal.won | Triggered when a deal is won. |
Identity Verification
Identity Verification
| Event | Description |
|---|---|
identity_verification.cancelled | Triggered when an identity verification is cancelled |
identity_verification.failed | Triggered when an identity verification failed |
identity_verification.processing | Triggered when an identity verification is processing |
identity_verification.succeeded | Triggered when an identity verification succeeded |
Invoice
Invoice
| Event | Description |
|---|---|
invoice.created | Triggered when a new invoice is created. |
invoice.finalized | Triggered when an invoice is finalized. |
invoice.marked_uncollectible | Triggered when an invoice is marked as uncollectible. |
invoice.paid | Triggered when an invoice is mark as paid. |
invoice.updated | Triggered when an invoice is updated. |
Note
Note
| Event | Description |
|---|---|
note.created | Triggered when a note is created. |
note.updated | Triggered when a note is updated. |
Order
Order
| Event | Description |
|---|---|
order.completed | Triggered when the order is completed. |
order.created | Triggered when a new order is created. |
order.finalized | Triggered when a new order is finalized (ready to be paid). |
Protection Level
Protection Level
| Event | Description |
|---|---|
protection_level.created | Triggered when a protection level is created. |
protection_level.updated | Triggered when a protection level is updated. |
Subscription
Subscription
| Event | Description |
|---|---|
subscription.cancelled | Triggered when the subscription is cancelled. |
subscription.created | Triggered when the subscription is created. |
subscription.ended | Triggered when the subscription is ended. |
subscription.started | Triggered when the subscription is started. |
Task
Task
| Event | Description |
|---|---|
task.completed | Triggered when the task is completed. |
task.created | Triggered when a task is created. |
task.reopened | Triggered when a completed task is reopened. |
task.updated | Triggered when a task is updated. |
Tenancy
Tenancy
| Event | Description |
|---|---|
tenancy.created | Triggered when a tenancy is created. |
tenancy.started | Triggered when the tenancy is started. |
Unit
Unit
| Event | Description |
|---|---|
unit.available | Triggered when a unit is made available. |
unit.created | Triggered when a unit is created. |
unit.deallocated | Triggered when a unit is deallocated. |
unit.occupied | Triggered when a unit is occupied. |
unit.overlocked | Triggered when a unit is overlocked. |
unit.repossessed | Triggered when a unit is repossessed. |
unit.reserved | Triggered when a unit is reserved. |
unit.unavailable | Triggered when a unit is made unavailable. |
unit.updated | Triggered when a unit is updated. |
Unit Type
Unit Type
| Event | Description |
|---|---|
unit_type.created | Triggered when a unit type is created. |
unit_type.updated | Triggered when a unit type is updated. |