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.
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.
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.
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.
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.
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>"
| param | required | notes |
|---|---|---|
| client | No | Client slug. Omit to get leads from every client. |
| since | No | ISO date/time — only leads created on or after this. |
| until | No | ISO date/time — only leads created on or before this. |
| limit | No | Max 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
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 | notes |
|---|---|
| client | Which client site the lead came from. |
| name | Always a single combined name, even for sites that collect first/last separately. |
| source_page | Full URL the form was submitted from, including subdomain — use this to tell a client’s landing page apart from their main site. |
| extra_data | JSON string of any fields specific to that client’s form. Parse it before reading — it’s not pre-expanded. |
| created_at | UTC timestamp, used for the since/until filters. |
x-api-key header is missing, wrong, or you’re accidentally using the write key instead of READ_API_KEY.results array — check the client slug matches exactly what that site inserts (case-sensitive), or that since/until aren’t excluding everything.GET, not POST.