FieldCamp Webhook Events Catalog: 20 Event Types and Payloads
Reference for every FieldCamp webhook event, including sample payloads, required scopes, and tips for building reliable webhook receivers.
This FieldCamp webhook events catalog documents every event type your endpoint can receive, along with sample payload shapes and the API scope required to subscribe. Use it as a companion to the Webhooks guide when you are wiring up integrations, mapping events to downstream systems, or testing receiver code against realistic payloads. The 20 events cover clients, jobs, visits, invoices, estimates, payments, schedules, and team members — the core entities that drive day-to-day field service operations.
Before subscribing to events, read the Webhooks guide and confirm your API key is set up by following Authentication. The catalog below assumes you already know how to register a subscription and verify HMAC signatures.
How to use this catalog
Every webhook FieldCamp sends follows the same envelope. The catalog below documents the data object for each event type, the resource the event relates to, and the scope you need on your API key to subscribe to it. Pair this reference with your existing receiver to confirm you handle every field your integration depends on.
A typical envelope looks like this:
{
"id": "evt_01HZX9V0Q7K6F3JNYG6Q8E1P2A",
"type": "job.status_changed",
"created_at": "2026-05-29T14:22:31.812Z",
"api_version": "2024-10-01",
"data": {
"object": { /* resource snapshot */ },
"previous_attributes": { /* fields that changed, when applicable */ }
}
}idis the FieldCamp event ID. Also sent in theX-FieldCamp-Delivery-Idheader for deduplication.typeis the event name in the formatresource.action(for example,invoice.paid).data.objectis a snapshot of the resource at the moment the event was emitted.data.previous_attributesonly appears on*.updatedand*.status_changedevents and contains the prior values of the fields that changed.
Store the full event payload alongside any state you derive from it. When you debug a downstream issue, having the original delivery — not just the parsed fields — saves hours.
Required scopes by resource
When you create an API key from Authentication, grant only the scopes you need. The table below lists the minimum scope required to subscribe to each event family.
| Event family | Required scope on API key | Linked resource |
|---|---|---|
client.* | clients:read | Clients |
job.* | jobs:read | Jobs |
visit.* | visits:read | Visits |
invoice.* | invoices:read | Invoices |
estimate.* | estimates:read | Estimates |
payment.* | payments:read | Payments |
schedule.* | jobs:read | Jobs |
team_member.* | team:read | Team |
If your API key is missing the relevant scope, the subscription creation request returns a 403 error and the event is silently skipped. Always test in staging with the same scopes you plan to use in production.
Client events
Client events fire whenever a customer record is created, updated, or deleted in your account. They are the foundation of any CRM sync.
client.created
Fires when a new client is added — manually, via import, or through the API.
{
"type": "client.created",
"data": {
"object": {
"id": "cli_01HZ...",
"first_name": "Jordan",
"last_name": "Reyes",
"company_name": "Reyes HVAC",
"email": "jordan@example.com",
"phone": "+15035551234",
"addresses": [{ "line1": "12 Pine St", "city": "Portland", "region": "OR" }],
"created_at": "2026-05-29T14:22:31.812Z"
}
}
}client.updated
Fires when any field on a client changes. data.previous_attributes lists the fields that were modified.
client.deleted
Fires when a client is permanently removed. The payload contains only the deleted resource's id and the timestamp.
Job events
Job events power most operations integrations — back-office sync, accounting, dispatch dashboards, and notifications.
job.created
Fires when a job is created from a request, an estimate, or directly from the Jobs API.
{
"type": "job.created",
"data": {
"object": {
"id": "job_01HZ...",
"client_id": "cli_01HZ...",
"title": "AC tune-up",
"status": "scheduled",
"scheduled_start": "2026-06-02T15:00:00Z",
"scheduled_end": "2026-06-02T17:00:00Z",
"assignees": ["usr_01HZ..."],
"total": 24900
}
}
}job.updated
Fires when any field on a job changes, including reschedules, assignment changes, and description edits.
job.status_changed
Fires when the job moves between statuses (for example, scheduled → in_progress → completed). Use this when you only care about lifecycle transitions and want to ignore noisy field-level edits.
job.deleted
Fires when a job is removed. The payload contains the job id, the related client_id, and the deletion timestamp.
Invoice events
Invoice events keep accounting systems and customer-facing dashboards in sync with billing changes.
invoice.created
Fires when a new invoice is generated from a completed job, from an estimate, or directly via the API.
invoice.updated
Fires when line items, totals, taxes, or memo fields change on an existing invoice. Use data.previous_attributes to see what changed.
invoice.sent
Fires when an invoice is sent to a client by email. Use this to log outbound communications or to trigger downstream reminder workflows.
invoice.paid
Fires when an invoice is marked as fully paid — either through Stripe, recorded manually, or via the API.
{
"type": "invoice.paid",
"data": {
"object": {
"id": "inv_01HZ...",
"client_id": "cli_01HZ...",
"total": 24900,
"amount_paid": 24900,
"currency": "USD",
"status": "paid",
"paid_at": "2026-05-29T18:11:02.443Z"
}
}
}invoice.overdue
Fires when an invoice passes its due date without being paid in full. Use this to drive collections automations.
Estimate events
Estimate events let you mirror the sales pipeline in external CRMs, BI tools, or notification systems.
estimate.created
Fires when a new estimate is created from a request, manually, or via the API.
estimate.accepted
Fires when a client accepts an estimate (with or without a signature). This is often the trigger to create a downstream job in another system, or to fire a Slack notification.
estimate.declined
Fires when a client declines an estimate. Pair this with your CRM to update opportunity stages or to trigger a follow-up cadence.
Payment events
Payment events keep your books accurate and let you reconcile money movement in near real time.
payment.created
Fires when a new payment is recorded against an invoice — including Stripe charges, manual entries, and applied deposits.
{
"type": "payment.created",
"data": {
"object": {
"id": "pay_01HZ...",
"invoice_id": "inv_01HZ...",
"client_id": "cli_01HZ...",
"amount": 24900,
"currency": "USD",
"method": "card",
"captured_at": "2026-05-29T18:11:02.443Z"
}
}
}payment.refunded
Fires when a payment is refunded in full or partially. Use data.object.refunded_amount to know how much money was returned.
Schedule and visit events
Schedule events keep dispatch boards, technician apps, and external calendars in sync as visits move on the timeline.
visit.created
Fires when a new visit is added to a job — manually on the Dispatch calendar, through AI dispatch, or via the API.
visit.updated
Fires when a visit changes — including reschedules, assignee changes, and status updates. Useful for syncing to external calendars or driving customer-facing arrival ETA notifications.
visit.completed
Fires when a technician marks a visit complete in the mobile app. This is often the trigger for invoice generation in downstream systems.
{
"type": "visit.completed",
"data": {
"object": {
"id": "vis_01HZ...",
"job_id": "job_01HZ...",
"assignees": ["usr_01HZ..."],
"actual_start": "2026-05-29T15:04:11Z",
"actual_end": "2026-05-29T16:38:55Z",
"status": "completed"
}
}
}Team member events
Team member events keep auth, scheduling, and reporting tools in sync as your crew grows or changes.
team_member.created
Fires when a new team member is added to the workspace, either invited from the dashboard or provisioned via the API.
team_member.updated
Fires when a team member's profile, role, skills, or assignment availability changes. Useful for syncing to identity providers, HRIS, or external scheduling tools.
Sample receiver flow
Verify the signature
Use the raw request body and the X-FieldCamp-Signature header as described in Webhooks. Reject any delivery that fails verification.
Look up the handler by type
Switch on event.type to route the payload to the right handler. Group rare events (for example, team_member.*) into a default handler so you log unknown types instead of dropping them.
Deduplicate by delivery ID
Store X-FieldCamp-Delivery-Id (or the event id) in a short-lived cache or DB column. Skip processing if you have seen it before — FieldCamp retries can resend the same event.
Acknowledge fast, process async
Return 200 OK as soon as the event is durably queued. Do the heavier downstream work in a background worker so your endpoint stays well under the FieldCamp delivery timeout.
Make your first authenticated request to FieldCamp before testing webhook deliveries end to end.
Standardized response codes you can rely on when retrying or surfacing failures to operators.
Troubleshooting and FAQs
Which event should I subscribe to for invoice payment automation?
Subscribe to invoice.paid for the moment money is fully collected, and to payment.created for individual payment events (including partial payments). Most accounting integrations subscribe to both and reconcile against the invoice ID.
Do I need separate subscriptions per event family?
No — a single subscription can listen to any combination of the 20 event types. That said, splitting subscriptions by downstream consumer (one for accounting, one for the CRM, one for dispatch) is easier to monitor and re-enable when something breaks.
Why am I seeing job.updated events with no obvious change?
Some background recalculations — total, balance due, status rollups — fire job.updated. Inspect data.previous_attributes to confirm what changed. If it is empty, you can safely ignore the event.
Can I receive webhook events for custom objects or job forms?
Custom object events are not yet part of this catalog. If you need to react to job form submissions, poll the resource on a schedule or react to the related visit.completed event and then fetch the latest form data via the API.
My handler errors out on client.deleted — what is in the payload?
The delete event contains only the id of the removed client and the deleted_at timestamp. The full record is not retrievable through the API afterward, so cache the resource snapshot from client.created / client.updated if you need to log the deleted record's full details.
Related articles
FieldCamp API Webhooks: Subscribe, Sign, and Verify Events
Set up FieldCamp API webhooks at /api/v1/webhooks to receive real-time events, verify HMAC signatures, and replay failed deliveries with confidence.
Clients | FieldCamp API
Use the FieldCamp Clients API to create, search, update, soft-delete, and sync the people and companies you do work for.