Webhooks
Webhooks let the platform automatically notify your other business tools whenever something important happens - such as a new contact being created, an appointment being booked, or a message being received. Instead of manually checking for updates, your connected systems get an instant notification the moment something happens.
What Are Webhooks?
Think of a webhook like an automatic text message between two apps. When something happens in the app (like a new contact signing up), the platform instantly sends a notification to another system of your choice. You provide a web address (called a “webhook URL”) where these notifications should be sent - this is typically provided by your CRM, automation platform, or developer.
Note: Setting up webhooks involves some technical configuration. If you are not comfortable with this, consider sharing this page with your developer or using an automation platform like Zapier, Make, or Pabbly, which provide webhook URLs with no coding required.
Common uses include:
- Syncing new contacts to your CRM.
- Triggering a workflow in Zapier, Make, or Pabbly when a tag is applied.
- Notifying your team in Slack when a human is alerted.
- Updating your calendar system when an appointment is booked.
- Logging conversation summaries to your database.
Setting Up Webhooks
- In the app, go to Settings > Webhook.
- Enter your Webhook URL - this is the web address where the platform will send event notifications. You get this URL from your external system (CRM, automation platform, or custom server).
- Select the trigger events you want to listen for (see the full list below).
- Optionally, configure tag-based triggers for more granular control.
- Click Save to activate your webhook.
Available Trigger Events
You can enable or disable each event independently. When an event fires, the platform automatically sends a notification to your webhook URL with the relevant data.
| Event | Description |
|---|---|
| Contact Created | A new contact is added to your account (manually, via import, or via API). |
| Contact Resumed | A paused or stopped contact conversation is resumed. |
| Contact Paused | A contact conversation is paused (bot stops responding). |
| Contact Do Not Disturb | A contact’s Do Not Disturb setting is turned on, meaning no further automated messages should be sent. |
| Contact Unarchived | An archived contact sends a new message, bringing them back into your active inbox. |
| Human Alerted | The AI bot determines it cannot handle a conversation and flags it for human attention. |
| Appointment Booked | A contact books an appointment through the booking system. |
| New Message | A new message is received from a contact on any channel. |
| Replies | A contact replies to a message. |
| Reads | A contact reads a message (on channels that support read receipts). |
| Deliveries | A message is successfully delivered to a contact. |
| Credits Spent | Credits are deducted from your account (useful for tracking usage in external systems). |
| Credits Recharged | Credits are added to your account via auto-recharge or manual purchase. |
| Agency Sub-Account Auto-Recharge | (Agency only) A sub-account’s credit balance dropped below their auto-recharge threshold. Your server should process payment and grant credits via the API. |
Tag-Based Webhook Triggers
For more precise control, you can configure webhooks to fire only when specific tags are applied:
- In the webhook settings, look for the Tags section.
- Select one or more tags.
- When any of the selected tags is applied to a contact, the webhook fires with the tagging event data.
This is useful when you want to trigger external workflows only for certain outcomes - for example, only when a contact is tagged as “qualified-lead” or “booked.”
Generate Summary for Tagged Contacts
When configuring tag-based triggers, you can check the Generate Summary option. When enabled, the platform will automatically generate a conversation summary for the contact at the time the tag is applied. This summary is included in the webhook data, giving your external system full context about the conversation without having to request it separately.
Testing Your Webhook
Before relying on your webhook in production, test it:
- Enter your webhook URL in Settings > Webhook.
- Click Send Test Event.
- Check your external system to confirm it received the test data.
- Review the data format to make sure your system can parse it correctly.
For a full end-to-end test:
- Send yourself a campaign message and trigger one of the configured events.
- Or use an incoming campaign and send a message to your connected number or channel.
- Verify the webhook fires and your external system processes it as expected.
Tip: Use a tool like webhook.site or RequestBin during development to inspect the raw webhook data before connecting your production system.
Webhook Data Format
When a webhook fires, the platform sends structured data (in JSON format) to your webhook URL. If you are using an automation platform like Zapier or Make, it will parse this data for you automatically. If you are building a custom integration, here is what the data looks like:
{
"event": "contact_tagged",
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"contactId": "abc123xyz",
"contactName": "Jane Smith",
"contactPhone": "+15551234567",
...
}
}
| Field | Description |
|---|---|
event |
The type of event that triggered the notification (for example, contact_created, appointment_booked). |
timestamp |
The date and time when the event occurred. |
data |
The details of the event (varies depending on what happened). |
The data section varies depending on the event. For example, an appointment_booked event includes appointment details like date, time, and attendee information, while a new_message event includes the message text, which channel it came from, and who sent it.
Agency Sub-Account Auto-Recharge Webhook
If you are an agency using a custom payment provider (instead of Stripe) for credit reselling, the platform can notify your server whenever a sub-account needs credits. Your server then processes the payment and calls the API to grant the credits.
To set this up, go to your agency Reselling settings and enter your webhook URL in the Auto-Recharge Webhook section. For the non-technical overview, see Agency Accounts.
Event name
agency_sub_account_auto_recharge
When it fires
This webhook is sent when a sub-account’s credit balance drops below their configured auto-recharge threshold.
Payload format
{
"event": "agency_sub_account_auto_recharge",
"sub_account_id": "<firebase-uid>",
"sub_account_email": "[email protected]",
"sub_account_name": "John Doe",
"agency_id": "<firebase-uid>",
"credits_requested": 500,
"current_balance": 42,
"threshold": 100,
"price_per_credit_cents": 10,
"price_per_credit_currency": "usd",
"total_amount_cents": 5000,
"timestamp": "2026-04-13T12:00:00.000Z",
"idempotency_key": "auto_recharge_abc123_1681387200000"
}
| Field | Description |
|---|---|
event |
Always agency_sub_account_auto_recharge for this webhook. |
sub_account_id |
The unique ID of the sub-account that needs credits. |
sub_account_email |
The sub-account’s email address. |
sub_account_name |
The sub-account’s display name. |
agency_id |
Your agency account’s unique ID. |
credits_requested |
How many credits the sub-account needs (based on their auto-recharge settings). |
current_balance |
The sub-account’s credit balance at the time the webhook was sent. |
threshold |
The balance threshold that triggered the recharge. |
price_per_credit_cents |
Your configured price per credit, in cents. |
price_per_credit_currency |
The currency for the price (e.g., usd). |
total_amount_cents |
The total amount to charge, in cents (credits_requested x price_per_credit_cents). |
timestamp |
When the webhook was sent (ISO 8601 format). |
idempotency_key |
A unique key for this specific recharge request. Use this to prevent granting credits twice if your server receives the same webhook more than once. |
What to do after receiving this webhook
- Verify the request — Check the
idempotency_keyto make sure you have not already processed this recharge. - Process payment — Charge the sub-account using your payment provider (card charge, invoice, balance deduction, etc.).
- Grant credits — Call the API to add credits to the sub-account. See API Access — Grant Credits to a Sub-Account for the exact request format.
- Return a success response — Respond with an HTTP
200status code to acknowledge receipt.
Important notes
- 5-minute cooldown: After a webhook is sent for a sub-account, the platform will not send another one for the same sub-account for at least 5 minutes, even if their balance drops further. This prevents duplicate charges during processing.
- Use the idempotency key: Always check the
idempotency_keybefore granting credits. If your server crashed after granting credits but before responding, the platform may resend the webhook on the next credit drop. - Failures are safe: If your webhook URL is unreachable or returns an error, no credits are granted and nothing breaks. The system will send a new webhook the next time the sub-account’s balance drops below the threshold.
Webhook Reliability
- The platform sends webhooks over a secure connection (HTTPS). Make sure the web address you provide uses HTTPS.
- If your system returns an error, the delivery is considered failed.
- Monitor your receiving system’s uptime to avoid missing events.
- For critical workflows, consider building in a fallback mechanism (for example, periodically checking the app for missed events).
Troubleshooting
| Problem | Solution |
|---|---|
| Webhook not firing | Confirm the webhook is saved and the correct events are selected. Check that your URL is reachable from the internet. |
| Test event works but real events do not | Make sure the specific event type is enabled. For tag-based triggers, confirm the correct tags are selected. |
| Receiving duplicate events | Check if you have multiple webhook configurations pointing to the same URL. |
| Data is empty or malformed | Verify your receiving system accepts JSON data. Check your server logs for parsing errors. |
| Webhook URL returns errors | Test your URL with a tool like Postman or webhook.site to confirm it can accept incoming data. |
Next Steps
- GoHighLevel Integration - Use webhooks to integrate the platform with GHL.
- API Access - Combine webhooks with the API for powerful automations.
- Creating Tags - Set up tags that trigger your webhooks.