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
| Header | Description |
|---|---|
X-PJ-Signature | HMAC-SHA256 hex digest of timestamp.payload |
X-PJ-Timestamp | Unix timestamp (seconds) used in signature computation |
Verification Flow
- PromptJang receives the event with
X-PJ-SignatureandX-PJ-Timestamp - Reconstructs the signed content:
timestamp.raw_body - Computes HMAC-SHA256 using the stored endpoint secret
- Compares signatures using constant-time equality
- Rejects events with missing or invalid signatures (
401)
Optional Headers
| Header | Description |
|---|---|
X-PJ-Event-Type | Event type (e.g., order.created). Auto-detected from event_type in body if omitted. |
X-PJ-Correlation-ID | Custom 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.