POST when something happens in your tenant. Register endpoints with POST /v1/webhooks and choose the events you want.
Envelope
Every delivery has the same envelope. Thedata object depends on the event.
Headers
Event catalogue
Event delivery
event.created
event.created
An event was accepted, online through
POST /v1/events or offline through POST /v1/sync/batch. The data includes your payload.Online:category is the code of the category of your catalog the type belongs to. requires_teams says whether the type sends a field team, and dispatch.status what the optional teams module will do: queued, manual, not_dispatchable (with reason: type_does_not_require_teams), off or sandbox. metadata is present only when the event was sent with metadata. labels gives, for each payload key that is a field of the parser the event was written with, the field label and, for enumerated fields, the label of the chosen option; the codes in payload never change, so your systems can keep matching on them. labels is absent when the event has no parser.From sync:event.delivered
event.delivered
The event was delivered over the internet path (
rest_full or rest_compressed) or through a channel of your cascade. The event is now completed. Its stored payload is cleared at this point for a type that does not send a team; for a type that sends a team it is kept until the event is closed or its missions end (see Get event).channel is the delivery channel: rest_full, rest_compressed, sms, voice, satellite, lora or edge. attempts counts every attempt across the cascade.event.failed
event.failed
No channel delivered the event and it could not be queued.
channel is the last channel tried. error is the last error, or null.event.status_changed
event.status_changed
The event was queued for delivery when connectivity returns (store-and-forward, or every channel of the cascade was exhausted). It stays Missions never change the status of an event, so a mission outcome does not send this webhook. Follow missions with
pending until it is reconciled.mission.status_updated.Offline sync and devices
sync.completed
sync.completed
A sync batch was processed. Sent once per batch.
device.synced
device.synced
A registered device synced its queue.
accepted and duplicates are counts.Connectivity
connectivity.degraded
connectivity.degraded
A zone left Changes between two states that are not
online.online (for example degraded to offline) do not send a webhook. Read the current state with GET /v1/connectivity/status.connectivity.restored
connectivity.restored
A zone returned to
online.zone_id is the zone code. With a sandbox key, these events follow the simulated state of the zone and carry "environment": "sandbox".
Teams
team.created
team.created
team.updated
team.updated
fields lists the names of the fields that changed.team.deleted
team.deleted
team.dispatched
team.dispatched
A team was dispatched to an event. The data depends on how.By a user:When the operator dispatched a team that does not cover the event type, or lacks equipment the type calls for, the data also carries As a substitution, when the previous team did not acknowledge within your acknowledgement timeout. The previous mission is set to
warnings, for example [{ "code": "no_coverage" }, { "code": "missing_equipment", "detail": ["defibrillator"] }]. The dispatch still happened.Automatically:FAILED (you also receive mission.status_updated for it) and a new mission is created for the replacement team:team.equipment.added
team.equipment.added
team.equipment.updated
team.equipment.updated
status and quantity are null when they were not changed.team.equipment.removed
team.equipment.removed
Missions
mission.created
mission.created
mission.status_updated
mission.status_updated
status is one of CREATED, SENT, ACK, ON_ROUTE, ON_SITE, COMPLETED, FAILED. feedback is the object sent by the field team, and is absent when none was sent.FAILED with "feedback": { "reason": "no_acknowledgement" }. Mission outcomes never change the status of the linked event, which stays the delivery status."environment": "production".
Reconciliation
operation.reconciled and operation.unmatched
operation.reconciled and operation.unmatched
One of your records was checked against the ledger.
operation.reconciled when it matched or differs, operation.unmatched when no operation fits it. See Reconciliation.reconciliation.resolved
reconciliation.resolved
Your organisation recorded a decision about an operation or a record. The note is never sent.
state is the state when the decision was recorded: differs, pending, missing_external or missing_operation. actor_kind is user or api_key.reconciliation.period_closed
reconciliation.period_closed
A day of a source was closed. Amounts are never sent: read them with
GET /v1/reconciliation/sources/{source_id}/closes/{day}.status is closed or difference; differences is how many currency and direction lines do not agree.Service levels (SLA)
Sent only when WEBHOOK is an alert channel of the SLA of the vertical. Counts, times and identifiers only, never the content of an event.sla.violated
sla.violated
A mission passed the response target of its priority (P1 for
critical, P2 for high, P3 for the rest), counted from the dispatch. Sent once per mission: while it is still open, or when it completes if it finished between two checks (checks run every minute).mission_state is open or completed; elapsed_min is the time from the dispatch when the alert was sent.sla.uptime_below_target
sla.uptime_below_target
The availability of the wede API this month is below the uptime target of the SLA of the vertical. The availability is the share of the minutes of the month in which the API was running. Sent at most once a month per vertical, after at least 24 hours measured.
Test
webhook.test is sent only by POST /v1/webhooks/:webhook_id/test. You cannot subscribe to it.
Verify the signature
Every delivery is signed with the secret you set when you created the webhook.X-Wede-Signature has the form t=<timestamp>,v1=<signature>, where signature is the hex HMAC-SHA256, keyed with your secret, of the string <timestamp>.<raw request body>.
To verify a delivery:
- Read the raw request body as bytes, before any JSON parsing.
- Split the header on
,and readtandv1. - Compute HMAC-SHA256 of
t + "." + raw bodywith your secret, as hex. - Compare it with
v1in constant time. - Reject the delivery if
tis too old. We recommend a tolerance of 5 minutes.
Responding and retries
- Answer with any
2xxstatus to confirm the delivery. Any other status, a network error or no answer within 10 seconds counts as a failed attempt. - A failed delivery is retried up to 3 attempts in total: the second attempt about 1 second after the first, the third about 5 seconds after the second.
X-Wede-Attempttells you which attempt you are receiving;X-Wede-Deliverystays the same. - Answer quickly and do slow work after responding, so deliveries do not time out.
- Deliveries can arrive more than once and out of order. Deduplicate on the delivery
idand usecreated_atand the resource’s own state (for exampleGET /v1/events/:event_id) when order matters.
Automatic disabling
Each failed attempt increases the webhook’sfailure_count, and any successful delivery resets it to 0. After 10 consecutive failed attempts, wede sets the webhook to active: false and stops sending to it. Check active and failure_count with GET /v1/webhooks. To resume, fix your endpoint and create the webhook again.