Zapier, Make & n8n

Connect HailMate to thousands of apps

Zapier, Make and n8n each have a built-in step for receiving a webhook and one for making an HTTP request. With a HailMate API key, those two steps connect HailMate to Slack, Google Sheets, your accounting app, your website forms and thousands more — today, with no code.

Two building blocks

You wantHailMate sideAutomation-tool side
HailMate starts it — “when a claim is approved…”A webhook to the tool’s URLZapier: Catch Hook · Make: Custom webhook · n8n: Webhook node
HailMate does it — “…then create a job”An API request with your keyZapier: Custom Request · Make: Make a request · n8n: HTTP Request node

For both you need an API key: in HailMate open Settings → Integrations → API & Webhooks and press New key. Give each tool its own key, so revoking one never breaks another, and use a read-only key for anything that only reads.

The headers every request needs

Authorization: Bearer hm_live_… on every call, and Content-Type: application/json on anything that sends a body. The base URL is https://app.hailmate.ai/api/v1.

Zapier

Trigger: Webhooks by Zapier → Catch Hook

  1. Create a Zap. For the trigger choose Webhooks by Zapier, event Catch Hook, and copy the webhook URL Zapier shows you.
  2. In HailMate, open Settings → Integrations → API & Webhooks, add a webhook, pick the event and any filters, and paste that URL. (Or subscribe it with POST /webhooks.)
  3. Press Send test in HailMate, then Test trigger in Zapier. The record’s fields arrive at the top level of the delivery, ready to map.

Action: Webhooks by Zapier → Custom Request

FieldValue
MethodPOST
URLhttps://app.hailmate.ai/api/v1/jobs
DataThe JSON body, with fields from earlier steps mapped in
HeadersAuthorization → Bearer hm_live_…
Content-Type → application/json
Idempotency-Key → an id from the trigger, e.g. the form submission id

The simpler GET and POST actions work too — for POST, set Payload Type to json. Webhooks by Zapier is one of Zapier’s premium apps, so check that your Zapier plan includes it.

Make

Trigger: Webhooks → Custom webhook

  1. Add a Webhooks module, choose Custom webhook, add a new webhook and copy its address.
  2. Add that address as a webhook in HailMate, as for Zapier.
  3. With the module waiting for data (Redetermine data structure), press Send test in HailMate. Make learns every field from the delivery.

Action: HTTP → Make a request

  • URL https://app.hailmate.ai/api/v1/… and the Method.
  • Headers: Authorization = Bearer hm_live_….
  • Body type Raw, Content type JSON (application/json), and the JSON in Request content.
  • Turn on Parse response so later modules can map the answer’s fields, such as the new job’s id.

n8n

Trigger: Webhook node

  1. Add a Webhook node with HTTP method POST.
  2. Give HailMate the node’s Production URL — the Test URL only answers while the editor is listening — and activate the workflow.
  3. To check signatures, turn on the node’s raw-body option and compare an HMAC-SHA256 of <t>.<raw body> (a Crypto node) with the v1 in X-HailMate-Signature. How signing works.

Action: HTTP Request node

  • Authentication: Generic credential type → Header Auth, with name Authorization and value Bearer hm_live_…. The key is then stored as a credential, not pasted into every node.
  • Send Body on, Body Content Type JSON.
  • For lists, the node’s Pagination option can follow next_cursor for you: send it back as the cursor query parameter until it comes back empty.

Tips that save an afternoon

  • Filter in HailMate, not in the tool. A webhook filter such as {"stage": "Claim Approved"} means the automation only runs when it should — a cleaner run history, and no runs spent on events you throw away.
  • Map fields from a real delivery. Send test in Settings, or GET /webhooks/samples/job.created, shows every field before anything real has happened.
  • Search before you create. GET /contacts/search matches a phone number however it was typed, so a form lead who is already a homeowner in HailMate is found rather than duplicated.
  • Send an Idempotency-Key built from something stable in the trigger, such as the form submission id. When the tool retries a step, HailMate replays the first answer instead of making a second job.
  • Send stages by label. "stage": "Inspection Scheduled" works as well as the key.
  • Appointment times are wall-clock. due_date has no time zone; show it as it is. A formatter step that assumes UTC will shift it by hours.
  • When a step fails, its error names the field that was wrong, and Settings → Integrations → API & Webhooks lists every request a key made, and every delivery, for you to look at.

Recipes

