GST Cranes developer resources
GST Cranes webhooks
Signed JSON notifications for account-owned marketplace events. Use this page to register endpoints, test deliveries, and verify every GST Cranes delivery before processing it.
Events
- webhook.test
- A signed-in member sends a test delivery to one of their active endpoints.
- saved_alert.match
- Best-effort companion delivery when a newly published marketplace listing matches a saved alert and the saved-alert fan-out reaches that alert.
Signing
Every delivery is signed with HMAC-SHA256 using the endpoint secret shown once during creation.
GST Cranes never sends unsigned webhook deliveries. Reject unsigned deliveries before JSON parsing.
- Secret format
whsec_<random endpoint secret shown once at creation>- Signature version
v1- Signature base string
timestamp + "." + raw_body
Sent header names are lowercase on the wire; HTTP header names remain case-insensitive.
gst-webhook-id/GST-Webhook-Idgst-webhook-event/GST-Webhook-Eventgst-webhook-timestamp/GST-Webhook-Timestampgst-webhook-signature/GST-Webhook-Signature: v1=<hex digest>
The signature input is GST-Webhook-Timestamp + "." + raw_body, where raw_body is the exact request
body before JSON parsing.
Verify the raw request body bytes before JSON parsing. Do not reserialize parsed JSON to verify a delivery; JSON key order and whitespace must not be reconstructed.
Verification rules
- Read the raw request body before JSON parsing.
- Reject
GST-Webhook-Timestampvalues outside 300 seconds. - Compute HMAC-SHA256 over
GST-Webhook-Timestamp + "." + raw_bodywith the endpoint secret. - Compare the expected
v1=digest againstGST-Webhook-Signaturewith a constant-time compare. - Store processed
GST-Webhook-Idvalues per endpoint and reject repeats before processing. - Reject duplicate
GST-Webhook-Idvalues per endpoint.
Node verification sketch
import crypto from 'node:crypto';
function verifyGstWebhook({ rawBody, timestamp, signature, secret }) {
const expected =
'v1=' + crypto.createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(signature);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
throw new Error('Invalid GST-Webhook-Signature');
}
}Official SDK verifier
The TypeScript SDK includes verifyGstWebhookSignature for receiver-side
verification. Install it with npm install @gstcranes/gstcranes or review the
package on npm.
import { verifyGstWebhookSignature } from '@gstcranes/gstcranes';
const ok = await verifyGstWebhookSignature({
rawBody,
timestamp: request.headers.get('GST-Webhook-Timestamp') ?? '',
signature: request.headers.get('GST-Webhook-Signature') ?? '',
secret: process.env.GST_WEBHOOK_SECRET ?? '',
});
if (!ok) throw new Error('Invalid GST-Webhook-Signature');