API documentation
The Webhooky API is deliberately tiny: one endpoint URL per notification channel, one POST request per notification. No API keys, no SDK, no OAuth dance – the secret is in the URL.
Your endpoint
Each endpoint you create in the app has a unique URL:
https://api.webhooky.app/YOUR_KEY
Treat the key like a password – anyone who has the URL can send you notifications. You can delete an endpoint (and create a new one) in the app at any time.
Send a notification
Send an HTTP POST to your endpoint. The simplest possible call:
curl -X POST "https://api.webhooky.app/YOUR_KEY"
This delivers a push notification using the title, message, sound and vibration you configured for the endpoint in the app.
Override title, message, sound & vibration
Include any of these fields in a JSON body to control the notification – per request:
curl -X POST "https://api.webhooky.app/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "New order 🎉",
"message": "Order #1042 · €49.99",
"sound": "cash_register",
"vibrate": true
}'
title– replaces the endpoint name as the notification title (max 100 characters).message– replaces the configured text (max 500 characters).sound– plays a different sound for this notification. Accepts any sound id from the app (e.g.cash_register,error_1,doorbell_1,level_up_1); unknown ids are ignored.vibrate–true/false, overrides the endpoint's vibration setting for this notification.- All fields are optional and independent; omitted fields fall back to the endpoint's configuration in the app.
- Longer values are truncated, whitespace is normalized. All other JSON fields are ignored for display but stored with the event if store payload is enabled.
Per-endpoint, the app additionally offers Silent (no sound or vibration, appears quietly) and Important (heads-up banner on Android) settings that apply to all notifications of that endpoint.
Available sound ids
All 40 sound ids accepted by the sound field (plus default for the device default):
| Category | Ids |
|---|---|
| Money / sales | cash_register, ka_ching (ka-ching), coin, coin_clatter, coin_collision, coin_drop, coin_received, coin_win, casino_bling |
| Success / gaming | level_up_1, level_up_2, level_up_3, level_complete, bonus_reached, fireworks, uplifting_bells, bottles_clink |
| Errors / alarms | error_1, error_2, error_3, buzzer, game_over, car_horn_1, car_horn_2 |
| Bells / doorbells | bell_ding, church_bell, doorbell_1, doorbell_2, doorbell_3, doorbell_4 |
| Neutral | notification_1 … notification_5, news_ting |
| Fun | cat_meow_1, cat_meow_2, dog_bark, rubber_duck |
You can preview every sound in the app's endpoint settings.
Examples in other languages
# Python
import requests
requests.post("https://api.webhooky.app/YOUR_KEY",
json={"title": "Hello", "message": "from Python"})
// JavaScript (Node 18+, browsers, Deno, Bun)
await fetch("https://api.webhooky.app/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Hello", message: "from JS" }),
});
# PowerShell
Invoke-RestMethod -Method Post -Uri "https://api.webhooky.app/YOUR_KEY" `
-ContentType "application/json" `
-Body '{"title": "Hello", "message": "from PowerShell"}'
Test page
Opening your endpoint URL in a browser (HTTP GET) shows a test page with input fields for title, message and a JSON payload, plus a send button. Handy for checking your setup without any tooling.
Responses
| Status | Meaning |
|---|---|
200 | Webhook accepted and delivered. JSON body: {"success": true, "delivered": 1, "devices": 1, "message": "…"} |
200 | Webhook accepted, but not delivered: free plan limit reached (100 notifications). JSON body has "reason": "free_limit_reached", plus the header X-Webhooky-Limit: free-limit-reached. Upgrade to Premium in the app. |
400 | No key in the URL. |
404 | Key not found – the endpoint was deleted or the URL is wrong. |
405 | Method not allowed – only GET and POST are supported. |
When the free limit is reached, the response is still 200 so that webhook senders don't retry, with this JSON body:
{ "success": false, "accepted": true, "delivered": 0, "reason": "free_limit_reached", "message": "…" }
Why 200 and not an error? Many webhook senders (e.g. Stripe, Shopify) treat non-2xx responses as failures, retry the delivery again and again and may eventually disable your webhook. Webhooky therefore always accepts the request and reports the limit in the body instead. Check success or the X-Webhooky-Limit header if you call the endpoint from your own code.
Delivery & limits
- Notifications are delivered via FCM/APNs to all devices signed in to your account, usually in under a second.
- The free plan includes 100 notifications in total and one endpoint; Premium removes both limits.
- Events are stored in your in-app history. The request payload is only stored if you enable store payload for the endpoint.
- There is no fixed rate limit, but bursts may be throttled by the push providers. One event = one notification (deduplicated per device).
Content types, CORS & payload size
JSON (application/json) is recommended. Form posts (application/x-www-form-urlencoded) and raw text bodies are accepted too – if a JSON object with title/message can be found, it is used.
- CORS is enabled (
Access-Control-Allow-Origin: *) – you can call your endpoint directly from browser JavaScript. - Keep payloads small. Only
title/message/sound/vibrateaffect the notification; the rest of the body is only kept if store payload is enabled. A few kilobytes are plenty.
Machine-readable spec
An OpenAPI 3.1 description of the API is available at webhooky.app/openapi.yaml – handy for API clients, code generators and AI coding tools.