Documentation
WebhookPush turns any webhook into a push notification on your phone. Point a service at your private URL — the moment it fires, you get a push and the message lands in your inbox.
Quickstart
1. Create a webhook (in the iOS app: Webhooks → New webhook, or on the web dashboard). Your secret is shown once — copy it right away.
2. Send a POST to your ingest URL:
curl -X POST https://d1yykmxdakarpv.cloudfront.net/ingest/<webhookId> \
-H "x-webhook-secret: <your-secret>" \
-H "Content-Type: application/json" \
-d '{"title":"Deploy done","body":"build #42 ✓"}'3. The push arrives on every registered device and the message is kept in your inbox (retention depends on your plan).
Authentication — three modes
- Header secret (default): send
x-webhook-secretwith every call. - URL secret: enable "URL secret (?secret=)" on the webhook, then append
?secret=<your-secret>to the URL — for services that can't send custom headers (TradingView, some monitors). - No secret: switch "Require secret" off — the unguessable URL is the only credential. Rotate by deleting/recreating the webhook.
Lost the secret? Rotate secret reveals a fresh one (the old one stops working immediately).
TradingView
TradingView webhooks can't send custom headers, so use the URL secret:
- 1. On your webhook, enable "URL secret (?secret=)".
- 2. Copy the full URL —
https://d1yykmxdakarpv.cloudfront.net/ingest/<id>?secret=<secret>(shown when the secret is revealed). - 3. In TradingView: Alert → Notifications → Webhook URL → paste it.
- 4. Set the alert Message to JSON for a clean notification:
{"title":"{{ticker}}","body":"Crossed {{close}}"}Plain text also works — it's delivered as-is as the notification body.
Message format
title— notification title (falls back to the webhook name).body— notification body (falls back to the raw text, then the full payload).- Non-JSON bodies are kept as text — nothing is dropped.
- Report failures with
?status=fail(or"status":"fail"in the payload) plus anerrorfield — the notification shows the error and, with monitoring on, fires an alert.
Templates
Per-webhook title/body templates shape the notification from any payload with {{ payload.field }} placeholders. Mix literal text with as many placeholders as you like — e.g. a title of FX {{ payload.repo }} {{ payload.status }}. Leave the body template empty to deliver the full payload.
Fields & nesting
Reach any depth with dots, and index arrays with brackets. A missing field (or missing parent) renders to nothing rather than erroring.
{{ payload.title }}
{{ payload.data.subtitle }} # nested, any depth
{{ payload.b.c.d }}
{{ payload.items[0] }} # array indexFilters
Pipe a value through one or more filters with |. Unknown filters are ignored (the value passes through unchanged).
{{ payload.title | default: "Alert" }} # fallback when empty/missing (alias: or)
{{ payload.side | upper }} # UPPERCASE (also: lower, title)
{{ payload.price | round: 2 }} # 3.14159 -> 3.14
{{ payload.ts | date }} # ISO 8601
{{ payload.ts | date: "short" }} # 2026-07-11 (also: "time")
{{ payload.sym | default: "?" | upper }} # chain them left-to-rightExtra variables
Beyond payload, templates can reference the webhook itself and the current time.
{{ webhook.name }} # this webhook's name
{{ now }} # delivery time
{{ now | date: "short" }} # 2026-07-11Conditionals
Show a section only when a field is present (non-empty), or compare it with == / !=. An optional {{else}} branch handles the other case.
{{#if payload.error}}❌ {{ payload.error }}{{else}}✅ ok{{/if}}
{{#if payload.status == "down"}}ALERT{{/if}}
{{#if payload.env != "prod"}}(test){{/if}}Safe by design
Templates are never executed as code — only these placeholders and filters are substituted. Malformed syntax (an unclosed {{ or {{#if}}) is left as plain text, and output is capped at 2,000 characters. If a template renders to nothing, the notification falls back to the payload's own title/body (then the webhook name), so you never get a blank push.
Monitoring (dead-man's-switch)
Enable Monitor on a webhook with an interval + grace period: if the webhook isn't called within that window, you get an alert — perfect for cron jobs and backups that should check in regularly. A successful ping clears the alert state.
Plans & limits
- Free — 50 calls/day, 7-day history.
- Starter — 100 calls/day, 14-day history.
- Pro — 1,000 calls/day, 90-day history, 7-day free trial.
- Enterprise — custom limits, 1-year history.
Over-quota calls return 402 with an upgrade link; short bursts are smoothed by a per-webhook burst guard (429). See pricing for details.
Questions? Contact us.