FieldCamp

FieldCamp API Reference | FieldCamp

Build with the FieldCamp API reference — fc_live keys, JSON endpoints, pagination and filters, outbound webhooks, and resources for clients, jobs, visits and invoices.

The FieldCamp API reference is the entry point for every integration that creates clients, schedules jobs, manages visits, or syncs data with your booking site, CRM, or ERP. Whether you're pushing leads from a marketing form, dispatching work from a third-party scheduler, or pulling invoices into accounting, this is where you start. The current v1 surface uses self-serve fc_live_ API keys, JSON request bodies, and outbound webhooks, so your stack stays in sync without polling. Every resource page here ends with a live request builder generated from the API's own OpenAPI spec.

The FieldCamp v1 API is generally available. If you are migrating from a support-issued JWT or legacy POST /api/jobs flow, the API changelog captures every breaking change you need to handle.

The basics

  • Base URL: https://api.fieldcamp.ai
  • API version: all current endpoints live under /api/v1/.... The legacy /api/... paths are kept only for backward compatibility and do not support the v1 filters — for example GET /api/jobs (no v1) ignores since, so a delta pull silently becomes a full, unfiltered list. Always use the /api/v1/... path. To pull only what changed, see Incremental sync.
  • Authentication: self-serve fc_live_ API keys created from Settings → Developer → API Keys, sent as Authorization: Bearer <key>. See Authentication and the API keys resource for the full key lifecycle.
  • Content type: request and response bodies are JSON (Content-Type: application/json). Multipart is only used for file uploads on legacy job-creation routes.
  • Webhooks: FieldCamp emits signed outbound events for clients, jobs, visits, invoices, and more — see Webhooks to subscribe and verify signatures, and the webhook events catalog for every payload shape.
  • Rate limits: per-key limits with X-RateLimit-* headers. Tune your retries using the guidance in Rate limits.
  • Interactive docs: every resource page on this site carries a live request builder generated from the OpenAPI spec — see Jobs for an example. There is no separately hosted Swagger UI on production.

Try requests from these docs

Every resource page on this site ends with a live request builder generated from the FieldCamp OpenAPI spec — the same spec the API is built from. Open Jobs, scroll to Endpoints, paste your fc_live_ key, edit the body, and send the request from the page.

There is no separate Swagger UI on production

Earlier versions of this page pointed at https://api.fieldcamp.ai/api/api-doc. That URL is not served — the standalone Swagger UI runs on internal environments only. The request builders on these resource pages are the supported way to try the API.

Working with the OpenAPI 3 spec

The spec for the public API — every /api/v1/... endpoint — is generated from the API build, so it does not drift from what the server actually serves. Common uses:

  • Generate a client SDK with openapi-generator or oapi-codegen — TypeScript, Python, Go, Java, and more are supported.
  • Import into Postman or Insomnia to get a pre-built collection with every endpoint, schema, and example.
  • Mock the API locally with Prism so you can build against the spec while you wait on credentials.
  • Pin a version in CI by checking the spec into your repo and diffing it on each release to catch breaking changes early.
# Generate a TypeScript client from the spec
npx @openapitools/openapi-generator-cli generate \
  -i fieldcamp-openapi.yaml \
  -g typescript-fetch \
  -o ./fieldcamp-client

Need the spec as a file?

Ask us and we will send you the current spec. A public download URL is on the roadmap and is not live yet, so a bookmarked link to api.fieldcamp.ai/api/api-doc/spec will not resolve.

Treat the OpenAPI spec as the contract. If something in the prose docs disagrees with the spec, the spec wins — and it's the artifact our server actually validates against. File an issue in the API changelog if you spot a drift.

Authentication at a glance

Every request needs a valid fc_live_ key on the Authorization header. Keys are scoped, optionally time-bound, and bound to your tenant so you can issue narrow keys per integration and rotate them without downtime. For the full key lifecycle — create, scope, rotate, revoke — see Managing API keys.

curl "https://api.fieldcamp.ai/api/v1/clients?limit=1" \
  -H "Authorization: Bearer $FIELDCAMP_API_KEY"

Create a separate key for each integration (Zapier, internal BI, partner portal) so you can rotate or revoke one without breaking the others. Manage them under the same admin permissions described in Roles and permissions.

Object model

A typical integration flow:

  1. Create or upsert a client with POST /api/v1/clients (or look one up by email first).
  2. Create the products and services you'll bill. There is no /api/v1/items endpoint — the price book lives on /api/product-service, which authenticates with a signed-in session rather than an API key, so this step is done in the app today.
  3. Create a job with POST /api/v1/jobs (JSON body) pointing at the client, items, and team.
  4. Create or accept auto-generated visits with POST /api/v1/visits for each on-site appearance.
  5. Subscribe to webhooks so your system reacts when statuses change instead of polling.

If you're new to how these objects come together in real workflows, the FieldCamp workflow from lead to payment explains the full lifecycle from a customer request to a paid invoice. For a hands-on walk-through with copy-paste snippets, jump straight into the Quickstart.

Make your first call

Create an fc_live key

Open Settings → Developer → API Keys, click Create key, pick the scopes you need (start with clients:read, jobs:read, jobs:write), and copy the fc_live_... secret once. Save it in your secrets manager. The API keys resource covers programmatic creation too.

