Crom Services · public sample crumb

API webhook sample

Hosted proof for CromServices/api-webhook-sample. Bid paste can link a URL that responds — not only the GitHub clone.

Live demo host

https://crom-api-webhook-demo.fly.dev
Health: https://crom-api-webhook-demo.fly.dev/health

Sample crumb only. This is a disposable public demo, not a forever-host claim for client workloads. Rotate the demo secret if it is ever reused beyond this sample.

Published demo secret

Public sample value only — not a client secret, not production. Set on the host as WEBHOOK_SECRET. Fail-closed HMAC is unchanged: bad or missing X-Signature-256 returns 401.

crom-demo-webhook-secret-v1

GET /health → 200

curl -sS https://crom-api-webhook-demo.fly.dev/health
# {"ok":true}

POST /webhook with valid HMAC → 200

Header is X-Signature-256 over the raw JSON body (hex, or sha256= prefix). Fixed body used below: {"event":"ping"}.

Ready curl with a precomputed signature for that body and the published secret:

curl -sS -X POST https://crom-api-webhook-demo.fly.dev/webhook \
  -H 'content-type: application/json' \
  -H 'x-signature-256: sha256=2f95da3b8a47b656b7e8a980a32916dce258b449cf738632c5ffac988b6f3e9c' \
  --data '{"event":"ping"}'
# {"received":true}

Compute the same hex yourself:

printf '%s' '{"event":"ping"}' \
  | openssl dgst -sha256 -hmac 'crom-demo-webhook-secret-v1' -hex \
  | awk '{print $NF}'

POST /webhook fail-closed → 401

Missing signature:

curl -sS -o /dev/stderr -w '%{http_code}\n' \
  -X POST https://crom-api-webhook-demo.fly.dev/webhook \
  -H 'content-type: application/json' \
  --data '{"event":"ping"}'
# {"error":"invalid signature"}
# 401

Bad signature:

curl -sS -o /dev/stderr -w '%{http_code}\n' \
  -X POST https://crom-api-webhook-demo.fly.dev/webhook \
  -H 'content-type: application/json' \
  -H 'x-signature-256: sha256=0000000000000000000000000000000000000000000000000000000000000000' \
  --data '{"event":"ping"}'
# {"error":"invalid signature"}
# 401

What this is not