Webhooks
Receive webhooks for various events happening in Pylon.
This page covers webhooks that Pylon sends to you.
Setup
Go to Settings > Integrations & dev > Webhooks and click Create Webhook.
Enter a Name and the Target URL, and pick the HTTP method (
POSTby default;GET,PUT,PATCH, andDELETEare also available).Optionally, add Custom headers, for example an
Authorizationheader with a Bearer token. Turn on Secret for a header to encrypt its value and hide it after saving.Click Create and copy the webhook secret. Pylon shows it only once. You need it to verify deliveries.
The target must be a public http or https URL. Private and internal network addresses are blocked. If your endpoint sits behind a firewall, allowlist Pylon's IP addresses for your region.
Payload
In the Send webhook action, write the request body in JSON payload. Type { to insert variables such as {{ issue.id }} or {{ issue.title }}. The variables you can use depend on the trigger's object. See Template variables for the full list, including tags, the latest message, and its author.

Follow these rules when you write the payload:
The payload must be valid JSON before variables are filled in.
Put every variable inside a JSON string. Pylon escapes each value for JSON but doesn't add quotes, so
"id": "{{issue.id}}"works and"id": {{issue.id}}does not.Every value arrives as a string, including numbers, dates, and
true/false. Convert them on your side if needed.Lists such as
{{ issue.tags }}arrive as one comma-separated string, and missing values arrive as"".
You can also use variables in the webhook's Target URL, for example https://example.com/hooks/{{ issue.account.id }}. Variables in the URL are not URL-encoded, so use URL-safe values such as IDs.
Delivery and retries
Timeout: each attempt waits up to 20 seconds for a response.
Success: any status below
400counts as delivered. A successful delivery adds a "sent webhook" entry to the activity of the object that fired the trigger.Retries: Pylon makes up to 3 attempts in total. If an attempt gets a
4xxor5xxstatus, times out, or can't connect, Pylon retries after about 4 seconds, then again after about 8 seconds. Retries include theX-Pylon-Retry-Numberheader.At-least-once: a delivery can arrive more than once, for example when your endpoint processes a request but responds too slowly. Make your handler idempotent.
No ordering guarantee: deliveries can arrive in a different order from the events that caused them.
No event ID header: to de-duplicate, include an identifier such as
{{issue.id}}together with the field that changed in your payload.
Pylon's own headers (Content-Type, the signature and timestamp headers, and X-Pylon-Retry-Number) replace any custom header with the same name. Every request is sent with Content-Type: application/json.
Test and monitor
Click Test in the create or edit dialog to send a test request with the body
{"data":{"type":"ping"}}. Tests sent while creating a webhook are unsigned, because the secret doesn't exist yet. Tests sent from Edit on a saved webhook are signed.The Logs tab on the Webhooks page lists every attempt with its status, method, payload, response, duration, and request ID. Retries appear as separate entries. Payloads and responses over about 65 KB are truncated in the log.
Verifying webhooks
When you create a webhook, Pylon shows its secret once. Store it securely: Pylon uses it to sign every delivery from a trigger or macro, and every test sent from a saved webhook, so your endpoint can confirm the request came from Pylon and has not been tampered with or replayed.
The secret can't be viewed again or rotated. To replace it, create a new webhook, point your triggers at it, and delete the old one.
Each delivery includes these headers:
X-Pylon-Timestamp
The time the request was sent, in Unix seconds.
X-Pylon-Signature-V2
Hex-encoded HMAC-SHA256 of <timestamp>.<body>, keyed with your webhook secret.
X-Pylon-Signature
Legacy. Hex-encoded HMAC-SHA256 of the body only.
X-Pylon-Retry-Number
Present on retries only: 1 on the first retry, 2 on the second.
To verify a delivery:
Read
X-Pylon-Timestampand reject the request if it is more than 5 minutes from your server's current time.Build the signed string by joining the timestamp, a period (
.), and the raw request body exactly as received, before any JSON parsing.Compute the HMAC-SHA256 of that string using your webhook secret as the key, and hex-encode it. Use the secret string as-is; do not hex-decode it.
Compare your result to
X-Pylon-Signature-V2using a constant-time comparison.
Retries are signed again with a fresh timestamp, so a retried delivery passes the timestamp check.
Last updated
Was this helpful?