Verify the key

Call a read endpoint that your key is scoped for and check you get a 200:

curl -s "https://api.fieldcamp.ai/api/v1/clients?limit=1" \
  -H "Authorization: Bearer fc_live_..."

A 200 with {"success": true, "data": [...], "meta": {...}} confirms the key is valid for that environment. A 401 means the key is wrong or revoked; a 403 means the key is missing the scope for that endpoint.

Create a test client

POST /api/v1/clients with a JSON body containing name, email, and phone. Save the returned id — you'll reuse it on every job.

Schedule a job

POST /api/v1/jobs with the client id, a startsAt and endsAt in UTC ISO-8601, a unique jobNumber, and optional items. See Idempotency for safe retries.

Subscribe to webhooks

POST /api/v1/webhooks with a url and events array. FieldCamp signs every delivery with HMAC-SHA256 so you can verify authenticity before processing.

Things to know before you build

Four things that catch most first-time integrators:

  1. Use the v1 surface. POST /api/v1/jobs takes a JSON body. The legacy POST /api/jobs route with multipart/form-data is kept only for older booking widgets and should not be used for new builds.
  2. Bearer keys, not JWTs. Use a self-serve fc_live_ key on the Authorization header. Support-issued JWTs still work for older accounts but are deprecated for new integrations.
  3. All datetimes are UTC ISO-8601. The job's timezone field is only a display hint for the UI — never use it to offset the timestamps you send.
  4. jobNumber is client-generated and must be unique. Treat it as your idempotency key. See Idempotency.

Webhooks vs. polling

Webhooks are the recommended way to stay in sync. FieldCamp emits events in the resource.action format — for example job.created, job.status_changed, visit.completed, invoice.paid, and form.submitted. Each delivery includes a timestamp, a signature header, and a JSON payload that mirrors the resource shape from the matching endpoint. The complete list of event names, scopes, and sample payloads lives in the webhook events catalog.

If you cannot accept inbound HTTPS (for example, you only run scheduled batch jobs), the API still supports list endpoints with updatedSince filters so you can poll efficiently. Most production integrations use webhooks for low-latency updates and a nightly poll as a safety net. If you also need calendar or accounting freshness, the integrations resource exposes Google Calendar, Outlook, and QuickBooks sync triggers from the same API surface.

Errors, retries, and idempotency

Every error response uses the same envelope: a code, a human-readable message, optional details, and a requestId you can quote to support. HTTP 429 responses include a Retry-After header — respect it and apply jitter.

For state-changing endpoints, treat your own request IDs as idempotency keys:

  • Jobs: the jobNumber field is your idempotency key. Sending the same jobNumber twice returns the existing job instead of creating a duplicate.
  • Clients: pass an externalId you generate so a retried upsert returns the same client.
  • Webhooks: every event includes an id. Store it and deduplicate on your side.

Full details, retryable status codes, and code samples live in Errors and Idempotency.

Start here

Resource reference

The resource pages document every field, request shape, response shape, and error code for the objects you'll touch most often. Each page is generated from the API's own OpenAPI spec, so the prose and the request builder on the page always agree with what the server accepts.

Troubleshooting

Where is the interactive Swagger UI hosted?

There is no separately hosted Swagger UI on production. The standalone UI runs on internal environments only. To explore or try requests, use the request builder at the bottom of any resource page on this site — for example Jobs → Endpoints. If you had bookmarked https://api.fieldcamp.ai/api/api-doc, that URL does not resolve.

How do I download the OpenAPI 3 spec?

Ask us and we will send you the current spec for the public /api/v1/... surface. A public download URL is on the roadmap and is not live yet — https://api.fieldcamp.ai/api/api-doc/spec returns 404. The spec is generated from the API build, so the copy you receive matches what the server serves.

Why does my JWT from FieldCamp support still work but feel "second-class"?

Support-issued JWTs continue to authenticate against the v1 API for accounts that received one. They lack the scope granularity and self-serve rotation of fc_live_ keys, which is why every new integration — and every key rotation on an old one — should move to self-serve keys from Settings → Developer → API Keys. The API keys resource explains how to scope and rotate them.

I'm getting 415 Unsupported Media Type on POST /api/v1/jobs. What's wrong?

You are almost certainly sending multipart/form-data from a legacy POST /api/jobs snippet. The v1 endpoint expects Content-Type: application/json with a JSON body. Update your client and re-send — or use the request builder on the Jobs page to confirm the working request shape, then port that back to your code.

Why isn't my webhook firing?

Check three things in order: the subscription is active on GET /api/v1/webhooks, the event type you expect is in the events array, and your endpoint returned a 2xx to recent deliveries. FieldCamp pauses subscriptions that fail too many deliveries in a row — see Webhooks for the exact retry policy and the webhook events catalog to confirm the event name.

How do I avoid duplicate jobs when my system retries?

Always send a unique, deterministic jobNumber per real-world job. A retried request with the same jobNumber returns the existing job (HTTP 200) instead of creating a new one (HTTP 201). Full pattern in Idempotency.

Where do I see what changed between API versions?

The API changelog captures every endpoint addition, field rename, and deprecation. Subscribe to its RSS feed or diff the generated OpenAPI spec between releases for a machine-readable view.

On this page