Add a Custom Webhook action to the workflow that already handles this. GoHighLevel can act as either side, so the steps are the same shape at the start and at the finish.
Decide where this action goes: right after the very first step of the scenario, before any of the real work happens.
In GoHighLevel, go to Automation, then Workflows. Open the workflow that handles this, or create one.
Click the plus icon at that point to add an action, then choose Send Data, then Webhook (called Custom Webhook on older accounts).
Method: set to POST.
URL: paste this in.
https://flowproof-ok3mquge8-hitenbs-projects.vercel.app/api/v1/events
Headers: add a header named Authorization with value:
Bearer fp_live_YOUR_API_KEY
Body Format: set to JSON.
Body: paste the template below, then fill external_id and match with real contact fields (see the table underneath).
{
"flow": "your-flow-slug",
"endpoint": "source",
"external_id": "USE-YOUR-OWN-REFERENCE",
"match": {
"phone": "+15551234567"
}
}| Key | What it is | What to replace with |
|---|---|---|
| flow | Your flow's identifier | Leave as shown |
| endpoint | Which side of the run this is | "source" for the start ping, "destination" for the finish ping |
| external_id | Unique reference for this specific run | A row ID, order ID, or unique field from the incoming data. Use the tool's variable syntax. |
| match | Fields used to pair start and finish pings | Include whichever unique identifier is available (email, phone, order_id). Use the tool's variable syntax. |
GoHighLevel's variable picker inserts contact and opportunity fields directly, e.g. {{contact.email}} or {{contact.phone}}. For example:
"external_id": "{{contact.id}}",
"match": { "email": "{{contact.email}}" }"external_id": "{{opportunity.id}}",
"match": { "phone": "{{contact.phone}}" }Save the action, then save and publish the workflow.
You'll add TWO of these actions total: one BEFORE the work step with endpoint: source, and one AFTER the work step with endpoint: destination. They share the same external_id so FlowProofs can pair them.
START OF YOUR FLOW | +--> FlowProofs webhook action (endpoint: source) <- add this first | v ...your existing steps, untouched... | +--> FlowProofs webhook action (endpoint: destination) <- add this last v END OF YOUR FLOW
Publish the workflow and trigger it once. Return to FlowProofs. The pending indicator turns green when your first ping arrives.
Screenshot placeholder
GoHighLevel workflow action: Send Data → Custom Webhook
drop a PNG at /public/docs/gohighlevel-custom-webhook.png
Decide where this action goes: right after the very last step, once the record has actually landed where it should.
In GoHighLevel, go to Automation, then Workflows. Open the workflow that handles this, or create one.
Click the plus icon at that point to add an action, then choose Send Data, then Webhook (called Custom Webhook on older accounts).
Method: set to POST.
URL: paste this in.
https://flowproof-ok3mquge8-hitenbs-projects.vercel.app/api/v1/events
Headers: add a header named Authorization with value:
Bearer fp_live_YOUR_API_KEY
Body Format: set to JSON.
Body: paste the template below, then fill external_id and match with real contact fields (see the table underneath).
{
"flow": "your-flow-slug",
"endpoint": "destination",
"external_id": "USE-YOUR-OWN-REFERENCE",
"match": {
"phone": "+15551234567"
}
}| Key | What it is | What to replace with |
|---|---|---|
| flow | Your flow's identifier | Leave as shown |
| endpoint | Which side of the run this is | "source" for the start ping, "destination" for the finish ping |
| external_id | Unique reference for this specific run | A row ID, order ID, or unique field from the incoming data. Use the tool's variable syntax. |
| match | Fields used to pair start and finish pings | Include whichever unique identifier is available (email, phone, order_id). Use the tool's variable syntax. |
GoHighLevel's variable picker inserts contact and opportunity fields directly, e.g. {{contact.email}} or {{contact.phone}}. For example:
"external_id": "{{contact.id}}",
"match": { "email": "{{contact.email}}" }"external_id": "{{opportunity.id}}",
"match": { "phone": "{{contact.phone}}" }Save the action, then save and publish the workflow.
You'll add TWO of these actions total: one BEFORE the work step with endpoint: source, and one AFTER the work step with endpoint: destination. They share the same external_id so FlowProofs can pair them.
START OF YOUR FLOW | +--> FlowProofs webhook action (endpoint: source) <- add this first | v ...your existing steps, untouched... | +--> FlowProofs webhook action (endpoint: destination) <- add this last v END OF YOUR FLOW
Publish the workflow and trigger it once. Return to FlowProofs. The pending indicator turns green when your first ping arrives.
Screenshot placeholder
GoHighLevel workflow published with the webhook action in place
drop a PNG at /public/docs/gohighlevel-workflow-published.png