KNOWLEDGE BASE · LEADS DATABASE

How do I query the leads API?

This covers reading leads out of the shared force-pilot-leads database through the internal read endpoint — for one client’s dashboard view or the all-clients internal view.

Backend use only. The READ_API_KEY must never appear in frontend/client-side code. Call this endpoint from your dashboard’s backend, then send only the data the client is allowed to see to their browser.
On this page

— The endpoint

There’s one URL for all reads — it’s the same Worker that Gravity Forms and client sites POST leads into, just called with GET instead.

GET https://leads-api.getforcepilot.com/

This is the live custom domain for the Worker.

— Authentication

Every request needs the read key as a header. This is a separate secret from the one forms use to write leads — ask Chris for the READ_API_KEY value if you don’t have it yet.

x-api-key: <READ_API_KEY>

Store it as an environment variable in whatever backend the dashboard runs on. A missing or wrong key returns 401 unauthorized.

— One client’s leads

For a client-facing dashboard view, pass client as a query parameter. This is the slug used when that client’s leads were inserted — e.g. atlantic-air, kalib.

curl "https://leads-api.getforcepilot.com/?client=atlantic-air&limit=50" \
  -H "x-api-key: <READ_API_KEY>"

This is the call your backend makes right before rendering that specific client’s view — the client never sees this request or the key.

— All clients at once

For the internal dashboard, omit client entirely and every lead across every client comes back, most recent first.

curl "https://leads-api.getforcepilot.com/?limit=200" \
  -H "x-api-key: <READ_API_KEY>"

— Query parameters

paramrequirednotes
clientNoClient slug. Omit to get leads from every client.
sinceNoISO date/time — only leads created on or after this.
untilNoISO date/time — only leads created on or before this.
limitNoMax rows returned. Defaults to 100, capped at 500.

Combine them freely, e.g. one client’s leads from the last 30 days:

?client=atlantic-air&since=2026-07-01&limit=100

— Response format

A successful request returns a JSON object with a results array, newest lead first:

{
  "results": [
    {
      "id": 42,
      "client": "atlantic-air",
      "name": "Jane Doe",
      "email": "jane@example.com",
      "phone": "555-1234",
      "message": "Need a quote",
      "source_page": "https://cool.atlanticairfl.com",
      "utm_source": "google",
      "utm_campaign": "summer-promo",
      "extra_data": "{\"roof_type\":\"shingle\"}",
      "created_at": "2026-07-29 14:02:11"
    }
  ]
}

— Field reference

fieldnotes
clientWhich client site the lead came from.
nameAlways a single combined name, even for sites that collect first/last separately.
source_pageFull URL the form was submitted from, including subdomain — use this to tell a client’s landing page apart from their main site.
extra_dataJSON string of any fields specific to that client’s form. Parse it before reading — it’s not pre-expanded.
created_atUTC timestamp, used for the since/until filters.

— Troubleshooting

Internal reference · force-pilot-leads · ask Chris before changing anything on the Worker itself.