Quick setup
- Open Settings, then Webhooks.
- Create a webhook with an HTTPS endpoint URL.
- Copy the signing secret and store it outside source control.
- Send a test webhook to verify the receiver.
- Verify
tickward-signaturein your receiver before trusting the payload. - Run the scheduler tick every minute.
Events
Webhook payloads use a stable event envelope:event_version is a date-based payload contract version. environment comes
from TICKWARD_ENVIRONMENT when configured, otherwise it falls back to
production, development, or test.
Supported event types:
project.createdproject.updatedproject.deletedtimer.createdtimer.updatedtimer.archivedtimer.restoredtimer.deletedtimer.endedshare.createdshare.deleted
API management
Webhook endpoints can be managed from Settings or through the public API:PATCH /webhooks/{webhook_id} to edit the subscribed event_types or to
disable and enable an endpoint:
DELETE /webhooks/{webhook_id} removes the endpoint and its delivery history.
Use disable when you only want to pause deliveries.
Test delivery
UseSend in Settings to send a one-off webhook.test event to the
endpoint immediately. Test deliveries are rate limited and do not retry
automatically. They use the same signing headers and payload envelope as normal
webhook deliveries.
The test payload identifies the tested endpoint:
data.object.object: "timer", project events use "project", and share events
use "share".
Sample events
TheSend menu can also send a sample of any event type the endpoint is
subscribed to, for example timer.ended. Sample events use the same envelope
and signing as real deliveries, with placeholder data such as
"id": "timer_sample" and "timer_label": "Sample timer". Use them to map
fields in Make, Zapier, or n8n without waiting for a real timer to end.
Make.com setup
Create aWebhooks > Custom webhook trigger in Make, copy its webhook URL, and
use that URL as the tickward endpoint.
Choose one of two setup modes.
Quick setup
Use this when you are testing, mapping fields, or building a low-risk workflow. This mode does not verify the HMAC signature.| Setting | Value |
|---|---|
| Webhook name | Use a short name such as tickward-events. |
| API Key authentication | Leave disabled for now. Make expects x-make-apikey, and tickward sends HMAC signing headers instead. |
| IP restrictions | Leave empty unless your tickward deployment has fixed outbound IPs. |
| Data structure | Leave empty at first, then use Send in tickward so Make can detect the payload fields. |
| Get request headers | No, unless you want to inspect delivery headers. |
| Get request HTTP method | No, unless you want it for debugging. tickward sends POST. |
| JSON pass-through | No. Make will parse the JSON body into fields you can map in later steps. |
Send in tickward. Make should detect
fields such as type, environment, event_version, and data.object.object.
For the test event, data.object.object is webhook_endpoint. Timer deliveries
use timer fields such as data.object.timer_label.
Verified setup
Use this for production workflows, workflows that change external systems, or anything that sends messages, bills users, updates records, or deletes data. Webhook settings:| Setting | Value |
|---|---|
| Get request headers | Yes. This exposes tickward-signature, tickward-event-id, tickward-delivery-id, and tickward-event-type. |
| JSON pass-through | Yes. Make keeps the original JSON body as text, which is required for signature verification. |
| Step | Module | Example name |
|---|---|---|
| 1 | Webhooks > Custom webhook | Webhook |
| 2 | Tools > Set multiple variables | Signature |
| 3 | Make Functions > Hash functions | HMAC |
| 4 | Connection filter after the hash step | Valid |
| 5 | JSON > Parse JSON | Parse |
| 6 | Your workflow action | Handle |
tickward-signature header has this shape:
t as the timestamp. Use v1 as the signature you compare with the hash
result. The value signed by tickward is the timestamp, a dot, and the exact raw
JSON body:
JSON pass-through: Yes first, then parse JSON only after
the signature filter passes.
Example validated Make flow
For Make’s__IMTHEADERS__ array, the header lookup formula usually looks like
this:
value field
for rows where name equals tickward-signature, then take the first match. Do
not map __IMTHEADERS__[].name directly for the hash step. The formula needs the
whole headers array as its first argument.
If Make inserts the array token with [], keep the array token but remove the
field access after it. In other words, use the __IMTHEADERS__ array, not
__IMTHEADERS__[].name.
Add Tools > Set multiple variables and name it Signature. Set the variable
lifetime to One cycle, then add these variables:
signature_header:
signature_timestamp:
signature_v1:
signed_payload:
Make Functions > Hash functions and name it HMAC.
| Field | Value |
|---|---|
Operation | SHA-256 |
Data | map signed_payload from Signature |
HMAC key | the endpoint signing secret shown once in tickward |
Key encoding | UTF-8 |
Output encoding | Hex |
HMAC key with a placeholder first.
Add a filter on the connection after HMAC and name it Valid.
Filter condition:
JSON > Parse JSON and parse the raw body from the
webhook trigger. Continue the rest of the scenario only from the valid path.
n8n setup
Add aWebhook trigger node, copy its production URL, and use it as the
tickward endpoint URL. n8n shows a separate test URL that only works while the
workflow editor is listening; register the production URL in tickward and
activate the workflow.
For field mapping, send a sample event from tickward (Send, then pick an
event type) while the n8n workflow is listening.
HMAC verification setup
To verify the HMAC signature you need the raw request body, so configure theWebhook node
first:
| Setting | Value |
|---|---|
| HTTP Method | POST |
| Raw Body | Yes (under node options). The body arrives as binary data instead of parsed JSON. |
| Response | Immediately, code 200 |
Code node directly after the webhook:
TICKWARD_WEBHOOK_SECRET environment variable
on your n8n instance (or use n8n credentials) instead of pasting it into the
node. Nodes after the Code node receive the parsed, verified event JSON.
Self-hosted n8n must be reachable over HTTPS. For local experiments, a
self-hosted tickward can allow http://localhost targets with
TICKWARD_WEBHOOK_ALLOW_PRIVATE_NETWORKS=true.
Zapier setup
Use theWebhooks by Zapier trigger. Zapier’s Catch Hook is the simplest
option for low-risk workflows because it parses the JSON body for field
mapping. For workflows that change external systems, use Catch Raw Hook so
the Zap receives the unparsed body and headers needed for HMAC verification.
Simple setup
Create aWebhooks by Zapier > Catch Hook trigger, copy the webhook URL into
tickward, then use Send so Zapier can detect the payload fields. This is
easy to map in later Zap steps, but the request is not verified.
HMAC verification setup
Create aWebhooks by Zapier > Catch Raw Hook trigger, copy the webhook URL
into tickward, then send a test event. Zapier documents that
Catch Raw Hook
includes the unparsed request body and headers.
Add Code by Zapier > Run JavaScript after the trigger. Add these input fields
from the raw hook sample:
| Input field | Value |
|---|---|
raw_body | the unparsed request body from the raw hook |
tickward_signature | the tickward-signature request header |
signing_secret | the endpoint signing secret shown once in tickward |
tickward-signature
against the raw body and forwards only valid requests to the Zapier hook URL.
The examples/webhook-receivers/cloudflare-worker example can be adapted into
that relay.
Signing
Each endpoint has a signing secret shown once when the endpoint is created. tickward signs every delivery with:v1
signature. Reject old timestamps in your receiver.
Security checklist:
- Use HTTPS endpoints in production.
- Store the signing secret as a secret, not in source code.
- Verify the signature against the raw request body.
- Reject old timestamps to reduce replay risk.
- Keep handlers idempotent because deliveries can retry.
- Do not rely on redirects. tickward sends requests directly to the configured URL.
TICKWARD_WEBHOOK_ALLOW_PRIVATE_NETWORKS=true and keep those endpoints private.
Delivery
Mutations write events to the database first. A scheduler tick then dispatches due events and retries failed deliveries with backoff. This keeps API requests fast and makes delivery durable. A failed receiver does not block timer edits or API calls.Limits and automatic disable
Each account can keep up to 3 active webhook endpoints. Creating an endpoint past the limit returns alimit_exceeded error. Disabled endpoints do not
count against the limit.
An endpoint that keeps failing is disabled automatically after 25 consecutive
failed delivery attempts with no successful delivery in between. With the
default retry policy that equals 5 events that exhausted all retries. Any
successful delivery resets the failure counter.
When an endpoint is disabled automatically, tickward emails the account owner
if a mail provider is configured. Fix the receiver, then use Enable on the
endpoint in Settings (or PATCH /api/account/webhooks/:id with
{"status": "active"}). Re-enabling resets the failure counter.
Use Disable when you want to pause deliveries and keep the endpoint history.
Use Remove only when the endpoint and its delivery history should be deleted.
Each endpoint row in Settings also shows its recent deliveries with status,
HTTP response code, attempt count, and the last error - check there first when
an automation platform does not receive events.
Self-hosted deployments can tune both limits:
Scheduler
Self-hosted deployments should call the scheduler endpoint periodically:TICKWARD_SCHEDULER_SECRET in the app environment. The same secret must be
used by the scheduler caller.
You can run the scheduler anywhere that can reach your tickward deployment:
- Cloudflare Cron Trigger
- AWS EventBridge Scheduler
- a VPS cron job
- a container worker
- another hosted scheduler
examples/scheduler/cloudflare-worker for a copy-paste starter.
Run it every minute for near-real-time webhook delivery. Browser-local alarms can
still fire immediately while tickward is open. Long-term, the same event
contract can be processed by Temporal for durable scheduled work without
changing webhook receivers.