FieldCamp

FieldCamp API Reference | FieldCamp

Build with the FieldCamp API reference — Swagger UI, OpenAPI spec, fc_live keys, JSON endpoints, webhooks, and resources for clients, jobs, and visits.

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 — and ships with an interactive Swagger UI and a downloadable OpenAPI 3 spec so your stack stays in sync without polling.

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.
  • 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: the live Swagger UI is published at https://api.fieldcamp.ai/api/api-doc and the raw OpenAPI 3 spec is served at https://api.fieldcamp.ai/api/api-doc/spec.

Interactive Swagger UI and OpenAPI spec

Every release of the FieldCamp API ships with a hosted Swagger UI and a downloadable OpenAPI 3 specification. They are the single source of truth for endpoint shapes, request schemas, and response codes — even the resource pages on this site are generated from the same spec.

What you can do in the Swagger UI

Open the live docs

Go to https://api.fieldcamp.ai/api/api-doc. You'll land on a full list of every /api/v1/... endpoint, grouped by resource (clients, jobs, visits, items, team, taxes, job forms, webhooks, company info).

Authorize once

Click Authorize, paste your fc_live_ key, and Swagger will attach the Authorization: Bearer <key> header to every subsequent Try it out call for the session. No code required.

Try a request

Expand any endpoint, click Try it out, edit the JSON body or path parameters, and hit Execute. Swagger shows the exact curl command, the request URL, response headers, response body, and HTTP status — handy for debugging webhook payload shapes or rate-limit headers.

Copy the curl

The generated curl snippet is the same one you can paste into a terminal or a CI job. It already includes the right Content-Type and Authorization headers.

Working with the OpenAPI 3 spec

The spec endpoint at /api/api-doc/spec returns the full OpenAPI 3 document as JSON. 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.
# Download the live spec
curl https://api.fieldcamp.ai/api/api-doc/spec -o fieldcamp-openapi.json

# Generate a TypeScript client
npx @openapitools/openapi-generator-cli generate \
  -i fieldcamp-openapi.json \
  -g typescript-fetch \
  -o ./fieldcamp-client

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/company-info \
  -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 items you'll bill with POST /api/v1/items — one-time setup; reuse IDs after that.
  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 in Swagger UI

Open https://api.fieldcamp.ai/api/api-doc, click Authorize, paste your key, then expand GET /api/v1/company-info and click Try it out → Execute. A 200 response with your tenant's company name confirms you are authenticated against the right environment — no local setup required.

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 same OpenAPI 3 spec the Swagger UI loads, so the prose and the live request explorer always agree.

Troubleshooting

Where is the interactive Swagger UI hosted?

The live FieldCamp Swagger UI is at https://api.fieldcamp.ai/api/api-doc. It's served by the same backend that powers the API, so the schemas are always up to date with what production accepts. You can authorize once with your fc_live_ key and execute requests directly from the browser — handy for debugging without spinning up a local environment.

How do I download the OpenAPI 3 spec?

GET https://api.fieldcamp.ai/api/api-doc/spec returns the full OpenAPI 3 JSON document. There's no authentication required to fetch the spec itself — only the actual /api/v1/... endpoints need an fc_live_ key. Pipe the output into a file and use it to generate clients, import into Postman, or feed into a contract-test tool in CI.

Can I rely on the Swagger UI for production traffic?

No. The Swagger UI is for exploration, debugging, and one-off requests. Production integrations should call the JSON endpoints directly from your server, with retries, idempotency, and structured logging in place. Treat Swagger like a REPL for the API, not a runtime.

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 Swagger UI's Try it out 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 OpenAPI spec at /api/api-doc/spec between releases for a machine-readable view.

On this page