A webhook is an automatic message that PaintForce sends to another app the moment something happens in your account. For example, a job changes status, an invoice is created, or a payment is recorded.
You give PaintForce a web address (a URL) and pick the event you care about. From then on, every time that event happens, PaintForce sends the details to that address. Nobody has to export or copy anything.
Webhooks or API: which one do I need?
PaintForce offers two ways to connect with other software. They work in opposite directions:
Webhooks: PaintForce tells your other app when something happens. PaintForce sends the data out automatically, the moment it changes. Nobody has to ask.
API: your other app asks PaintForce for data, or sends data into it. It happens whenever that app decides to make a request.
| Webhooks | API |
Direction | Out of PaintForce | Into PaintForce, or reading from it |
When it runs | Automatically, right after a change | Whenever your other app makes a request |
Good for | "When a job is completed, add it to our website map." "When an invoice is created, copy it to QuickBooks." | "When someone fills out our website form, create a Request in PaintForce." "Pull this month's numbers into our dashboard." |
What you set up | Paste a URL in Settings → Webhooks. No code needed with Zapier or Make. | Create an API key, then a developer (or a Zapier/Make step) makes the requests. |
Data covered | Jobs, estimates, invoices, payments, expenses, contacts, requests | Contacts, requests, notes, calendar events, reports |
Many integrations use both. For example, a webhook tells your system that a job changed, and the API adds a note back to that job.
This article covers webhooks. For the API, see Using the PaintForce API.
This guide is for everyone: office managers setting up a connection and developers building one. The technical details (the exact data PaintForce sends for each event) are in the companion article, Webhook Reference: Events and Data Format.
What can I use webhooks for?
Connect to hundreds of apps through Zapier or Make. Send new customers to your CRM, create invoices in QuickBooks Online, add rows to Google Sheets or Airtable, or post a Slack message when a job is sold. No coding needed.
Update your website automatically. For example, show a "recent projects" map that adds a pin whenever a job is completed.
Feed your own software. If you have a developer, they can receive PaintForce data directly and use it however you need.
Is a webhook the right tool?
Webhooks are best for "when X happens, do Y right away". If you only need a list of records now and then (for example, all jobs completed in the last 12 months), use the Reports screen and export the list instead. It's simpler and doesn't need anything running on the other end.
Webhooks only send events that happen after you turn them on. They don't send your past records. If you need history too, export it from Reports once, then let the webhook handle new activity from then on.
Before you start
You need to be an Owner or Admin in PaintForce.
Use PaintForce on the web (in a browser on your computer). The Webhooks setting doesn't appear in the mobile app.
You need the URL to send data to. In Zapier this is the "Catch Hook" URL from a Webhooks by Zapier trigger. If a developer or web agency is building the connection, they will give you the URL.
How to set up a webhook
Log in to PaintForce in your web browser.
Go to Settings → Webhooks.
Click Edit in the top right corner.
Click + Add Webhook. A new row appears.
Fill in the row:
Label: a name just for you, like "New customers to QuickBooks".
URL: paste the address you were given (it usually starts with
https://).Action: the event that should send data, like Job Updated (see the list below).
Turn the switch on (ON/OFF column). New webhooks start switched off, so this step is easy to miss.
Click Save.
Each row sends one event to one URL. To send several events, add a row for each. You can use the same URL on several rows, or send one event to several URLs.
To pause a webhook, turn its switch off and click Save. To remove one, click Edit, then the red minus icon next to the row, then Save.
Test it
After saving, do something in PaintForce that matches the event. For Job Updated, open a test job and change its status. The data usually arrives within a few seconds. If you're using Zapier, make the change first, then click Test trigger in Zapier to pull in the sample.
Events you can choose
Action in PaintForce | Sends when… |
Job Created | A new job is created. |
Job Updated | Anything on a job changes: status, dates, assigned people, totals, custom fields, and more. This also fires when PaintForce recalculates a job's totals, for example after you add an expense or record a payment. |
Job Deleted | A job is deleted. |
Contact Created / Updated / Deleted | A customer contact is added, edited (including archived), or deleted. |
Estimate Created / Updated / Deleted | An estimate is created, changed, or deleted. "Updated" includes the customer signing the estimate and payments recorded on it. |
Invoice Created / Updated / Deleted | An invoice is created, changed, or deleted. "Updated" includes payments being recorded. |
Payment Created / Updated / Deleted | A payment is added to, changed on, or removed from an invoice or estimate. This includes online card and bank payments made through Stripe. |
Expense Created / Updated / Deleted | A labor or materials expense is logged on a job, edited, or deleted. |
Request Created / Updated / Deleted | A customer request (lead) is created, edited, or deleted. |
Important things to know
"Updated" events are sent often
PaintForce sends an "Updated" webhook every time the record is saved, even for small changes. One action in PaintForce can send several webhooks. For example, logging one expense recalculates the job, which can send two Job Updated webhooks.
So the receiving side should look at the data and decide what to do. It shouldn't treat every message as something new. Two tips:
Filter. For example, "only continue if the job's stage is Complete". In Zapier, add a Filter step.
Update instead of duplicating. Use the record's
idto find and update an existing record in the other app, so you don't create a new one every time.
The data format is fixed
PaintForce always sends its standard format. You can't choose which fields are included or rename them. If the receiving app needs different field names, Zapier (or your developer) can map or reshape them.
Use the job's stage, not its status name
Every company names its job statuses differently ("Paid & Closed", "Done", "Completed"…). Each status is linked to one of seven fixed stages, which you can see in Settings → Job Statuses: Lead, Estimating, Sold, Lost, In Production, Accounts Receivable and Complete.
Every Job Updated webhook includes the current status with its stage (status.relatedStage), so filtering on the stage keeps working even if you rename or add statuses later.
Keep your webhook URL private
PaintForce webhooks don't use a password, sign-in or signature. The URL must be reachable on the public internet, and anyone who knows it could send data to it. Treat it like a password:
Don't share it publicly.
If you have a developer, ask them to add a long random secret to the URL (for example
https://yoursite.com/paintforce-hook?key=8f3k2...) and reject any request that doesn't include it. Zapier Catch Hook URLs already contain a unique code.
Each webhook is sent once
PaintForce makes one delivery attempt per event. If the receiving app is down or returns an error at that moment, that message isn't sent again. For important records, it's a good idea to occasionally compare against a Reports export to catch anything missed.
Example: show completed jobs on your website map
A common request: add a pin to a "recent projects" map on your website whenever a job is finished. Here's how to set it up:
In PaintForce, add a webhook with the Action Job Updated and the URL your web developer gives you. Switch it on and save.
Your developer's code checks each message and only keeps jobs where
status.relatedStageis"complete".They use the job's
idso the same job is never added twice, even though it will keep sending updates (for example when the final payment is recorded).The address is in
customerContact.address, and the completion date is indateCompleted. PaintForce fills it in automatically the first time a job moves to a Complete-stage status.To show past projects on day one, export your completed jobs from Reports once and load that list into the map.
Troubleshooting
Nothing arrives. Check that the row's switch is on and that you clicked Save. Also check that you picked the right Action and that the URL is complete and public (it can't be a page that needs a login).
I don't see Webhooks in Settings. Open PaintForce in a web browser and make sure you're logged in as an Owner or Admin.
A field is empty. If a field isn't filled in PaintForce, it's sent empty (blank text,
null, or an empty list). For example,dateCompletedstays empty until the job reaches a Complete-stage status.Too many messages. That's normal for "Updated" events. Add a filter on the receiving side (see above).
For developers
For the request format, delivery behavior, and every field with real example payloads, see Webhook Reference: Events and Data Format.