Skip to main content
This example uses the core of wede (events, delivery, offline sync, webhooks) together with the optional teams, dispatch and missions module, which delivery operations add on top. This example follows one parcel from order to doorstep. Your order system sends a parcel_pickup event, a dispatcher scores the available drivers and dispatches the best one, the driver app reports each step, and proof of delivery is captured on the phone even where there is no signal. wede stores each delivery confirmation exactly once. All names, coordinates and identifiers below are illustrative. Each driver (or van crew) is a team in wede.

Who does what

wede uses two credentials. The API key is your server’s integration credential. People (dispatchers, drivers, administrators) sign in and use a session token whose permissions come from their role. An API key calling a team, dispatch, mission or catalog write endpoint receives 403 forbidden. The snippets call the REST API through a small helper, so they run in Node.js 20 or later, browsers and React Native without extra packages:
lib/wede.ts
Customers with SDK access can use the wede SDK instead. It adds retries, the offline queue and automatic synchronisation. See SDKs.

1. Create your event types (one time)

Event types belong to your tenant and live in your catalog, organised by category. wede pre-loads the delivery catalog (collected, in_transit, out_for_delivery, delivered, delivery_failed, returned under Deliveries, none of them sending a team). This example adds a pickup type that sends a driver and a cash type; this needs a signed-in administrator, so run it as a setup script.
setup-catalog.ts
Codes use lowercase letters, digits and underscores. Only types with requires_teams: true enter dispatch; required_equipment lists codes from your equipment list (GET /v1/catalog/equipment) and counts in the driver score without ever blocking a dispatch. Each driver team then covers the Deliveries category (or just parcel_pickup) under Teams in the dashboard.

2. Send the order from your server

Your order system sends the event with the API key. Put the zone code in metadata.zone_id and derive the idempotency_key from your order id, so a retry can never create a second pickup.
server/orders.ts
The call returns 202 with event_id, status: "pending" and environment. Sending the same idempotency_key again returns 409 duplicate_event.
Use a wede_test_ key while you build. Sandbox events follow the same channel decision as production, never reach a real provider and never count toward usage.

3. Score the drivers and dispatch

The dispatch console signs in with a user that has dispatch:assign. Scoring with the event_id returns the free drivers that cover the event’s type (or its category), ranked by score from 0 to 1 (higher is better). The first team is marked recommended; missing_equipment lists what the type calls for and the driver lacks, which lowers the score but never excludes the driver.
console/dispatch.ts
Each entry of scored has team_id, team_name, status, vertical, distance_km, eta_min, equipment_match, member_availability, score, recommended, tier, missing_equipment, channel and position; drivers that are not candidates come in excluded with a reason (no_members, no_coverage). The dispatch returns 201 with the dispatch record (id, event_id, team_id, dispatched_by, dispatched_at, notes), marks the team on_mission, creates the mission in CREATED status and sends the team.dispatched webhook. There is one mission per team and event. A dispatch accepts only an existing production event and a team of your tenant (404 event_not_found or 404 team_not_found otherwise). When the mission reaches COMPLETED or FAILED, the team becomes available again for the next score. The event keeps its own status, which is its delivery status. If a driver does not acknowledge within your acknowledgement timeout (reinforcement_timeout_min), wede sets the mission to FAILED and dispatches the best free driver not yet called for that order; with no driver free, the event returns to the dispatch queue (GET /v1/events?undispatched=true).

4. The driver app

Drivers sign in on their phone and use the session token, never an API key. A field_operator lists the missions of their own team with GET /v1/missions/my, can update only those missions, and can update only their own location.

Mission status

Mission statuses: CREATED, SENT, ACK, ON_ROUTE, ON_SITE, COMPLETED, FAILED.
app/mission.ts
A status update is a direct API call: keeping and replaying the updates made without connectivity is up to your app. Missions only move forward and COMPLETED and FAILED are final, so a replayed update that is no longer valid returns 409 invalid_transition: treat it as already applied. feedback is stored with the mission and included in the webhook. Use FAILED when the delivery cannot be made (for example, nobody at the address). wede then releases the driver. The event keeps its own status, which is its delivery status; follow the outcome through the mission.

Proof of delivery without connectivity

Basements, rural roads and dense buildings lose signal. Capture the proof of delivery at the doorstep, with the capture time and an integrity checksum, and send the queue to POST /v1/sync/batch when the phone reconnects.
app/proof-of-delivery.ts
  • duplicate means wede already had that confirmation, online or from an earlier batch, and stored it once. Resending a batch after a dropped connection is always safe.
  • capture adds the capture time and the SHA-256 integrity checksum. A confirmation edited after capture is rejected with integrity_check_failed and recorded as a security incident; the rest of the batch is still accepted.
  • Accepted events produce event.created webhooks with origin: "sync" and offline_generated_at, so your backend knows when the delivery really happened. One sync.completed webhook follows with the summary.
  • A captured event can carry metadata.zone_id and metadata.location, as an online event does. They are not part of the checksum.

5. Webhooks on your backend

Subscribe once with the API key. The secret must be at least 16 characters.
server/webhooks-setup.ts
event.created (from sync)
Verify every delivery before you trust it. X-Wede-Signature is t=<unix seconds>,v1=<hex>, where hex is HMAC-SHA256 with your webhook secret over <t>.<raw body>.
server/webhooks.ts
Answer with any 2xx within 10 seconds. wede makes up to 3 attempts per delivery and disables a webhook after 10 consecutive failed deliveries.

Data protection alignment

wede is designed to support a GDPR-aligned delivery operation. Your own lawful basis, notices and contracts complete it. wede is hosted in the European Union by default. Where local regulation requires in-country data residency, a dedicated regional instance is available by agreement.

Next steps

Offline sync

Batches, duplicates and checksums.

Score engine

How teams are ranked.

Missions

Mission lifecycle and endpoints.

Webhooks

Subscribe and verify deliveries.