FAQ
What is the difference between the API Key and the Endpoint Secret?
These serve two completely different purposes:
API Key (pj_live_...) | Endpoint Secret | |
|---|---|---|
| Who uses it | You → PromptJang | PromptJang → Your target server |
| Purpose | Authenticate your API calls to PromptJang | Verify that incoming webhooks are genuinely from PromptJang |
| Sent as | Authorization: Bearer pj_live_... | Never sent directly — used to generate X-PromptJang-Signature |
| Where to use | When you call any PromptJang API endpoint | On your target server to verify webhook signatures |
In short: Use the API key to send events. Use the endpoint secret on your receiving server to verify them.
API Key
Every request to the PromptJang API requires an API key. Pass it in the Authorization header:
curl -X POST https://api.promptjang.net/api/v1/e/{endpoint_id} \
-H "Authorization: Bearer pj_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"event": "order.created", "data": {"order_id": 123}}'API keys are created in the dashboard. The full key is shown once at creation time — copy it immediately. After that, only the prefix (first 12 characters) is visible.
Endpoint Secret
When PromptJang delivers a webhook to your endpoint, it signs the payload with the endpoint's secret using HMAC-SHA256. Your receiving server should verify this signature to confirm the webhook is authentic:
import hmac, hashlib
def verify_signature(payload_body, signature_header, secret):
expected = hmac.new(
secret.encode(),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)The signature is sent in the X-PromptJang-Signature header on every outbound delivery.
Can I retrieve a full API key after creation?
No. API keys are stored as one-way hashes. The full key is only available at the moment of creation. This is the same approach used by Stripe, GitHub, and AWS.
If you lose an API key, revoke it in the dashboard and create a new one.
What happens if delivery fails?
PromptJang retries failed deliveries with exponential backoff. The retry schedule is:
| Attempt | Delay |
|---|---|
| 1st retry | 60 seconds |
| 2nd retry | 120 seconds |
| 3rd retry | 240 seconds |
| 4th retry | 480 seconds |
| 5th retry | 960 seconds |
After 5 failed attempts, the event is marked as EXPIRED and no further retries occur. You can replay expired events from the dashboard.
Is there a free plan?
No. PromptJang is pay-first with two plans:
- Starter ($29/mo): 100K events, 7-day retention, 256KB payload
- Pro ($69/mo): 1M events, 30-day retention, 2MB payload
Events are never dropped — if you exceed your plan allocation, overage applies at per-100K rates.
How do I know my events were delivered?
Every event includes a full delivery log. Check the Events page in the dashboard or use the API:
curl https://api.promptjang.net/api/v1/events/{event_id} \
-H "Authorization: Bearer pj_live_your_key_here"The response includes the event status (DELIVERED, FAILED, QUEUED, RETRYING, EXPIRED) and all delivery attempts with HTTP status codes and response bodies.
What status codes do target endpoints need to return?
PromptJang considers any 2xx response as a successful delivery. All other status codes (including 3xx redirects) are treated as failures and will trigger a retry.
Your endpoint should respond quickly — timeouts also count as failures.