What sync does
When a device or system works without connectivity, it captures each operation locally at the moment it happens. When connectivity returns, it sends them to wede in one batch. wede checks every event on its own, stores each operation once, and then delivers the accepted ones exactly as if they had been sent online.How it works
1
Capture
Capture each operation when it happens, with its
idempotency_key, the capture time (offline_generated_at) and an integrity checksum. The wede SDKs do this for you. Store the captured object unchanged.2
Send the batch
When connectivity returns, send up to 500 captured events to
POST /v1/sync/batch.3
Read the results
wede returns one result per event:
accepted, duplicate or rejected, with a reason for rejections.4
Delivery
Accepted events follow the same delivery path as online events and trigger the same webhooks.
Capture and send
With the wede SDKs, capture and sync are automatic: operations are kept on the device and sent when the connection returns. See SDKs. Without an SDK, capture each operation yourself and send the batch:Batch contract
POST /v1/sync/batch with { "events": [ ... ] }, from 1 to 500 events. A malformed batch returns 400 invalid_payload and nothing is stored.
Integrity checksum
integrity_hash is the SHA-256, in lowercase hexadecimal, of this string:
JSON.stringify(payload) is the compact JSON of the payload with its keys in the order you send them. Any change to the payload, the key or the capture time after capture makes the checksum fail.
Response
200 whenever the batch is well formed, even if some events are rejected. Read results to know what happened to each event.
Duplicates
An operation that already reached wede, online throughPOST /v1/events or in an earlier batch, is returned as duplicate with the event_id of the existing event. It is never stored twice. duplicates is your proof against double counting.
Rejections
A rejection affects only that event. The other events of the batch are still accepted.
Refused events are kept
wede keeps every event it refuses with its full content as it arrived, the device that sent it, its place in the device’s numbering and the reason, whether it came in a batch or by SMS, satellite or LoRa. Each refusal is a record that cannot be changed, so the trail of an operation never depends on the device keeping it. The result of a refused event says so withrecorded: true.
Your organisation sees them in the dashboard, on the Refused page, and reads them with GET /v1/sync/rejected. wede never sees their content. At the end of the retention period the content and the device are removed; the key, the reason, the device number and a checksum of the content stay.
A device that kept refused events with an SDK version before 2.17.0 can hand them to wede only to be kept, never processed again, with POST /v1/sync/rejected. The same event sent twice is kept once.
Integrity incidents
A checksum that does not match is treated as a possible security incident. wede rejects that event only, records an incident that cannot be altered, and alerts your tenant administrators by email. With a sandbox key the event is refused and the incident is recorded the same way, marked as sandbox, but nobody is alerted: you are testing. To rehearse it end to end, use the Proof kit.After sync
Each accepted event:- is stored with
offline_generated_atand, when sent,connectivity_state_at_generation; - sends an
event.createdwebhook withorigin: "sync"; - follows the same delivery path as an online event, with the same
event.delivered,event.failedandevent.status_changedwebhooks; - becomes
completedas soon as it is delivered, and its stored payload is cleared (for a type that sends a team, when the event is closed or its missions end). It stayspendingonly while it is queued for store-and-forward.
sync.completed webhook with the summary.
Events sent in a batch can carry metadata.zone_id and metadata.location, as online events do. They are not part of the checksum.
Sync status
GET /v1/sync/status summarises the events of your tenant that were captured offline:
environment=sandbox.
Best practices
- Create the
idempotency_keywhen the operation happens, not when you send it. - Store captured events unchanged. Any change breaks the checksum.
- Send batches as soon as connectivity returns, up to 500 events each.
- Always read
results. Resend only events rejected withpersistence_error, or fixed afterunknown_event_typeorunknown_vertical. - A captured event can also be sent online with
POST /v1/events. If the connection drops before you get the answer, keep it in the queue: the batch will return it asduplicateif it already arrived.
