Skip to content

Example — HubSpot deal provisioning

This guide walks through a production-style workflow that:

  1. Receives a HubSpot deal closed won webhook
  2. Finds or creates the Patrol customer and environment (idempotent on re-run)
  3. Updates the HubSpot deal with the new environment details

Create a new workflow under Workflows in Patrol and follow the node configuration below.

flowchart TD
  A[Deal closed won<br/>HubSpot trigger] --> B[Find or create customer]
  B --> C[Find or create environment]
  C --> D[Update deal<br/>HubSpot output]

Each step passes context forward. Downstream nodes reference paths like customer.id, environment.name, and trigger.dealId.

Before building this workflow, set up:

  • A connected HubSpot integration with:
    • crm.objects.deals.read and crm.objects.companies.read
    • crm.objects.deals.write (required for the Update deal step)
  • A HubSpot automation workflow that POSTs to Patrol’s webhook URL when a deal reaches Closed Won (include dealId / hs_object_id and portalId in the body)
  • At least one service template in Patrol’s catalogue
  • A HubSpot deal property to write provisioning notes into (this example uses the internal name description; use a custom property if your portal does not expose description on deals)
SettingValue
Node typeDeal closed won (hubspot:deal_closed_won)
IntegrationYour HubSpot integration

No field mapping is required on the trigger. Patrol merges the webhook body with CRM data into trigger.* paths (for example trigger.dealId, trigger.deal.dealname, trigger.deal.product, trigger.company.name).

Matches an existing customer by HubSpot company ID, or creates one on first run.

FieldMappingNotes
Nametrigger.company.nameFalls back to deal name if company name is empty
HubSpot company ID (external ref)trigger.companyIdUsed to find the same customer on re-run

Optional mappings from deal properties:

FieldExample mapping
Support tiertrigger.deal.support_tier
Cloud providertrigger.deal.cloud_provider
Cloud regiontrigger.deal.cloud_region

Outputs used downstream: customer.id, customer.name

Creates the environment on first run; finds the existing record when the same deal triggers again.

FieldMappingNotes
HubSpot deal ID (external ref)trigger.dealIdPrimary lookup key — auto-filled if omitted
Name (create)(leave blank)Defaults to {deal name} Environment, e.g. Acme Expansion Environment
Service template ID (create)trigger.deal.productMap from a HubSpot deal property holding your catalogue template UUID
Type (create)ProductionLiteral value (no dots)

You can also set an explicit name template, e.g. New ${trigger.deal.dealname} env, instead of the default.

Outputs used downstream: environment.id, environment.name

Writes provisioning results back to HubSpot.

FieldMapping
Deal IDtrigger.dealId

Add a property row for each HubSpot field to update:

HubSpot property (internal name)Value
descriptionEnvironment created in Patrol called ${environment.name}. View it here: https://app.usepatrol.dev/environments/${environment.id}

The property name column must be the HubSpot CRM internal name (e.g. description), not Patrol context notation like deal.description or trigger.deal.description.

After a successful run, HubSpot shows text similar to:

Environment created in Patrol called Acme Expansion Environment. View it here: https://app.usepatrol.dev/environments/0ed70a2c-a8cb-462f-8a19-cac26a87d612

Use the workflow Debug tab before going live:

  1. Click Listen for trigger and send a HubSpot webhook test (or close a test deal)
  2. Step next node through each action
  3. Expand each step in the execution trace — confirm Field mapping and Resolved values match expectations
  4. Re-run the same trigger to confirm Find or create environment finds the existing record instead of failing

See Workflows — Test mode for full debug instructions.

  • Executions tab on the workflow — per-run status, duration, and step details
  • Integrations → Event Log — inbound webhooks and outbound HubSpot API calls