Getting started

Setup & verification

Connect your key, confirm your scope, and make a couple of test requests before you wire anything up.

1. Receive your API key

Your integration contact will provide an API key (e.g. fi_pk_live_…) and the gateway hostname. Treat the key like a password — store it in a secret manager, never in source control. If a key is ever leaked, contact us and we’ll rotate it with a grace window so your integration doesn’t break.

2. Confirm authentication

Every request must include a Authorization: Bearer fi_pk_… header. The simplest way to confirm the key works is to fetch your customers:

curl -sS -H "Authorization: Bearer fi_pk_…" \
  https://<host>/v1/customers
Expected response
HTTP 200, your tenant’s customer(s).
{ "items": [{ "id": "245715", "name": "Acme Holdings" }] }

If you see 401 unauthorized, the key is wrong, missing, or doesn’t have the scope this endpoint needs.If you see 403 no-scope, the key is valid but no customers have been assigned yet — contact us so we can finish setting it up.

3. Discover the IDs you need

Sites, projects, job types and statuses are identified by numeric IDs. The lookup endpoints exist so you can resolve them once during setup and cache the results. See Lookups for the full list. At minimum, before creating a job you’ll want:

  • /v1/sites — which site is the job for
  • /v1/job-types — what kind of work
  • /v1/custom-fields — what custom fields you’re allowed to send

If the site you need doesn’t exist yet, you can add it with POST /v1/sites (requires the sites:write scope). You cannot create a site as a side-effect of POST /v1/jobs — create the site first, then reference its ID on the job.

4. Try a read

Pull the open jobs already in your scope. An empty list is fine — it means the key works and there’s simply nothing open yet.

curl -sS -H "Authorization: Bearer fi_pk_…" \
  "https://<host>/v1/jobs?state=open&page_size=5"

5. Try a write

Use a real site ID + job type from step 3. The start_time and end_time are your preferred window — the scheduling team confirms the actual time.

curl -sS -X POST -H "Authorization: Bearer fi_pk_…" \
  -H "Content-Type: application/json" \
  -d '{
    "site": "3065756",
    "job_type": "29400",
    "title": "Integration check",
    "start_time": "2026-07-01T09:00:00+10:00",
    "end_time":   "2026-07-01T11:00:00+10:00",
    "notes": "Created during initial integration."
  }' \
  https://<host>/v1/jobs
Expected response
HTTP 201, the new job’s ID and number.
{ "id": "21172159", "number": "16" }

6. Wire it in

A few habits make the integration easier to operate later:

  • Cache the lookup results (sites, job types, custom fields). See Rate limits for the budget.
  • Log the X-Request-Id from each response next to your own request ID — it’s a quick way to pivot between logs if something needs investigating.
  • For ongoing sync, pass updated_at_from to GET /v1/jobs so you only pull what changed.

Jump to the full reference starting at List jobs.