Delivery Operations
Dispatch, analytics, export, notifications, and webhook management for delivery operations.
Dispatch
Auto-assign drivers and get suggestions for optimal driver matches.
Suggest drivers for an order
Suggest the best nearby available drivers for an order.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/dispatch/suggest \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"order_id":"..."}'
{ "status": "ok" }
const suggestions = await ss.delivery.dispatch.suggest({
order_id: 'ord_01',
limit: 5,
})
- Open Delivery and go to Orders
- Click on an unassigned order, then click Suggest Drivers
- Review the ranked driver suggestions
order_id requiredradius_kmlimitAuto-assign a driver to an order
Automatically assign the best available driver to an order.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/dispatch/auto-assign \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"order_id":"..."}'
{ "status": "ok" }
const result = await ss.delivery.dispatch.autoAssign({
order_ids: ['ord_01', 'ord_02', 'ord_03'],
})
- Open Delivery and go to Orders
- Select multiple unassigned orders, then click Auto-Assign
order_id requiredDispatch Rules
Configure priority-ordered auto-dispatch rules with zone, time window, and radius conditions.
Create a dispatch rule
Create a priority-ordered dispatch rule with zone/time conditions and driver selection strategy.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","priority":1,"conditions":{},"action":{}}'
{ "status": "ok" }
const rule = await ss.delivery.dispatchRules.create({
name: 'Night Shift',
priority: 1,
conditions: { time_window: { start: '22:00', end: '06:00' } },
action: { strategy: 'round_robin', fallback: 'queue' },
})
- Open Delivery and go to Dispatch Rules
- Click Add Rule
- Configure the rule name, priority, conditions (zones, time windows, radius), and dispatch strategy, then click Save
name requiredpriority requiredconditions requiredaction requiredenabledmetadataList dispatch rules
List all dispatch rules for the project, ordered by priority.
curl https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const { rules } = await ss.delivery.dispatchRules.list()
- Open Delivery and go to Dispatch Rules
- Browse the list of dispatch rules ordered by priority
Get a dispatch rule
Get a single dispatch rule by ID.
curl https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules/{rule_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const rule = await ss.delivery.dispatchRules.get('ddr_01')
- Open Delivery and go to Dispatch Rules
- Click on a rule to view its details
rule_id requiredUpdate a dispatch rule
Update a dispatch rule's conditions, action, priority, or toggle enabled state.
curl -X PATCH https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules/{rule_id} \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{}'
{ "status": "ok" }
const updated = await ss.delivery.dispatchRules.update('ddr_01', {
enabled: false,
})
- Open Delivery and go to Dispatch Rules
- Click on a rule, edit the fields, then click Save
rule_id requirednamepriorityconditionsactionenabledmetadataDelete a dispatch rule
Delete a dispatch rule.
curl -X DELETE https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules/{rule_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
await ss.delivery.dispatchRules.delete('ddr_01')
- Open Delivery and go to Dispatch Rules
- Click the delete icon next to a rule, then confirm
rule_id requiredEvaluate dispatch rules (dry-run)
Test which rule would fire for given coordinates and time without performing any assignment.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/dispatch-rules/evaluate \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"lat":1,"lng":1}'
{ "status": "ok" }
const result = await ss.delivery.dispatchRules.evaluate({
lat: 40.7128,
lng: -74.0060,
})
- Open Delivery and go to Dispatch Rules
- Use the Evaluate tool to test which rule matches for a given location and time
lat requiredlng requiredtime^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Auto-dispatch an order using rules
Evaluate dispatch rules for an order and assign the best available driver based on the matched rule's strategy. Falls back to nearest-driver if no rules match.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/auto-dispatch \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"order_id":"..."}'
{ "status": "ok" }
const result = await ss.delivery.dispatchRules.autoDispatch({
order_id: 'ord_01',
})
- Open Delivery and go to Orders
- Click on an unassigned order, then click Auto-Dispatch to trigger rules-based driver assignment
order_id requiredTracking Links
Generate short-lived public tracking tokens for customer and driver tracking pages.
Create a tracking link
Generate short-lived public tracking tokens for a delivery order. Returns embeddable customer and driver tracking page URLs.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/tracking-links \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"order_id":"..."}'
{ "status": "ok" }
const link = await ss.delivery.trackingLinks.create({
order_id: 'ord_01',
ttl_minutes: 1440,
})
- Open Delivery and go to Orders
- Click on an order, then click Create Tracking Link
- Copy the customer or driver URL to share
order_id requiredttl_minutesResolve a tracking token
Public endpoint — resolves a tracking token to its associated channel and role. No authentication required.
curl https://api.saasignal.saastemly.com/modules/delivery/tracking-links/{token} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const info = await ss.delivery.trackingLinks.resolve('trk_c_abc123')
- Tracking links are resolved automatically when a customer or driver opens the tracking URL
- No dashboard action needed — this is a public endpoint
token requiredRevoke a tracking link
Revoke a tracking link, invalidating both customer and driver tokens.
curl -X DELETE https://api.saasignal.saastemly.com/modules/delivery/tracking-links/{link_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
await ss.delivery.trackingLinks.revoke('dtl_01')
- Open Delivery and go to Orders
- Click on an order, find the active tracking link, then click Revoke
link_id requiredTracking Pages
Public customer and driver tracking routes, plus SSE updates and proof submission flows.
Render Customer Tracking Page
Render the public customer-facing delivery tracking page for a tracking token. Returns HTML that embeds live order updates, proof history, and customer rating submission. This route is intentionally public and authenticated by the signed tracking token in the URL.
curl https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/customer/{token} \
-H "Authorization: Bearer <session_token>"
{ "status": "ok" }
const html = await ss.delivery.trackingPages.customerPage('trk_c_abc123')
- Open Delivery, generate a tracking link for an order, then copy the customer URL
- Paste the URL into a new tab to verify the public customer experience end-to-end
- Or use API Console to fetch the raw HTML route directly from the browser
token requiredLoad Customer Tracking Feed
Load the initial JSON payload for a customer tracking page, including order status, delivery proofs, and any submitted rating. This route is public and authenticated by the tracking token in the URL.
curl https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/customer/{token}/feed \
-H "Authorization: Bearer <session_token>"
{ "status": "ok" }
const feed = await ss.delivery.trackingPages.customerFeed('trk_c_abc123')
- Use API Console to call this public JSON feed with a customer tracking token
- Inspect the order snapshot, proof records, and rating data that power the public tracking page
token requiredSubmit Customer Rating
Submit or update a customer rating from the public tracking page after an order is delivered. This route is public and authenticated by the tracking token in the URL.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/customer/{token}/rating \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{"score":1}'
{ "status": "ok" }
await ss.delivery.trackingPages.rate('trk_c_abc123', { score: 5, comment: 'Right on time' })
- Generate a tracking link for a delivered order in Delivery
- Open the customer tracking page and submit a rating through the public UI, or send the JSON payload from API Console
token requiredscore requiredcommentRender Driver Tracking Page
Render the public driver-facing delivery tracking page for a tracking token. Returns HTML used by couriers to send location pings and upload proof. This route is intentionally public and authenticated by the signed tracking token in the URL.
curl https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/driver/{token} \
-H "Authorization: Bearer <session_token>"
{ "status": "ok" }
const html = await ss.delivery.trackingPages.driverPage('trk_d_abc123')
- Open Delivery, generate a tracking link, then copy the driver URL
- Open the driver URL in a new tab to validate the public courier workflow, including ping and proof actions
token requiredSend Driver Tracking Ping
Publish a live driver location update from the public driver tracking page. This route is public and authenticated by the tracking token in the URL.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/driver/{token}/ping \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{"lat":1,"lng":1}'
{ "status": "ok" }
await ss.delivery.trackingPages.ping('trk_d_abc123', { lat: 51.5072, lng: -0.1276 })
- Open the public driver tracking page in a browser to send live location updates
- Or use API Console with the driver token to test the public JSON endpoint directly
token requiredlat requiredlng requiredUpload Driver Photo Proof
Upload delivery proof directly from the public driver tracking page using multipart form data. Expected fields: file (required image file), optional comment, lat, and lng. This route is public and authenticated by the tracking token in the URL.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/driver/{token}/proof/photo \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{"file":"..."}'
{ "status": "ok" }
await ss.delivery.trackingPages.uploadPhotoProof('trk_d_abc123', file, { fileName: 'dropoff.jpg', comment: 'Left at reception' })
- Open the public driver tracking page and upload a proof photo from the courier UI
- Or use API Console in form mode to send multipart proof uploads from Chrome
token requiredfile requiredcommentlatlngSubmit Driver Comment Proof
Submit text-only proof from the public driver tracking page. This route is public and authenticated by the tracking token in the URL.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/driver/{token}/proof/comment \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{"text":"..."}'
{ "status": "ok" }
await ss.delivery.trackingPages.commentProof('trk_d_abc123', { text: 'Customer requested handoff at side gate' })
- Open the public driver tracking page to add text proof from the courier flow
- Or send the JSON request from API Console with the driver tracking token
token requiredtext requiredlatlngSubscribe to Public Tracking Updates
Open a public Server-Sent Events stream for a delivery tracking token. Use this from customer and driver tracking pages to receive live order, proof, and location updates without any bearer token. If reconnecting, pass last_event_id to resume from the previous event cursor.
curl https://api.saasignal.saastemly.com/modules/delivery/tracking-pages/subscribe/{token} \
-H "Authorization: Bearer <session_token>"
{ "status": "ok" }
const es = new EventSource(ss.delivery.trackingPages.subscribeUrl('trk_c_abc123'))
- Open the customer or driver tracking page to watch live SSE updates automatically
- Or inspect the event stream directly from API Console by calling the subscribe endpoint with a tracking token
token requiredlast_event_idSettings
Configure delivery module behavior per project.
Get delivery settings
Get or create default delivery settings.
curl https://api.saasignal.saastemly.com/modules/delivery/settings \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const settings = await ss.delivery.settings.get()
- Open Delivery and go to Settings
- View the current delivery configuration
Update delivery settings
Update delivery settings.
curl -X PATCH https://api.saasignal.saastemly.com/modules/delivery/settings \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{}'
{ "status": "ok" }
const updated = await ss.delivery.settings.update({
auto_dispatch: true,
default_timezone: 'America/New_York',
})
- Open Delivery and go to Settings
- Edit the configuration fields, then click Save
auto_assignauto_assign_radius_kmmax_concurrent_ordersrequire_proofproof_typeseta_fence_threshold_minNotifications
Configure which delivery events trigger notifications.
List notification configs
List all notification configs for the project.
curl https://api.saasignal.saastemly.com/modules/delivery/notifications \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const templates = await ss.delivery.notifications.list()
- Open Delivery and go to Notifications
- Browse the list of notification templates
Upsert notification config
Insert or update a notification config by project + event.
curl -X PUT https://api.saasignal.saastemly.com/modules/delivery/notifications \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"event":"metric.updated","enabled":true}'
{ "status": "ok" }
await ss.delivery.notifications.upsert({
event: 'order.delivered',
channel: 'sms',
template: 'Your order {{order_id}} has been delivered!',
enabled: true,
})
- Open Delivery and go to Notifications
- Click on a template to edit it, or click Add Template
- Configure the event trigger, channel, and message template, then click Save
event requiredenabled requiredchannelWebhooks
Manage webhooks for delivery-specific event topics.
List delivery webhooks
List webhooks filtered to delivery.* topics.
curl https://api.saasignal.saastemly.com/modules/delivery/webhooks \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const webhooks = await ss.delivery.webhooks.list()
- Open Delivery and go to Webhooks
- Browse the list of registered webhooks
Create a delivery webhook
Register a webhook for delivery event topics.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/webhooks \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","url":"https://app.acme.com/webhooks/saasignal","topics":["kv:write"]}'
{ "status": "ok" }
const webhook = await ss.delivery.webhooks.create({
url: 'https://example.com/hooks/delivery',
events: ['order.created', 'order.delivered'],
})
- Open Delivery and go to Webhooks
- Click Add Webhook
- Enter the endpoint URL, select the events to subscribe to, then click Save
name requiredurl requiredtopics requiredsecretETA Fences
Create and manage ETA fences for delivery destinations. Receive breach webhooks when a tracked entity's driving ETA drops below the configured threshold.
Create Delivery ETA Fence
Define a destination point and time threshold for delivery ETA monitoring. When a tracked entity's driving ETA drops below the threshold, a logistics.eta_fence.breach webhook fires.
curl -X POST https://api.saasignal.saastemly.com/modules/delivery/eta-fences \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"example","dest_lat":1,"dest_lng":1,"threshold_min":1}'
{ "status": "ok" }
await ss.delivery.etaFences.create({
name: 'Depot Arrival',
dest_lat: 40.7128, dest_lng: -74.0060,
threshold_min: 30,
avg_speed_kmh: 50,
})
- Open Delivery and go to the ETA Fences tab
- Click Create ETA Fence and fill in the destination, threshold, and speed
- Click Create to save the fence
name requireddest_lat requireddest_lng requiredthreshold_min requiredlogistics.eta_fence.breach webhook fires when driving ETA drops below this value.entity_typesavg_speed_kmh40.40heuristic_multiplier1.5.1.5metadataList Delivery ETA Fences
List all ETA fences for the project.
curl https://api.saasignal.saastemly.com/modules/delivery/eta-fences \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const result = await ss.delivery.etaFences.list()
- Open Delivery and go to the ETA Fences tab
- All ETA fences are displayed with their destination coordinates and threshold
enabledtrue or falsetrue, falselimit25.25cursorGet Delivery ETA Fence
Retrieve a single ETA fence.
curl https://api.saasignal.saastemly.com/modules/delivery/eta-fences/{fence_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const fence = await ss.delivery.etaFences.get('etaf_abc')
- Open Delivery and go to the ETA Fences tab
- Click on a fence to view its destination, threshold, and metadata
fence_id requiredDelete Delivery ETA Fence
Permanently removes an ETA fence.
curl -X DELETE https://api.saasignal.saastemly.com/modules/delivery/eta-fences/{fence_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
await ss.delivery.etaFences.delete('etaf_abc')
- Open Delivery and go to the ETA Fences tab
- Click the delete icon on the fence you want to remove
fence_id requiredAnalytics
Delivery performance analytics and driver statistics.
Get delivery analytics summary
Aggregate delivery metrics.
curl https://api.saasignal.saastemly.com/modules/delivery/analytics/summary \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const summary = await ss.delivery.analytics.summary()
- Open Delivery and go to Analytics
- View the summary dashboard with order counts, delivery times, and trends
from^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$to^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Get driver analytics
Per-driver delivery metrics.
curl https://api.saasignal.saastemly.com/modules/delivery/analytics/drivers \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const driverStats = await ss.delivery.analytics.drivers()
- Open Delivery and go to Analytics
- Switch to the Drivers tab to view per-driver performance metrics
from^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$to^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$driver_idExport
Export delivery data in JSON or CSV format.
Export delivery orders
Export orders as JSON or CSV.
curl https://api.saasignal.saastemly.com/modules/delivery/export/orders \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
const csv = await ss.delivery.export.orders()
- Open Delivery and go to Orders
- Click the Export button to download orders as CSV
from^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$to^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$statusformatjson, csvdefault json