Send Webhook
Send HTTP requests to any external service whenever something happens in HubSpot.
On this page
Overview
The Send Webhook action lets your HubSpot workflow communicate with any external service by sending an HTTP request. You specify where it goes (the URL), what data to send (the body), how to authenticate (headers), and what method to use (POST, GET, PUT, PATCH, DELETE).
This is the primary way to connect HubSpot to tools like Slack, Stripe, Google Sheets, Airtable, your own backend server, or any service that accepts HTTP requests.
When to use Send Webhook
- Notify your team on Slack when a deal closes or a new lead signs up
- Create invoices in Stripe when a deal moves to "Closed Won"
- Sync contact or deal data to your own API or database
- Log events to Google Sheets every time a form is submitted
- Trigger external automations in Zapier, Make, or your own microservices
- Fetch data from an external API and map the response back into HubSpot properties
Setup
Follow these steps to add Send Webhook to your HubSpot workflow:
Add the action to your workflow
In your HubSpot workflow editor, click the + button to add a new action. Search for "AuPerate: Send Webhook" under Custom Actions and select it.
Enter the webhook URL
Paste the full URL of the service you want to reach. You can use template variables like {{contact.email}} to dynamically insert HubSpot property values.
Configure method, headers, and body
Choose the HTTP method, add authentication headers, write the request body in JSON, and optionally configure output mappings.
Save and publish
Save your workflow action configuration. The webhook will fire every time a record enters that step of the workflow.
Configuration
Webhook URL Required
The full URL to send the request to. Must start with https://. You can include template variables that HubSpot replaces with property values at runtime.
https://api.example.com/contacts/{{contact.email}}/update{{property_name}}. These are replaced by HubSpot with the actual property value of the enrolled record when the workflow runs.HTTP Method
Select the HTTP method that matches your use case:
POST Send data to the service (most common). Default method.GET Fetch data from the service. Body is ignored.PUT Replace existing data at the URL.PATCH Partially update existing data.DELETE Remove data at the URL.Request Body
Write the request body in JSON format. Use template variables to include HubSpot property values. The body is sent as-is, with template variables replaced by HubSpot.
{
"email": "{{contact.email}}",
"first_name": "{{contact.firstname}}",
"company": "{{contact.company}}",
"deal_amount": "{{deal.amount}}",
"custom_message": "New lead from HubSpot!"
}Request Headers
Add custom headers in JSON format. This is where you set authentication tokens, API keys, and content type.Content-Type: application/json is added automatically if not specified.
{
"Authorization": "Bearer your-api-key-here",
"X-Custom-Header": "optihub-workflow",
"Content-Type": "application/json"
}Output Mappings
Extract values from the HTTP response and make them available as output fields in your workflow. Use JSON path notation to specify which fields to extract.
{
"output1": "$.data.id",
"output2": "$.data.status",
"output3": "$.data.created_at"
}Up to 3 output fields can be mapped. These become available in subsequent workflow steps as output properties (output1, output2, output3).
Retry Settings
Configure automatic retries for failed requests. When enabled, AuPerate will retry the webhook if it receives a 5xx error or times out.
Output Fields
Every Send Webhook execution produces the following output fields, available in subsequent workflow steps:
| Field | Type | Description |
|---|---|---|
| optihub_success | Boolean | true if the request returned a 2xx status code |
| optihub_status_code | Number | The HTTP status code returned (e.g., 200, 404, 500) |
| optihub_error | String | Error message if the request failed, empty if successful |
| optihub_retries_used | Number | Number of retry attempts used (0 if succeeded on first try) |
| output1, output2, output3 | String | Values extracted from the response body via output mappings |
Examples
1Send a notification to Slack
Post a message to a Slack channel whenever a new deal is closed in HubSpot.
https://hooks.slack.com/services/T00000/B00000/XXXXX{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*New Deal Won!* :tada:\n*Deal:* {'{{'}dealname{'}}'}\n*Amount:* {{amount{'}}'}\n*Owner:* {'{{'}hubspot_owner_id{'}}'}"
}
}
]
}2Post data to a custom API with authentication
Send contact data to your backend API with a Bearer token for authentication.
https://api.yourcompany.com/hubspot/contacts{
"Authorization": "Bearer sk_live_abc123xyz",
"Content-Type": "application/json",
"X-Source": "hubspot-workflow"
}{
"email": "{{email}}",
"first_name": "{{firstname}}",
"last_name": "{{lastname}}",
"company": "{{company}}",
"lifecycle_stage": "{{lifecyclestage}}",
"source": "hubspot"
}3GET request with response mapping
Fetch company data from Clearbit and map the response back into your workflow.
https://company.clearbit.com/v2/companies/find?domain={{company_domain}}{
"Authorization": "Bearer sk_clearbit_abc123"
}{
"output1": "$.name",
"output2": "$.metrics.employees",
"output3": "$.category.industry"
}After execution, output1 contains the company name, output2 contains the employee count, and output3 contains the industry. Use these in subsequent workflow steps to update HubSpot properties.
Security
SSRF Protection
AuPerate includes built-in Server-Side Request Forgery (SSRF) protection. The following URL patterns are blocked to prevent abuse:
Blocked URLs
- •
localhostand127.0.0.1-- local loopback addresses - •
10.x.x.x,172.16-31.x.x,192.168.x.x-- private network ranges - •
169.254.x.x-- cloud metadata endpoints (AWS, GCP, Azure) - •
http://URLs -- onlyhttps://is allowed
Data Handling
- Request and response data is not stored permanently. Only execution metadata (status, duration, error messages) is logged.
- All requests are made over HTTPS with TLS 1.2+.
- API keys in headers are masked in execution logs.
- Requests time out after 30 seconds to prevent hanging workflows.
Troubleshooting
Error: "SSRF blocked"
The URL you entered points to a private network or localhost. Only public HTTPS URLs are allowed. Make sure your service is publicly accessible and uses https://.
Error: "Invalid JSON in body"
The request body is not valid JSON. Common issues: trailing commas, unquoted keys, single quotes instead of double quotes. Use a JSON validator to check your body before pasting it in.
Error: "Timeout after 30s"
The external service did not respond within 30 seconds. This could be because the service is slow or down. Enable retries to automatically retry on timeout. If the issue persists, check with the service provider.
Status code 401 or 403
Authentication failed. Double-check your API key or Bearer token in the headers. Make sure the token has not expired and has the required permissions for the endpoint you are calling.
Status code 400
The external service rejected your request. Check the response body in your execution logs for details. Common causes: missing required fields, wrong data types, or invalid template variable values.
Template variables showing as empty
If a HubSpot property has no value for the enrolled record, the template variable resolves to an empty string. Use the Format Data action before Send Webhook to set default values.
Next: Run Custom Code
Learn how to execute JavaScript in your workflows.