The API page
Everything about the API lives on one page: sidebar → Settings → API. It holds the API keys manager and the endpoint documentation, including ready-to-paste cURL and JavaScript examples. The page requires the "Manage API keys" permission, which owners and admins have. There's also a "Lead API" button at the top of the Leads page that jumps straight there.
The API has three endpoints: Create Lead (write), and two read-only lists, List open invoices and List customers. It cannot create or change customers, jobs, or invoices, and there are no webhooks. If you need an endpoint that doesn't exist, contact support at support@poolfounder.com and we'll log the request.
Create an API key

- 1On the API keys card, click Create key.
- 2Name the key after where it'll be used (e.g. "Zapier"), then click Create key.
- 3The next screen shows the full key (it starts with pf_live_) with a Copy button. This is the only time it's shown — copy it now. It cannot be recovered later, only revoked and replaced.
- The keys table lists each key's name, fingerprint (like pf_live_ab…cd12), created date, and last-used date.
- Revoke (with a confirm dialog) kills a key immediately and permanently — requests using it stop working on the spot.
Authentication
- Base URL: https://api.poolfounder.com.
- Send the key as an Authorization: Bearer pf_live_... header on every request.
- The Authentication card on the API page shows the base URL, your Company ID (the <code>companyId</code> the website form endpoint needs), and the OpenAPI spec URL, each with a Copy button.
API keys are secrets. They're fine in Zapier and in server-side code — never in a public website's JavaScript, where anyone could read them. Public website contact forms use a separate form endpoint (POST /api/website-lead with your companyId in the body) precisely because a secret key can't live in public website code.
The Create Lead endpoint
The one write endpoint is Create Lead: POST /api/v1/leads. Its card on the API page includes cURL and JavaScript examples, a field reference table, and response codes (200 / 400 / 401 / 429).
| Field | Required? | Notes |
|---|---|---|
| name | Required | The lead's name |
| At least one of email or phone | Send both when available | |
| phone | At least one of email or phone | Send both when available |
| address | Optional | Geocoded automatically |
| service | Optional | What they're asking for |
| message | Optional | Free-text message |
| source | Optional | Where the lead came from |
| sourcePage | Optional | The page it was submitted from |
| bodiesOfWater | Optional | Array of the property's pools/spas (type required; gallonage, sanitizer, surface optional) — sharpens the chemical estimate and carries onto the customer at conversion |
| category | Optional | One of your lead categories (Settings → Lead Categories), by name ignoring case or by slug: "Waitlist", "waitlist" and "summer-startups" for "Summer Startups" all match. A category you don't have, or one you archived, is ignored and the lead still saves with no category. The response's <code>category</code> says where it landed (null for none). |
| tags | Optional | Array of free-form labels shown on the lead page, e.g. ["pool-opening", "zip-34102"]. Up to 20, 50 characters each; repeats and non-text items are dropped, never rejected. |
| smsConsent | Optional | Boolean. Send true only when the prospect ticked a box agreeing to be texted. It is what allows automated text follow-ups to this lead; without it the lead is followed up by email only — a lead who never asked for texts is never texted. Leads who called or texted you first are always textable and don't need it. The public form endpoint (POST /api/website-lead) accepts the same field, and rejects a non-boolean with a 400. Defaults to false. |
| suppressAutoReply | Optional | Boolean. Set to true to skip the automatic branded first reply to this prospect (the new-lead admin notification still fires). Use it when you've already replied to them yourself — for example an automation that adds someone who already texted you — so they don't get a duplicate first response. Defaults to false. |
When a lead arrives through the API, it appears in the Leads inbox instantly with the Website channel badge, triggers the standard new-lead admin notification, and sends the automatic branded first reply to the prospect — unless you set suppressAutoReply: true, which skips only that customer reply and leaves the admin notification untouched.
The public form endpoint, POST /api/website-lead, accepts category and tags the same way. Neither field can make a lead fail: whatever doesn't match is dropped and the lead comes in.
Rate limit: 30 accepted leads per hour per company. The API is for a live trickle of leads, not bulk loads — to bring in a whole book of contacts, use the CSV customer import instead.
smsConsent: collecting permission to text a lead
Pool Founder can text leads who go quiet — the Lead follow-up automation on Messages → Phone → Automated texts (see Leads). A lead who called or texted you is always eligible. A lead that arrives through a form or the API is only textable if you tell us they agreed, with smsConsent: true. Without it that lead is followed up by email only.
- Both endpoints accept it: POST /api/v1/leads (API key) and POST /api/website-lead (the public form endpoint, with your companyId in the body).
- Only an explicit boolean <code>true</code> counts. A string <code>"true"</code> is rejected with a 400 — Field "smsConsent" must be true or false — deliberately, so a form that looks like it is collecting consent can't silently be collecting nothing.
- Recommended checkbox wording next to the box on your form: "Text me about my request. Msg & data rates may apply. Reply STOP to opt out."
- For your own contact form, you build it and post it to the endpoint, which is why the consent checkbox and its wording are yours to add. If you would rather not build one, the Sign-up Page (Settings → Sign-up Page) is a ready-made Pool Founder form with the checkbox built in, which you can link to or embed with an iframe.
Read open invoices and customers
Two read-only endpoints let another tool (GoHighLevel, a spreadsheet, your own script) pull data out with the same API key. The API page documents both with examples. Every /api/v1 endpoint, Create Lead included, requires a key: a request without one is refused. A public website form that has no key posts to /api/website-lead with your companyId instead.
| Endpoint | What it returns |
|---|---|
| GET /api/v1/invoices | Every open invoice: number, amount due and total (in cents), due date, payUrl (the invoice's pay page, same as Copy Payment Link), paymentProcessing (a bank payment is clearing), awaitingBankVerification (the customer started a bank payment but still has to confirm the test deposit; the pay link opens that step), and the name, email, and phone of whoever pays it (the parent, for a child account). |
| GET /api/v1/customers | Every active customer: name, email, phone, serviceDays (maintenance days, e.g. Tuesday), and schedule (route, technician, frequency). Suspended or archived jobs, archived routes, and work orders don't count. |
- Pages hold up to 200 (?limit=, default 100). While nextCursor is not null, ask again with ?cursor= set to it.
- Paid or voided invoices drop off the open list. To keep an invoice-link field current elsewhere, re-pull on a schedule and clear it for anyone no longer listed.
- Texts sent from another tool come from that tool's number and don't appear in Pool Founder's Phone inbox.
OpenAPI spec
The API page links a machine-readable OpenAPI spec at https://api.poolfounder.com/api/openapi.json, ready to import into Postman or Zapier.
What the API does not cover (yet)
- Only the three endpoints above exist. The API cannot create, edit, or delete customers, jobs, invoices, or routes, and cannot record a payment. There is no endpoint for jobs, visit history, quotes, or paid invoices.
- There are no webhooks: Pool Founder does not push events (like "invoice paid") to your system. Poll the read endpoints instead.
- Besides the API, Pool Founder's integrations are Stripe (payments) and QuickBooks Online — there are no others today.
- For anything you'd like the API to do, contact support at support@poolfounder.com.
Frequently asked questions
Can a lead from my website or Zapier land straight in a category like my waitlist?
Yes. Create the category first on Settings → Lead Categories, then send "category": "Waitlist" with the lead (POST /api/v1/leads or POST /api/website-lead). It matches the name ignoring case, or its slug ("summer-startups"). If no active category matches, the lead still saves, just with no category, and the v1 response says "category": null.
I lost my API key — can I see it again?
No. The full key is shown exactly once, at creation. If it's lost, revoke it and create a new one — the table only ever shows the fingerprint (like pf_live_ab…cd12).
Can I put my API key in my website's contact form?
No — keys are secrets and must never appear in a public website's JavaScript. Public website contact forms use the separate form endpoint (POST /api/website-lead with your companyId in the body) instead. Keys belong in Zapier and server-side code.
Where do I find my Company ID (companyId)?
Settings → API, on the Authentication card: Company ID, with a Copy button. It is the companyId your website form sends to POST /api/website-lead. Requests with an API key don't need it.
Can I bulk-import contacts through the API?
No — the Create Lead endpoint accepts up to 30 leads per hour per company. For bulk imports, use the CSV customer import instead.
Can I stop the automatic first reply to a lead I push through the API?
Yes. Send "suppressAutoReply": true in the POST /api/v1/leads body and the automatic branded first reply (email or text) is skipped for that lead. You still get the new-lead admin notification and the lead still lands in your inbox. It's meant for cases where you've already replied out-of-band — like an automation that adds someone who already texted you — so they don't get a duplicate first response.
How do I let Pool Founder text the leads that come in from my website?
Add a texting-consent checkbox to your own form and post "smsConsent": true with the lead (both POST /api/v1/leads and POST /api/website-lead accept it). Only an explicit boolean true counts — the string "true" is rejected with a 400. Without it the lead is followed up by email only; a lead who never asked for texts is never texted. Leads who called or texted you first are always textable and need nothing. Recommended wording next to the box: "Text me about my request. Msg & data rates may apply. Reply STOP to opt out." On your own form the checkbox is yours to add; the ready-made Sign-up Page (Settings → Sign-up Page) already has it.
Is there an API for customers, jobs, or invoices?
Read-only, yes: GET /api/v1/invoices lists your open invoices with their pay links, and GET /api/v1/customers lists active customers with their contact details and route days. There is nothing to create or edit customers, jobs, or invoices, and no endpoint for jobs on their own. Contact support at support@poolfounder.com to request more.
Can I send invoice links or route-change texts from GoHighLevel (or another texting tool) instead of Pool Founder?
Yes. Pull GET /api/v1/invoices (each open invoice's payUrl and payer phone) and GET /api/v1/customers (each customer's serviceDays), store them on the contact, and text from that tool. Re-pull on a schedule, since paid invoices drop off the open list.