Integrations
Send webhooks from automation rules
Send Job and email events to your own system with a webhook: set up the rule, verify the signature, and check or resend deliveries.
A webhook tells another system the moment something happens in Tidyflow, such as a Job moving to a status. Webhooks are an action on automation rules, so you choose what sends one. They are part of the Pro plan, see pricing, and an owner or admin sets them up.
Webhooks send Job events and incoming email events. To read or change clients, contacts, invoices and other records, use the Tidyflow API alongside them.
Set up a webhook rule
- Go to Settings → Automations and click New rule.
- Enter a Name, such as “Send status changes to our CRM”.
- Under When, choose what sends the webhook.
- Under Then, choose Send webhook.
- Enter the Webhook URL. It must start with
https://and be reachable from the internet. - Click Send test to send a
pingevent. The result shows under the URL. - Click Save.
Tidyflow creates the rule’s Signing secret when you save. Open the rule again and click Copy to put the secret in your endpoint. A test sent before the first save is not signed.
What can send a webhook
Any Job trigger can send a webhook: a date passing or approaching, a tag being added, a status change or a new Job. So can An email is received on a shared inbox. See Automate Jobs with rules and Automate incoming email for the triggers and conditions.
To hear about every status a Job moves through with one rule, choose A Job status changes and then Any status.
Rules that start from a new client or an accepted proposal cannot send a webhook.
How often a webhook rule sends
A webhook rule sends every time its event happens. A Job that returns to a status sends again, and so does a tag that is removed and added back.
Date rules send once per Job. If you change the Job’s date, the rule can send again for the new date.
Webhook events and payload
Each delivery is a POST with a JSON body. The event field names what happened:
| Event | Sent when |
|---|---|
job.created | A Job is created |
job.status_changed | A Job’s status changes |
job.tag_added | The rule’s tag is added to a Job |
job.date_passed | The rule’s date has passed |
job.date_approaching | The rule’s date is coming up |
email.received | An email arrives in a shared inbox |
ping | You click Send test |
A Job event looks like this:
{
"id": "0199f3a2-7c1e-7b6e-9c3a-5d2f8e1a4b70",
"event": "job.status_changed",
"occurred_at": "2026-11-11T09:42:10+00:00",
"automation": { "id": "0199e0c4-...", "name": "Send status changes to our CRM" },
"data": {
"job": {
"id": "0199d7b1-...",
"name": "2025 tax return",
"url": "https://app.tidyflow.com/jobs/0199d7b1-.../2025-tax-return",
"status": { "key": "in-review", "label": "In review" },
"client": { "id": "0199c2aa-...", "name": "Ruiz Family" },
"assignees": [{ "id": "0199b1f0-...", "name": "Sarah Chen" }],
"tags": ["Priority"],
"start_date": "2026-11-01",
"due_date": "2026-11-30",
"internal_due_date": null,
"extended_due_date": null
},
"change": { "field": "status", "from": "in-progress", "to": "in-review" }
}
}
change is present for status and tag events. Date events carry date_field in its place. The id values match the ids the Tidyflow API uses, so you can fetch more detail with an API token. An email.received event carries data.email with the subject, sender, recipients, received time and whether it has attachments. It never includes the email body.
New fields may be added over time, so ignore fields your code does not know.
Verify a webhook signature
Every delivery from a saved rule is signed, following the Standard Webhooks format, so its libraries can verify Tidyflow webhooks without custom code. Each request carries three headers:
webhook-id: the delivery’s id, the same asidin the body.webhook-timestamp: when it was sent, in seconds.webhook-signature:v1,followed by the signature.
To check a signature yourself:
- Take the part of the secret after
whsec_and base64-decode it. That is the key. - Join the id, the timestamp and the raw request body with full stops:
{webhook-id}.{webhook-timestamp}.{body}. - Compute an HMAC-SHA256 of that string with the key and base64-encode the result.
- Compare it with the value after
v1,. Reject the request if they differ or the timestamp is more than a few minutes old.
Use the raw body exactly as received. Parsing and re-encoding the JSON changes it and the signature will not match.
To replace a secret, open the rule, click Roll next to Signing secret, then Roll secret. New deliveries use the new secret straight away, so update your endpoint at the same time.
Webhook retries and failures
Your endpoint should answer with any 2xx status within 10 seconds. Tidyflow does not follow redirects.
If a delivery fails, Tidyflow tries again up to seven more times over about a day, waiting longer each time: 1 minute, 5 minutes, 30 minutes, then 2, 4, 8 and 10 hours. A retry keeps the same webhook-id, so use it to ignore a delivery you have already handled.
When every try has failed, the rule shows Last delivery failed in Settings → Automations until a later delivery succeeds.
Check webhook delivery history and resend
- Go to Settings → Automations.
- Open the menu on the webhook rule and click Delivery history.
The history lists the rule’s recent deliveries from the last 30 days with the result of each. Click Resend to send one again with the same id and payload, or the copy button to copy the payload for debugging. The rule must be turned on to resend.
Related articles
Was this page helpful?
What went wrong?
Thanks for your feedback.
- Previous
- QuickBooks Online integration
Last updated November 11, 2026