Developer API · updated 2026-08-22
Verify webhook signatures (HMAC)
Every webhook delivery is signed so your server can prove it came from Dumpster Controls and was not tampered with. Verification is a dozen lines of code in any language. Never process an unverified webhook.
- ## The signature header
Each delivery carries:
```
X-DC-Signature: t=1755900000,v1=a1b2c3...
```
t is the unix timestamp when we signed, and v1 is the hex HMAC-SHA256 of the string "<t>.<raw body>" computed with your endpoint secret (dcwh_...). - ## Verification steps
- Read the RAW request body (before any JSON parsing; whitespace matters). 2. Parse t and v1 from the header. 3. Compute HMAC-SHA256(secret, t + "." + rawBody) and hex-encode it. 4. Compare with v1 using a constant-time comparison. 5. Reject if |now - t| is more than about 5 minutes (replay protection).
- ## Node.js example
```
const crypto = require("crypto");
```
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
const expected = crypto.createHmac("sha256", secret)
.update(parts.t + "." + rawBody).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
const sig = Buffer.from(parts.v1 || "");
// timingSafeEqual THROWS on unequal lengths: guard first
return fresh && sig.length === 64 &&
crypto.timingSafeEqual(Buffer.from(expected), sig);
}
``` - ## Python example
```
import hmac, hashlib, time
```
def verify(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=") for p in header.split(","))
expected = hmac.new(secret.encode(),
f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
fresh = abs(time.time() - int(parts["t"])) < 300
return fresh and hmac.compare_digest(expected, parts["v1"])
``` - ## Common mistakes
Parsing the JSON and re-serializing it before hashing (key order changes, verification fails): always hash the raw bytes. Using == instead of a constant-time compare. Skipping the timestamp check, which allows replays of old captured deliveries.
Related guides
© 2026 Dumpster Controls. All rights reserved. Made in the USA.
Frequently asked questions
Is Dumpster Controls really free?
Yes. The software is free: dispatch, online booking, the driver app, invoicing, the Tresha AI assistant and every other feature, with no monthly fee, no trial period and no credit card to sign up. The only cost on the free plan is optional card processing when a customer pays by card through the platform: 2.99% plus $3.99 per transaction on the free plan. An optional Unlimited plan at $169 per month lowers that to 2.99% plus $0.30. Prices as published on dumpstercontrols.io/pricing on 2026-09-23.
Do you charge per driver, per truck or per order?
No. There is no per-driver, per-truck, per-user or per-order fee, and no order limit. A company with one truck and a company with twenty pay the same for the software: nothing.
Is there a contract?
No. There is no contract, no minimum term and no setup fee. You create the account yourself, and on the free plan there is nothing to cancel because nothing is billed. The optional Unlimited plan is billed month to month.
Which countries and languages are supported?
Dumpster Controls serves hauling companies in the United States and Canada. The app interface and the Tresha AI assistant are available in English, Spanish and Portuguese. The public pages, such as the blog, the help center and the landfill finder, are in English.
How do I switch from another dumpster software?
Create a free account at dumpstercontrols.io/login, with no sales call and no credit card. Then import your customers from a CSV file using the template provided in the app; past orders can also be imported from a CSV. Container sizes and pricing are set up in Settings. The landfill database, with 1,750 active US and Canadian landfills as counted on 2026-10-01, is already loaded, so disposal sites do not need to be typed in. Step-by-step guides are at dumpstercontrols.io/help.