FieldCamp

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 */ }
  }
}
  • id is the FieldCamp event ID. Also sent in the X-FieldCamp-Delivery-Id header for deduplication.
  • type is the event name in the format resource.action (for example, invoice.paid).
  • data.object is a snapshot of the resource at the moment the event was emitted.
  • data.previous_attributes only appears on *.updated and *.status_changed events 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 familyRequired scope on API keyLinked resource
client.*clients:readClients
job.*jobs:readJobs
visit.*visits:readVisits
invoice.*invoices:readInvoices
estimate.*estimates:readEstimates
payment.*payments:readPayments
schedule.*jobs:readJobs
team_member.*team:readTeam

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, scheduledin_progresscompleted). 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.

Reconcile with the API

On every *.updated event, optionally fetch the resource through the matching API resource — Clients, Jobs, or Visits — so you always operate on the freshest state, not just the snapshot at the moment of delivery.

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.

On this page