Eight automations roofers ask for. Each works in Zapier, Make or n8n; placeholders like {{email}} stand for a field mapped from an earlier step.

Website form → contact and job, without duplicates

Trigger: a new submission from your website form, a Facebook lead ad or any form tool.

  1. Look them up. GET /contacts/search?email={{email}}&phone={{phone}} tries email, then phone.
  2. Only if data is empty (a Filter, Path or Router step), create them with POST /contacts.
  3. Create the job with the contact’s id from step 1 or 2, and the submission id as the Idempotency-Key, so a retried step never makes a second job.
POST /contacts
{
  "name": "{{name}}",
  "email": "{{email}}",
  "phone": "{{phone}}",
  "address": "{{street}}",
  "city": "{{city}}",
  "state": "{{state}}",
  "postal_code": "{{zip}}"
}
POST /jobs · Idempotency-Key: {{submission_id}}
{
  "name": "{{street}}",
  "address": "{{street}}",
  "city": "{{city}}",
  "state": "{{state}}",
  "postal_code": "{{zip}}",
  "homeowner_id": "{{contact_id}}",
  "lead_source": "Website",
  "notes": "{{message}}"
}

Slack message when a claim is approved

Trigger: job.stage_changed with the filter {"stage": "Claim Approved"} — use your board’s own stage name.

Action: Slack → send a channel message. The delivery already carries the old and new stage and a link to the job:

Message
✅ {{name}} moved from {{previous_stage_label}} to {{stage_label}}
RCV {{rcv_amount}} · {{assigned_to_name}}
{{url}}

A Google Sheets row for every signed estimate

Trigger: estimate.signed

  1. Optional: GET /jobs/{{job_id}} for the address and the homeowner’s name.
  2. Google Sheets → create a row: estimate_number, title, total, selected_tier, signer_name, signed_at, and the job’s address.

total is the package the homeowner chose, computed the way the PDF computes it — the number that belongs in a sales sheet.

Payments into your accounting app

Trigger: payment.received, optionally filtered — e.g. {"payer_type": "insurance"}.

  1. GET /jobs/{{job_id}} for the customer: homeowner.name and the job’s address.
  2. In your accounting app, record the payment: amount, date_received, payment_method, check_number and notes.
  3. Add a second automation on payment.refunded — a refund is its own payment with a negative amount.
Already syncing HailMate to QuickBooks with the built-in connection? Don’t also run this into QuickBooks — the money would be recorded twice.

Text the crew when a build day is booked

Trigger: appointment.created with the filter {"appointment_type": "build_day"}.

  1. GET /jobs/{{job_id}} for the address.
  2. Send the text — your SMS app, or a message in the crew’s chat — with the job’s address and due_date.

due_date is the crew’s local time with no offset (2026-10-02T07:00:00 is 7 AM on site). Format it as it is. To catch reschedules, add task.updated with the same filter and continue only when changed_fields contains due_date.

An “interested” door becomes a lead

Trigger: pin.result_changed with the filter {"knock_result": "interested"} — and pin.created with the same filter, for doors marked interested on the first knock.

Send it wherever your setters work — a dialer, a shared sheet, another CRM — with homeowner_name, phone, email, address, created_by_name (the rep) and map_url. Skip pins whose job_id is already set: that door has been turned into a job in HailMate.

Storm list ready → the mail house

Trigger: storm_list.ready

  1. GET /storm_lists/{{id}}/properties?mailable=true&limit=200, following next_cursor until it is empty (n8n’s pagination option or Make’s repeater do this well).
  2. Send the rows — owner_name, mailing_address, mailing_city, mailing_state, mailing_zip, hail_size_in, hail_event_date — to your mail house, as a sheet or a file.
mail_deliverable is HailMate’s own judgement from the address on file — not a CASS or NCOA result. Run your own address validation before you spend postage.

Tag a new lead with its hail history

Trigger: job.created

  1. GET /hail_history?address={{address}}, {{city}}, {{state}} {{postal_code}} — the same Evidence Grade™ ruling HailMate’s maps and storm reports use.
  2. Write it onto the job’s timeline with POST /notes.
POST /notes
{
  "job_id": "{{id}}",
  "content": "Hail history: {{hail_day_count}} hail days since {{since}}. Largest {{largest_hail_in}} in, most recent {{last_hail_date}}."
}

Hail lookups are limited to 20 a minute per key — plenty for new leads, but pace a bulk backfill of your whole book.