Skip to content

Webhook Signatures

Every event sent to PromptJang must be signed with HMAC-SHA256. This ensures payload integrity and authenticity.

Signing Events

Events are signed using the endpoint secret (returned when you create an endpoint):

bash
SIGNATURE = HMAC-SHA256(endpoint_secret, "${TIMESTAMP}.${PAYLOAD}")

The signed content is the timestamp and raw JSON body joined by a period (.).

Example

bash
PAYLOAD='{"event":"order.created","data":{"order_id":"ORD-001"}}'
TIMESTAMP=$(date +%s)
BODY="${TIMESTAMP}.${PAYLOAD}"
SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "whsec_abc123" | awk '{print $NF}')

Required Headers

HeaderDescription
X-PJ-SignatureHMAC-SHA256 hex digest of timestamp.payload
X-PJ-TimestampUnix timestamp (seconds) used in signature computation

Verification Flow

  1. PromptJang receives the event with X-PJ-Signature and X-PJ-Timestamp
  2. Reconstructs the signed content: timestamp.raw_body
  3. Computes HMAC-SHA256 using the stored endpoint secret
  4. Compares signatures using constant-time equality
  5. Rejects events with missing or invalid signatures (401)

Optional Headers

HeaderDescription
X-PJ-Event-TypeEvent type (e.g., order.created). Auto-detected from event_type in body if omitted.
X-PJ-Correlation-IDCustom correlation ID for tracing. Must be ≤128 chars, alphanumeric + -_.

Outbound Signatures

When PromptJang delivers to your endpoint, it also signs the payload. The same scheme is used:

X-PJ-Signature: <hmac-sha256-hex>
X-PJ-Timestamp: <unix-timestamp>

Verify inbound deliveries the same way — reconstruct the signature and compare.

Released under the MIT License.