Workflows and Webhooks
Triggers#
Workflows start with a trigger. When the trigger event occurs, the workflow's actions run in order.
| Trigger | When it fires |
|---|---|
form_submitted |
A form response is completed |
booking_created |
A new booking is created |
booking_cancelled |
A booking is cancelled |
booking_pending / booking_confirmed |
A booking enters the corresponding state |
new_contact_created |
A brand-new contact is stored |
tag_added |
A tag is added to a contact |
manual |
Triggered manually via the API |
scheduled |
Hourly, daily, weekly, or monthly in the configured timezone |
Actions#
Chain actions together with conditions and delays.
| Action | What it does |
|---|---|
send_email |
Send an email via Resend (at most 3 per workflow) |
ai_research |
Research and enrich a contact with structured results |
add_tag / remove_tag |
Modify contact tags |
wait |
Delay execution by a specified duration |
condition |
If/else branching based on contact data |
webhook |
HTTP request to an external URL |
update_contact |
Modify contact fields |
Webhooks#
To get real-time notifications, create a workflow with a trigger (for example form_submitted) and add a webhook action pointing to your URL.
{
"trigger": "booking_created",
"actions": [
{
"type": "webhook",
"config": {
"url": "https://your-app.com/webhooks/goodinbound",
"method": "POST",
"headers": {
"X-Webhook-Secret": "your_secret"
}
}
}
]
}
A webhook step sends the configured method, headers, and body. The method defaults to POST, and the body defaults to the workflow context below; you can replace it and interpolate workflow values.
Default payload
{
"projectId": "proj_123",
"contactId": "ct_m1n2o3",
"contactEmail": "jane@example.com",
"formResponseId": "resp_a1b2c3d4",
"metadata": {}
}
Always verify webhook payloads with a shared secret header so you know requests came from GoodInbound.
To manage workflows from code, see Workflows in the Management API.