If you've ever watched a deal close in HubSpot and then had to manually generate the contract in Docusign, this guide is for you. We'll set up end-to-end automation so that the moment a HubSpot deal hits closed-won, a Docusign Workflow Builder run fires with the right template, the right signers, and the right deal data pre-filled.

What you'll need #

  • A HubSpot account on Professional or Enterprise tier for at least one Hub (Sales, Marketing, Operations, Service, or Content). HubSpot webhooks ride on the workflows engine, which Starter doesn't include.
  • A Docusign account with IAM and Workflow Builder enabled. Workflow Builder is Docusign's low-code workflow orchestration surface, part of the IAM (Identity and Access Management) plan.
  • A Baton account. Baton is the relay between HubSpot webhooks and Docusign Workflow Builder runs - it verifies the HMAC signature on the incoming webhook, matches the payload fields to your Docusign workflow's expected parameters, and fires an authenticated API request to Docusign.

How HubSpot webhooks fire #

HubSpot doesn't use the generic "Webhooks API" approach you'll see in other CRMs. Instead, webhooks are a workflow action. You build a HubSpot workflow with a trigger (e.g. "Deal stage becomes Closed Won") and a webhook action that HTTP POSTs a signed payload to a URL you provide.

Payload shape: HubSpot sends a JSON body containing the object ID (e.g. deal ID), a list of property changes, and metadata about the subscription. Every request includes a X-HubSpot-Signature-v3 header that HMAC-signs the body with your account's client secret. Baton verifies this signature before acting - Baton does not authenticate to HubSpot in any way, it only verifies that the incoming webhook came from HubSpot.

Step 1 - Add the automation in Baton #

In the Baton Command Center, open Flow Builder and click + Add Automation. Select HubSpot as the source platform. Pick the target Docusign Workflow Builder workflow from the dropdown - the list is populated from your connected Docusign account by the Workflow Checker, which syncs every workflow your org has access to along with the API parameters each one declares.

Baton generates a unique, UUID-tokenized webhook URL for this automation. It looks like:

https://app.iambaton.com/hook/a7f3b9e2c8d1

In the same panel, enter the Webhook Secret field with the HMAC client secret from HubSpot. Baton uses this secret to verify the X-HubSpot-Signature-v3 header on every incoming webhook.

Copy the webhook URL. You'll paste it into HubSpot in the next step.

Step 2 - Build the HubSpot workflow #

In HubSpot, navigate to Automation → Workflows → Create workflow. Choose Deal-based workflow.

Set the trigger: When a deal stage changes to "Closed Won" (or whichever stage should fire the agreement).

Add a single action: Send a webhook.

Fill in the webhook action:

  • URL: paste the Baton URL from Step 1
  • Method: POST
  • Authentication: HubSpot signs with your account's client secret automatically - the matching secret must be entered in Baton's Webhook Secret field
  • Include all properties: yes (Baton only uses fields whose names match the Docusign workflow's parameter contract, so sending the full record is safe)

Save and turn the workflow on.

Step 3 - How Baton maps fields #

There is no drag-and-drop field mapping step in Baton. Instead, Baton relies on the parameter contract your Docusign Workflow Builder workflow declares. When you build a Workflow Builder workflow, its start trigger specifies named, typed parameters (e.g. objectId STRING, companyId STRING, email STRING). Baton's Workflow Checker page syncs that contract and displays it as a read-only reference.

At runtime, when a HubSpot webhook arrives, Baton scans the JSON payload and matches fields by name to the parameters your workflow expects. A HubSpot payload that contains objectId: 757533273294 will match a Docusign workflow parameter named objectId automatically - no explicit mapping required.

If you need a different field layout, you design the Docusign workflow to expect different parameter names. The extraction is configurable - configured on the Docusign side, not in Baton.

Step 4 - Test end-to-end #

In HubSpot, move a test deal to the Closed Won stage. In the Baton Command Center's Flow Builder, you should see the automation card's counter tick up within a few seconds.

Click Logs on the automation card to see the Action log:

  1. Webhook verification → Verified - HMAC signature checked out
  2. Maestro Trigger → Launched - Baton fired the API request and Docusign returned a Maestro Instance ID

Each Action stores three IDs you can copy: the Webhook ID (Baton's idempotency key, so duplicates don't retrigger), the Action ID (Baton's internal trace of verify + route), and the Maestro Instance ID (links directly to the instance in Docusign).

If something failed, the Action log shows where: verification_failed if the HMAC didn't match, validation_error if no payload field matched a workflow parameter, or upstream_error if the Docusign API returned an error.

What can go wrong (and how Baton handles it) #

HMAC signature mismatch. The secret in Baton doesn't match HubSpot's. Action marked verification_failed, webhook rejected at the door, nothing fires to Docusign. Fix the secret in the Edit Automation panel, retry the webhook from HubSpot's retry log.

Payload fields don't match workflow parameters. HubSpot's webhook doesn't contain a field whose name matches a required parameter on the Docusign workflow. Action marked validation_error. Inspect the raw payload from the Action log and either adjust the Docusign workflow's parameter names or change which HubSpot fields get sent.

Docusign API returns an error. Network hiccup, token expiry, workflow archived. Action marked upstream_error and retried with exponential backoff. After retries are exhausted, an Automation Failed notification fires - visible in the Inbox and routable to Slack.

Docusign OAuth token expiry. The only OAuth connection Baton maintains is to Docusign. A scheduled job refreshes the token every 5 minutes, so this rarely surfaces. If the org's Docusign connection is revoked entirely, a Connection Degraded alert fires and blocks the automation until reconnected.

Monitoring and observability #

Every Action logs:

  • Timestamp + relative time
  • Full webhook payload received (viewable under "View Payload")
  • Signature verification result
  • Docusign API request + response
  • Maestro Instance ID (with a direct-open link into Docusign)
  • 2-phase lifecycle status

You can filter the Action log by status and date. Failures surface in the Notifications Inbox, filterable by severity and category. Slack routing per event type is configurable under Notifications.

Beyond deals: other HubSpot triggers #

The same pattern works for any HubSpot workflow event that can send a webhook action. Common configurations teams ship in week one:

  • Contact becomes qualified lead → fire NDA workflow
  • Vendor record created in HubSpot → fire onboarding pack (MSA + W9 + banking form)
  • Quote approved → fire order form workflow
  • Custom property "Contract type" = Enterprise → route to a workflow with different signers

Each one is a separate Baton automation with its own webhook URL - add it from the Flow Builder, paste the URL into the corresponding HubSpot workflow, done.

Closing thought #

The reason teams end up wiring HubSpot to Docusign through Baton rather than Zapier isn't that Zapier can't fire a webhook - it's that Zapier doesn't answer the hard questions when things go wrong. Which deal stalled? Why? Which workflow failed? How do I retry? Baton's two-phase Action log (verify → route) with three persistent IDs per Action makes every run traceable, and the Notifications Inbox surfaces failures immediately instead of letting them disappear.

If you want to see this wired up on your actual HubSpot and Docusign accounts, book a 20-minute demo and we'll run it live.