Skip to content

Webhooks

RE-ZIP can send webhook requests to notify your system about events such as inventory updates and order status changes. All webhook requests are signed using HTTP Message Signatures (RFC 9421) so you can verify that incoming requests genuinely originate from RE-ZIP.

Every webhook request includes Signature and Signature-Input headers. These are generated using ECDSA P-384 with SHA-384. To verify a webhook you need to:

  1. Fetch our public keys from the JWKS endpoint
  2. Match the key by kid (Key ID) from the signature
  3. Verify the signature against the request contents

Our public signing keys are published as a standard JWKS document at:

https://webhook.re-zip.com/.well-known/jwks.json

The response looks like this:

{
"keys": [
{
"kty": "EC",
"crv": "P-384",
"x": "...",
"y": "...",
"kid": "key-a1b2c3d4",
"key_ops": ["verify"]
}
]
}

Multiple keys may be present during key rotation periods. Always match the key using the kid referenced in the request’s Signature-Input header.

Signing keys are currently rotated monthly. After rotation, the previous key remains available in the JWKS endpoint for at least 14 days to allow verification of any in-flight requests. This rotation schedule is subject to change, so your implementation should not depend on any specific timing. Your implementation should:

  • Fetch keys from the JWKS endpoint rather than hardcoding them
  • Cache the JWKS response, but refresh it if you encounter an unknown kid
  • Match keys by kid, not by array position

The Signature-Input header describes which components of the request are covered by the signature, and the Signature header contains the actual signature value. Together they follow the HTTP Message Signatures standard.

POST /your-webhook-endpoint HTTP/1.1
Host: your-api.example.com
Content-Type: application/json
Signature-Input: sig1=("@method" "@target-uri" "content-type");keyid="key-a1b2c3d4";alg="ecdsa-p384-sha384";created=1700000000
Signature: sig1=:BASE64_ENCODED_SIGNATURE:
  1. Parse the Signature-Input header to extract the keyid and covered components
  2. Fetch the JWKS from https://webhook.re-zip.com/.well-known/jwks.json
  3. Find the key matching the keyid
  4. Reconstruct the signature base from the covered components as specified in RFC 9421 Section 2.5
  5. Verify the signature using the public key with ECDSA P-384 / SHA-384
import * as crypto from "node:crypto";
async function verifyWebhook(request) {
// 1. Fetch public keys
const jwksResponse = await fetch(
"https://webhook.re-zip.com/.well-known/jwks.json"
);
const { keys } = await jwksResponse.json();
// 2. Extract keyid from Signature-Input
const sigInput = request.headers["signature-input"];
const keyidMatch = sigInput.match(/keyid="([^"]+)"/);
const keyid = keyidMatch[1];
// 3. Find the matching key
const jwk = keys.find((k) => k.kid === keyid);
if (!jwk) throw new Error("Unknown key: " + keyid);
// 4. Import the public key
const publicKey = await crypto.subtle.importKey(
"jwk",
jwk,
{ name: "ECDSA", namedCurve: "P-384" },
false,
["verify"]
);
// 5. Reconstruct signature base and verify
// Use an HTTP Message Signatures library for your platform
// to handle the full verification per RFC 9421
}

We recommend using an existing HTTP Message Signatures library for your platform rather than implementing the signature base reconstruction yourself. Libraries are available for most languages:

Your endpoint should return a 2xx status code to acknowledge receipt. If we do not receive a successful response, the webhook will be retried.

Use the sandbox environment at https://webhook.sandbox.re-zip.com to test your webhook integration. The sandbox JWKS endpoint is available at:

https://webhook.sandbox.re-zip.com/.well-known/jwks.json