1. Register the endpoint
The signing secret is returned once. Store it in your server's secret manager before leaving the response.
Terminal
export GRAMCLAW_BASE_URL="https://gramclaw.com"
export GRAMCLAW_API_KEY="gc_live_replace_with_your_key"
curl -s "$GRAMCLAW_BASE_URL/api/v1/webhooks" \
-H "Authorization: Bearer $GRAMCLAW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/gramclaw",
"events": ["message.received", "campaign.replied", "pipeline.moved"]
}'2. Verify the raw request body
Compute the digest from the exact bytes received, before JSON parsing. Compare signatures in constant time.
Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyGramClaw(rawBody, signature, secret) {
const expected = "sha256=" + createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const actualBuffer = Buffer.from(signature || "");
const expectedBuffer = Buffer.from(expected);
return actualBuffer.length === expectedBuffer.length &&
timingSafeEqual(actualBuffer, expectedBuffer);
}- Return a 2xx response quickly and process heavier work asynchronously.
- Supported events are message.received, message.edited, message.deleted, pipeline.moved, and campaign.replied.
- Twenty consecutive delivery failures automatically disable an endpoint.