Skip to content

Webhook Signatures

PromptJang signs every outbound webhook delivery using Standard Webhooks v1 with HMAC-SHA256. API keys authenticate requests into PromptJang; webhook signing secrets authenticate deliveries from PromptJang to your receiver.

Delivery headers

HeaderDescription
webhook-idStable event ID; use it for receiver idempotency
webhook-timestampUnix timestamp for this delivery attempt
webhook-signatureOne or more space-separated Base64 v1 signatures
X-PromptJang-Event-TypeOptional PromptJang event-type metadata

The signed bytes are:

text
webhook-id.webhook-timestamp.raw-body

The event ID stays stable across retries. Each attempt receives a fresh timestamp and signature. Manual replay creates a new event ID.

Verify with the official library

Read the request body as raw bytes before JSON parsing.

ts
import { Webhook } from "standardwebhooks"

const webhook = new Webhook(process.env.PROMPTJANG_SIGNING_SECRET!)

export async function receive(request: Request) {
  const rawBody = await request.text()

  webhook.verify(rawBody, {
    "webhook-id": request.headers.get("webhook-id")!,
    "webhook-timestamp": request.headers.get("webhook-timestamp")!,
    "webhook-signature": request.headers.get("webhook-signature")!,
  })

  const eventId = request.headers.get("webhook-id")!
  if (await alreadyProcessed(eventId)) return new Response(null, { status: 200 })

  await processEvent(eventId, JSON.parse(rawBody))
  return new Response(null, { status: 200 })
}

The verifier performs constant-time comparison and rejects timestamps outside its five-minute tolerance. Do not verify a parsed or reformatted JSON value.

Secret rotation

Rotating a webhook target returns the new whsec_ value once. While rotation is active, webhook-signature contains signatures from both the current and previous secrets. Update the receiver, confirm delivery with the new secret, then finish rotation from the target screen or API.

PromptJang does not send legacy X-PromptJang-Signature, X-PromptJang-Timestamp, or X-PromptJang-Event-ID headers.

Released under the MIT License.