Developers
Webhooks
Demurly posts a signed JSON event to your server the moment a record changes, so you don't have to poll. Here's how to receive them safely.
On this page
Set up an endpoint
An admin adds endpoints under Settings > Webhooks > Add endpoint: an https URL that's reachable from the internet, and the events to send (or all of them). Up to 10 endpoints per company. Adding or editing one needs two-step sign-in (2FA). Carriers need Pro ($199 a month) to set this up; upgrade on Settings > Plan & Billing. Fuel buyers get it free.
Demurly shows the endpoint's signing secret (whsec_...) once. Store it next to your API key, as a secret on your server. You can make a new one at any time without missing a delivery: see roll the signing secret. Endpoints can also be added and changed through the API.
What a delivery looks like
Each event is a POST to your URL with a JSON body and these headers. Answer with any 2xx within 10 seconds; do slow work after you answer (put the event on a queue).
| Header | Example | What it is |
|---|---|---|
| X-Demurly-Signature | t=1768500600,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd | The signature: t is the Unix time it was signed, v1 the hex HMAC-SHA256 of "<t>.<raw body>" keyed with the endpoint's signing secret. Signed afresh on every attempt. After the secret is rolled there's a second v1 (made with the old secret) until the old one expires: accept the delivery if any v1 matches. |
| X-Demurly-Event | record.approved | The event type (the same as the body's type), to route before parsing. |
| X-Demurly-Delivery | 0b8f4f5e-2c7a-4d1e-9b3a-6f2e8d1c4a57 | This delivery's id: one per event per endpoint, the same on its retries. The delivery log shows it. |
| Content-Type | application/json | The body is JSON (UTF-8). |
| User-Agent | Demurly-Webhooks/1.0 | Lets you tell Demurly's calls apart in your logs. |
The body is { id, type, created_at, record_id, sequence, occurred_at, data: { record, event } }: data.record is the record as the API returns it (the record object), and data.event says what happened, who did it (actor_type) and through what (source: web, api, guest_link...). The full shape is the webhook event object, and each event's example is below.
Verify the signature
Check every delivery before you trust it. The signature proves it came from Demurly and wasn't changed:
- Read the raw request body, as bytes, before any JSON parsing. Re-serialized JSON won't match.
- Split
X-Demurly-Signatureon commas intotand thev1values. There can be more than onev1(while a rolled secret's overlap lasts); keep them all. - Compute the HMAC-SHA256 of
<t>.<raw body>with your endpoint's secret (the wholewhsec_...string) as the key, as lowercase hex. - Compare it with each
v1in constant time (not==). The delivery is genuine if any of them matches. - Reject it if
tis more than 5 minutes (300 seconds) from your clock, either way. That stops an old delivery being replayed. Keep your server's clock synced (NTP).
Then drop the event if you've already handled its id. These verifiers are tested against real signed deliveries; copy the one for your language.
// Verify a Demurly webhook in Node.js (18+), no dependencies.
//
// X-Demurly-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
// keyed with your endpoint's signing secret (whsec_...). Check the raw body
// exactly as it arrived: parsing and re-serializing the JSON changes the bytes.
// After you roll the secret there are two v1 values until the old secret
// expires (t=...,v1=<new>,v1=<old>): accept the delivery if ANY v1 matches.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyDemurlySignature(rawBody, header, secret, { toleranceSeconds = 300, now = Date.now() } = {}) {
if (!header || !secret) return false;
let timestamp = null;
const signatures = [];
for (const part of String(header).split(",")) {
const i = part.indexOf("=");
if (i < 0) continue;
const key = part.slice(0, i).trim();
const value = part.slice(i + 1).trim();
if (key === "t") timestamp = value;
else if (key === "v1") signatures.push(value);
}
if (!timestamp || !/^\d+$/.test(timestamp) || signatures.length === 0) return false;
// Reject old (or far-future) timestamps so a captured request can't be replayed
if (Math.abs(now / 1000 - Number(timestamp)) > toleranceSeconds) return false;
const body = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(String(rawBody), "utf8");
const expected = createHmac("sha256", secret).update(`${timestamp}.`).update(body).digest();
return signatures.some((sig) => {
if (!/^[0-9a-f]{64}$/i.test(sig)) return false;
return timingSafeEqual(Buffer.from(sig, "hex"), expected);
});
}
// Usage with Node's http server (or express.raw({ type: "application/json" })):
//
// import http from "node:http";
// http.createServer((req, res) => {
// const chunks = [];
// req.on("data", (c) => chunks.push(c));
// req.on("end", () => {
// const raw = Buffer.concat(chunks);
// if (!verifyDemurlySignature(raw, req.headers["x-demurly-signature"], process.env.DEMURLY_WEBHOOK_SECRET)) {
// res.writeHead(400).end();
// return;
// }
// const event = JSON.parse(raw.toString("utf8"));
// // Answer 2xx fast (within 10 seconds); drop an event.id you've already handled
// res.writeHead(200).end();
// });
// }).listen(3000);
Roll the signing secret
Make a new secret with Roll signing secret in the endpoint's menu (Settings > Webhooks) or POST /api/v1/webhook_endpoints/{id}/roll_secret, and choose how long the old one keeps working: immediately, 1 hour, 24 hours, 7 days (the default is 24 hours). Until then every delivery carries two signatures, one per secret, newest first:
X-Demurly-Signature: t=1768500600,v1=<new>,v1=<old>- Roll the secret and copy the new one (it's shown once).
- Deploy it to your receiver. A receiver that accepts any matching
v1(the samples above do) verifies with either secret, so nothing fails in between. - When the overlap ends, deliveries carry only the new signature. Roll "immediately" if the old secret leaked.
Rolling again during an overlap stops the older secret at once; only the one just replaced keeps working. The endpoint shows until when the old secret is still sent (previous_secret_expires_at in the API).
Delivery rules
- At least once. An event can arrive more than once (a retry after your answer was lost, or a resend). Its
idis the same every time: keep the ids you've handled and drop repeats. - Unordered. Each delivery retries on its own schedule, so an older event can arrive after a newer one for the same record.
sequenceis the event's place in its record's history and only goes up: keep the highest you've applied perrecord_idand ignore lower ones, or fetch the record withGET /api/v1/records/{id}for its current state. - A snapshot.
data.recordis the record when the body was first built (the first attempt; retries send the same bytes), not necessarily at the moment of the event. - Retries. Anything but a
2xxwithin 10 seconds (an error status, a timeout, a refused connection) is retried 7 times, after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 1 day: 8 attempts over about 45 hours. Redirects aren't followed. After the last attempt the delivery is marked failed; you can still resend it from the delivery log. - Additive. New event types and new fields can be added. Ignore types and fields you don't know, and don't subscribe to "all events" if you can't.
When an endpoint is turned off
Demurly turns an endpoint off only when both are true: it has accepted nothing for 3 days, and at least 5 events in a row failed every retry. Each event is retried for about 45 hours, so an outage of hours never turns it off, and any delivered event resets the count.
Your company's admins get an email and an in-app notice. Nothing is lost: deliveries waiting for it pause, and events while it's off are kept (shown as Paused in the delivery log; the same happens when an admin turns it off). Fix your receiver, turn the endpoint back on under Settings > Webhooks, and choose Send the missed events (or skip them). They arrive with their original id and sequence, so your duplicate and ordering checks still work.
Testing your receiver
Send test on an endpoint posts a webhook.test event, signed like any other, once (no retries). The delivery log shows every event sent with the body, and each attempt: the request headers (with the signature), how long it took, and your endpoint's status, headers and first 2 KB of its answer. Resend sends one again.
{
"id": "7d3e1c2b-9a8f-4e6d-b5c4-a3b2c1d0e9f8",
"type": "webhook.test",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": null,
"sequence": null,
"occurred_at": "2026-01-16T15:20:00.412Z",
"livemode": true,
"data": {
"message": "Test event from Demurly settings"
}
}The URL must be public https. To receive events on your own machine while you build, use a tunnel (such as ngrok or Cloudflare Tunnel) and add it as a test endpoint (Settings > Webhooks, mode Test). A test endpoint gets only test-mode events, the ones your test keys and the simulation endpoints cause in your sandbox, each with "livemode": false; a live endpoint never gets them, and real events never reach a test endpoint. Test endpoints are free for every company. See testing your integration.
Polling as a safety net
updated_since every few minutes to catch anything missed. Keep your system in sync shows both together.Manage endpoints with the API
A TMS or ERP that serves many companies can set up its own endpoint instead of asking an admin to paste a URL. Give an API key the webhooks:write scope (webhooks:read to only look) and use POST /api/v1/webhook_endpoints: it returns the signing secret once, like Settings does. The same rules apply: 10 endpoints at most, a public https URL, events your side gets, and Pro for carriers.
PATCH /api/v1/webhook_endpoints/{id}changes the URL or events, and turns it off or on (active);POST /api/v1/webhook_endpoints/{id}/missed_eventssends or skips what was kept while it was off.POST /api/v1/webhook_endpoints/{id}/roll_secretrolls the secret with an overlap;POST /api/v1/webhook_endpoints/{id}/testsends a test event.GET /api/v1/webhook_endpoints/{id}/deliveriesreads the delivery log with every attempt (requests and responses);POST /api/v1/webhook_endpoints/{id}/deliveries/{delivery_id}/resendsends one again.
Every change is in your company's audit log as the key's creator, naming the key. A live key manages live endpoints and a test key test endpoints.
Events
Carriers get events about their records; fuel buyers about records sent to them. The record lifecycle shows which move sends which event.
| Event | Sent when | Carriers | Fuel buyers |
|---|---|---|---|
| record.created | A record was started: a driver started the clock, or a wait was reported through the API, EDI or an import (carriers only) | Yes | No |
| record.stopped | The driver stopped the clock; the record is a draft until submitted (carriers only) | Yes | No |
| record.submitted | A record stopped and is waiting for the carrier's review (carriers only) | Yes | No |
| record.rejected_internal | The carrier's review rejected its driver's record; the buyer never sees it (carriers only) | Yes | No |
| record.reopened | The carrier took a review rejection back; the record is under review again (carriers only) | Yes | No |
| record.sent | The carrier sent a record to the buyer for approval | Yes | Yes |
| record.approved | The buyer approved a record | Yes | Yes |
| record.disputed | The buyer disputed a record, with a reason | Yes | Yes |
| record.escalated | The carrier escalated a dispute | Yes | Yes |
| record.closed | A disputed record was closed without payment | Yes | Yes |
| record.offer_accepted | The carrier accepted the buyer's counter-offer from a dispute; the charge is back with the buyer at that amount, to approve | Yes | Yes |
| record.withdrawn | A charge you were sent was sent to another buyer or taken back for review by the carrier; data.record is the tombstone the API shows you (buyers only) | No | Yes |
| record.cancelled | The carrier cancelled a record (buyers hear only of records sent to them, and get this, not record.withdrawn) | Yes | Yes |
| record.updated | A record's details or billed times changed (a field edit, or times adjusted, which changes the amount); data.event.type says which | Yes | Yes |
| record.comment_added | Someone on the carrier or the buyer side commented on a record | Yes | Yes |
| record.payment_pending | A payment is on its way: a bank payment started in Demurly, or the buyer marked it paid outside Demurly (method and reference in data.event.data) | Yes | Yes |
| record.payment_failed | A pending payment didn't arrive: a bank payment failed, or the carrier said an outside payment was never received; the record is approved and unpaid again | Yes | Yes |
| record.paid | A record was paid by card or confirmed paid outside Demurly | Yes | Yes |
| record.payment_reversed | A card payment was fully refunded or lost to a chargeback; the record is approved and unpaid again | Yes | Yes |
record.created
A record was started: a driver started the clock, or a wait was reported through the API, EDI or an import (carriers only). data.event.type: record_created.
{
"id": "e1a2b3c4-0000-4000-8000-000000000047",
"type": "record.created",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 47,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "recording",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": null,
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": null,
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": null,
"free_time_minutes": 120,
"billable_minutes": null,
"hourly_rate": 100,
"amount": null,
"amount_approved": null,
"stop_reason": null,
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": null,
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": null,
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_created",
"sequence": 47,
"actor_type": "driver",
"source": "android_app",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.stopped
The driver stopped the clock; the record is a draft until submitted (carriers only). data.event.type: gps_tracking_stopped.
{
"id": "e1a2b3c4-0000-4000-8000-000000000048",
"type": "record.stopped",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 48,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "draft",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": null,
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "gps_tracking_stopped",
"sequence": 48,
"actor_type": "driver",
"source": "android_app",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.submitted
A record stopped and is waiting for the carrier's review (carriers only). data.event.type: record_submitted.
{
"id": "e1a2b3c4-0000-4000-8000-000000000049",
"type": "record.submitted",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 49,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "pending_review",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": null,
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_submitted",
"sequence": 49,
"actor_type": "driver",
"source": "android_app",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.rejected_internal
The carrier's review rejected its driver's record; the buyer never sees it (carriers only). data.event.type: employer_rejected.
{
"id": "e1a2b3c4-0000-4000-8000-000000000050",
"type": "record.rejected_internal",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 50,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "rejected_by_employer",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": null,
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "employer_rejected",
"sequence": 50,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"reason": "Driver was on a break, not waiting at the rack"
}
}
}
}record.reopened
The carrier took a review rejection back; the record is under review again (carriers only). data.event.type: record_reopened.
{
"id": "e1a2b3c4-0000-4000-8000-000000000051",
"type": "record.reopened",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 51,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "pending_review",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": null,
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_reopened",
"sequence": 51,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.sent
The carrier sent a record to the buyer for approval. data.event.type: record_sent_to_customer.
{
"id": "e1a2b3c4-0000-4000-8000-000000000052",
"type": "record.sent",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 52,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "sent_to_customer",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_sent_to_customer",
"sequence": 52,
"actor_type": "carrier_admin",
"source": "api",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.approved
The buyer approved a record. data.event.type: record_approved or record_partially_approved.
{
"id": "e1a2b3c4-0000-4000-8000-000000000053",
"type": "record.approved",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 53,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "customer_approved",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": 125,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": "2026-01-16T15:20:00.000Z",
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_approved",
"sequence": 53,
"actor_type": "customer_admin",
"source": "api",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"approvedAmount": 125
}
}
}
}record.disputed
The buyer disputed a record, with a reason. data.event.type: record_disputed or record_rejected.
{
"id": "e1a2b3c4-0000-4000-8000-000000000054",
"type": "record.disputed",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 54,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "disputed",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_disputed",
"sequence": 54,
"actor_type": "customer_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"reason": "Gate log shows a 90-minute wait",
"disputeType": "time",
"proposedAmount": 75
}
}
}
}record.escalated
The carrier escalated a dispute. data.event.type: record_escalated.
{
"id": "e1a2b3c4-0000-4000-8000-000000000055",
"type": "record.escalated",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 55,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "escalated",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_escalated",
"sequence": 55,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.closed
A disputed record was closed without payment. data.event.type: record_closed.
{
"id": "e1a2b3c4-0000-4000-8000-000000000056",
"type": "record.closed",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 56,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "closed",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_closed",
"sequence": 56,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.offer_accepted
The carrier accepted the buyer's counter-offer from a dispute; the charge is back with the buyer at that amount, to approve. data.event.type: dispute_offer_accepted.
{
"id": "e1a2b3c4-0000-4000-8000-000000000057",
"type": "record.offer_accepted",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 57,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "sent_to_customer",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "dispute_offer_accepted",
"sequence": 57,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.withdrawn
A charge you were sent was sent to another buyer or taken back for review by the carrier; data.record is the tombstone the API shows you (buyers only). data.event.type: record_withdrawn.
{
"id": "e1a2b3c4-0000-4000-8000-000000000058",
"type": "record.withdrawn",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 58,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "withdrawn",
"withdrawn_reason": "reassigned",
"withdrawn_at": "2026-01-16T15:20:00.000Z",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_withdrawn",
"sequence": 58,
"actor_type": "system",
"source": "system",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"withdrawn_reason": "reassigned"
}
}
}
}record.cancelled
The carrier cancelled a record (buyers hear only of records sent to them, and get this, not record.withdrawn). data.event.type: record_cancelled.
{
"id": "e1a2b3c4-0000-4000-8000-000000000059",
"type": "record.cancelled",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 59,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "cancelled",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "record_cancelled",
"sequence": 59,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.updated
A record's details or billed times changed (a field edit, or times adjusted, which changes the amount); data.event.type says which. data.event.type: field_updated, field_corrected or time_adjusted.
{
"id": "e1a2b3c4-0000-4000-8000-000000000060",
"type": "record.updated",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 60,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "sent_to_customer",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "field_updated",
"sequence": 60,
"actor_type": "carrier_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"field": "bol_number",
"value": "BOL-99812"
}
}
}
}record.comment_added
Someone on the carrier or the buyer side commented on a record. data.event.type: comment_added.
{
"id": "e1a2b3c4-0000-4000-8000-000000000061",
"type": "record.comment_added",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 61,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "sent_to_customer",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": null,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": null,
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "comment_added",
"sequence": 61,
"actor_type": "customer_admin",
"source": "api",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"comment": "Matched to invoice 4471 in our ERP"
}
}
}
}record.payment_pending
A payment is on its way: a bank payment started in Demurly, or the buyer marked it paid outside Demurly (method and reference in data.event.data). data.event.type: payment_processing or external_payment_marked.
{
"id": "e1a2b3c4-0000-4000-8000-000000000062",
"type": "record.payment_pending",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 62,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "payment_pending",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": 125,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": "2026-01-16T15:20:00.000Z",
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "payment_processing",
"sequence": 62,
"actor_type": "customer_admin",
"source": "web",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"payment_method": "us_bank_account"
}
}
}
}record.payment_failed
A pending payment didn't arrive: a bank payment failed, or the carrier said an outside payment was never received; the record is approved and unpaid again. data.event.type: payment_failed or external_payment_rejected.
{
"id": "e1a2b3c4-0000-4000-8000-000000000063",
"type": "record.payment_failed",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 63,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "customer_approved",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": 125,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": "2026-01-16T15:20:00.000Z",
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "payment_failed",
"sequence": 63,
"actor_type": "system",
"source": "webhook",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {
"method": "us_bank_account",
"failureCode": "insufficient_funds",
"failureMessage": "The bank account had insufficient funds."
}
}
}
}record.paid
A record was paid by card or confirmed paid outside Demurly. data.event.type: payment_completed, external_payment_confirmed or external_payment_recorded.
{
"id": "e1a2b3c4-0000-4000-8000-000000000064",
"type": "record.paid",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 64,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "paid_stripe",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": 125,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": "2026-01-16T15:20:00.000Z",
"paid_at": "2026-01-20T16:00:00.000Z",
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "payment_completed",
"sequence": 64,
"actor_type": "system",
"source": "webhook",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}record.payment_reversed
A card payment was fully refunded or lost to a chargeback; the record is approved and unpaid again. data.event.type: payment_reversed.
{
"id": "e1a2b3c4-0000-4000-8000-000000000065",
"type": "record.payment_reversed",
"created_at": "2026-01-16T15:20:00.412Z",
"record_id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"sequence": 65,
"occurred_at": "2026-01-16T15:20:00.000Z",
"livemode": true,
"data": {
"record": {
"id": "3f6c1d2e-8a4b-4c1e-9f0a-1b2c3d4e5f60",
"record_number": "DMR-00001042",
"status": "customer_approved",
"carrier": {
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "Acme Trucking"
},
"customer": {
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "Gulf Fuel Supply"
},
"terminal": {
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "Houston Terminal",
"time_zone": "America/Chicago"
},
"load_number": "L-55821",
"bol_number": "BOL-99812",
"container_number": null,
"start_time": "2026-01-15T14:30:00.000Z",
"end_time": "2026-01-15T17:45:00.000Z",
"time_zone": "America/Chicago",
"time_zone_source": "terminal",
"start_time_local": "2026-01-15T08:30:00.000-06:00",
"end_time_local": "2026-01-15T11:45:00.000-06:00",
"local_start_date": "2026-01-15",
"adjusted_start_time": null,
"adjusted_end_time": null,
"time_adjustment_reason": null,
"total_minutes": 195,
"free_time_minutes": 120,
"billable_minutes": 75,
"hourly_rate": 100,
"amount": 125,
"amount_approved": 125,
"stop_reason": "manual",
"started_offline": false,
"start_received_at": null,
"start_clock_drift_seconds": null,
"gps_evidence": {
"status": "complete",
"source": "phone",
"point_count": 42,
"issues": []
},
"source": "phone",
"source_label": "Recorded by the driver's phone.",
"vehicle": null,
"evidence_hash": null,
"sent_to_customer_at": "2026-01-15T18:10:00.000Z",
"approved_at": "2026-01-16T15:20:00.000Z",
"paid_at": null,
"created_at": "2026-01-15T14:30:02.000Z",
"updated_at": "2026-01-16T15:20:00.000Z"
},
"event": {
"type": "payment_reversed",
"sequence": 65,
"actor_type": "system",
"source": "webhook",
"occurred_at": "2026-01-16T15:20:00.000Z",
"data": {}
}
}
}