FieldStacker API · webhooks · every paid plan

Connect FieldStacker to anything: your CRM, your website, your own code

Your FieldStacker account has a REST API and webhooks. Send new leads, appointments, approvals and payments to the tools you already use, and pull your customers, appointments, estimates, invoices and price list into your own systems. It is for your own business’s systems, and it comes with every paid plan, from the $15/mo Website & Hosting plan up, and during your free trial.

Needs a FieldStacker account · business owner only · no extra charge

In short: the FieldStacker API connects your FieldStacker account to your other systems. Tools that can call a REST API or catch a webhook, like Zapier, Make, n8n or a Google Sheet script, work with it, and so does code your own developer writes. You need a FieldStacker account to get a key, and each key belongs to one business.

Most small businesses end up with their customers in two or three places: the app they sell and schedule with, a CRM or email tool, and a spreadsheet the bookkeeper uses. The API keeps those in step without anyone retyping. A few things owners use it for:

  • Add every new lead and website form lead to the CRM or email list you already use.
  • Copy paid invoices into a sheet for your bookkeeper, or into your own reporting.
  • Show your price list or open booking times on a website you built yourself.
  • Create leads and customers in FieldStacker from your own forms, ads or call tracking.

What you can connect

Each part follows your plan: if a screen is not in your plan in the app, its endpoint answers with a clear “not in your plan” message.

📍

Leads

Read new leads, add leads from your own forms or ads, and change a lead’s status or notes.

👤

Customers

Search, read, add and update customers, the same list you see in the app. Needs a plan with Customers.

📅

Bookings

Read appointments and online bookings, see open times, book, move or cancel, using your own booking rules.

🧾

Estimates & invoices

Read them with their lines, totals, status and amount paid. Needs a plan with estimates and invoicing.

🏷️

Price list

Your services and equipment with their prices. Never your costs.

📨

Form leads & webhooks

Website and landing-page form leads to read, and instant webhooks when a lead, sale, approval or payment happens.

Getting your key

  1. Start free or sign in to FieldStacker. The API needs a FieldStacker account in good standing.
  2. As the business owner, open Settings → API & webhooks.
  3. Read and accept the API Terms, then choose Generate API key.
  4. Copy the key straight away. It starts with fsk_ and is shown once; FieldStacker keeps only a fingerprint of it. Generating a new key turns the old one off.
  5. Put it in your tool or your code as the header Authorization: Bearer fsk_…. Keep it secret, like a password.
For your own business only. The API is for connecting your own FieldStacker account to your own systems. A developer or contractor you hire may build that connection for you, with your key, for your business only. Building an app, plugin or service that other businesses use with FieldStacker, or using the API for other FieldStacker accounts, is not allowed. See the API Terms.

The basics

Base URLhttps://www.fieldstacker.com/app/api.php?route=v1/… (the route is in the query string; add other parameters with &)
AuthAuthorization: Bearer fsk_… or X-API-Key: fsk_…. A key in the URL is refused.
FormatJSON in and out (UTF-8). Form-encoded bodies are accepted too. Bodies up to 64 KB.
Rate limit60 requests a minute per key. Over that: 429 with Retry-After: 60.
TimesISO 8601 with your business’s UTC offset, e.g. 2026-11-03T10:00:00-08:00. Inputs also take a date or unix seconds.
MoneyDecimal strings with a currency, e.g. "total": "1250.00", "currency": "USD".
PATCHIf your tool can’t send PATCH, send POST with X-HTTP-Method-Override: PATCH.

Errors

Every error has the same shape and a matching HTTP status: 400 bad parameter, 401 missing or wrong key, 403 not in your plan or account not active, 404 not found in your account, 409 conflict (for example a time that was just taken), 422 a field is not valid, 429 rate limit, 503 try again shortly.

{"ok": false, "error": {"code": "bad_email", "message": "email is not a valid email address.", "field": "email"}}

Codes you may see on any call: account_inactive (the account is switched off or its plan has ended), terms_not_accepted (accept the API Terms in Settings → API & webhooks), plan_required (that part is not in your plan).

Pagination

Lists answer {"ok": true, "data": [ … ], "next_cursor": "…", "limit": 50}. Pass limit (1–100, default 50) and, for the next page, cursor=<next_cursor> with the same filters. next_cursor is null on the last page.

Idempotency

Send an Idempotency-Key header (any unique string up to 100 characters, a UUID is ideal) on a POST. If the request is retried with the same key and body within 24 hours, you get the first answer back (with Idempotent-Replayed: true) instead of a second customer or booking. The same key with a different body is refused with 422 idempotency_key_reused.

Endpoints

Method and routeWhat it doesPlan
GET v1/meYour business, timezone and the webhook events. Use it to test a key.All
GET v1/leads · GET/PATCH v1/leads/{id} · POST v1/leadsLeads (pins on your map): new since a time, one lead, create, change status or notes.All
GET v1/customers · GET/PATCH v1/customers/{id} · POST v1/customersCustomers: search, read, add, update.Plans with Customers
GET v1/bookings · GET/PATCH v1/bookings/{id} · POST v1/bookingsAppointments and online bookings: list by date, read, book, move, cancel, confirm.All
GET v1/availabilityOpen times from your booking settings.All
GET v1/estimates · GET v1/estimates/{id}Estimates with lines and totals.Plans with estimates and invoicing
GET v1/invoices · GET v1/invoices/{id}Invoices with lines, totals, amount paid and status.Plans with estimates and invoicing
GET v1/servicesYour price list (Equipment & pricing): name, category, price.Plans with quoting or invoicing
GET v1/form-leads · GET v1/form-leads/{id}Website contact form, landing-page and card-form leads.All

Customers

A customer in FieldStacker is built from their records: quotes, estimates and invoices, completed jobs, card contacts and, for door-knocking trades, won doors. A customer’s id is one of those records, like cus_q1042 (a quote) or cus_c88 (a contact). It is the customer’s oldest record, so it stays the same as new work comes in. Any of the customer’s record_ids finds the same customer, and if two customers are combined in the app, both old ids keep working.

GET v1/customers takes q (name, phone, email or address), updated_since, limit, cursor, newest activity first. POST takes name, phone, email, address, notes (at least a name, phone or email); if those details already match a customer, you get that customer back with "existing": true and nothing new is made. PATCH changes name, business, phone, alt_phone, email, address, notes, tags: what FieldStacker shows for the customer, the same as ✏️ Edit customer in the app. Past quotes and invoices keep what was on them.

curl -s 'https://www.fieldstacker.com/app/api.php?route=v1/customers&q=lopez&limit=20' \
  -H 'Authorization: Bearer fsk_your_key'

curl -s -X POST 'https://www.fieldstacker.com/app/api.php?route=v1/customers' \
  -H 'Authorization: Bearer fsk_your_key' -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 6f1c2a9e-crm-contact-311' \
  -d '{"name":"Maria Lopez","phone":"775-555-0100","email":"maria@example.com","address":"10 Main St, Reno, NV 89501"}'

Bookings and availability

Bookings come in two types. online_booking (ids like bk_52) is what your booking page makes, and appointment (ids like ap_918) is a job on your schedule. GET v1/bookings takes from, to (default: from 30 days ago), status (pending, confirmed, canceled, declined, completed, no_show, comma-separated), type, in start-time order.

POST v1/bookings books through your booking page’s own rules: the time must be one GET v1/availability offers, your approval setting applies, you get the same notification as a website booking, and your customer gets the same confirmation. Online booking must be switched on in FieldStacker. PATCH moves a booking (start_at), cancels it ("status": "canceled") or confirms a pending one ("status": "confirmed"). Jobs on your schedule that crews work from are changed in FieldStacker; the API can move or cancel only those booked by a customer online.

curl -s 'https://www.fieldstacker.com/app/api.php?route=v1/availability&date=2026-11-03' -H 'Authorization: Bearer fsk_your_key'

curl -s -X POST 'https://www.fieldstacker.com/app/api.php?route=v1/bookings' \
  -H 'Authorization: Bearer fsk_your_key' -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: web-booking-8812' \
  -d '{"start_at":"2026-11-03T10:00:00-08:00","service":"in_home",
       "customer":{"name":"Sam Lee","email":"sam@example.com","phone":"775-555-0142","address":"22 Oak Ave, Sparks, NV"}}'

Estimates and invoices

Read-only. Each has its number, status (estimates: draft, sent, approved; invoices: draft, in_progress, sent, unpaid, paid), the customer, the lines your customer sees, subtotal, tax, total, and for invoices amount_paid, deposit_paid, paid_at. customer_url is the link you already shared with the customer, if there is one. Lists take status, updated_since, most recently changed first.

curl -s 'https://www.fieldstacker.com/app/api.php?route=v1/invoices&status=paid&updated_since=2026-10-01' -H 'Authorization: Bearer fsk_your_key'

Price list and form leads

GET v1/services lists your Equipment & pricing items (q, category) with their customer prices; your costs are never included. GET v1/form-leads lists what visitors sent you, newest first (since, source = website_message, website_form, landing_page or card).

Webhooks

Webhooks send events to your own HTTPS address the moment they happen, so you don’t have to ask. Add up to 5 in Settings → API & webhooks and pick the events for each. Every delivery is a signed JSON POST (X-FieldStacker-Signature: sha256=…, an HMAC of the raw body with that webhook’s secret), retried for about 15 hours if your address does not answer with a 2xx.

lead.createdA new lead: dropped on the map, added, imported or created through the API.
lead.status_changedA lead’s status changes.
lead.soldA lead becomes a sale.
appointment.createdAn appointment is set on a lead or added to the schedule.
quote.approvedA customer approves a quote or estimate.
invoice.paidAn invoice is paid in full.

GET v1/me always lists the events your account can send, including any added after this page was written.

Good to know

  • Each key belongs to one business and sees only that business’s data. The data your team members add to your business is included.
  • Only the business owner can make or see a key. Team members and technicians can’t.
  • A webhook that creates a lead, sent to a tool that creates a lead in FieldStacker, would loop. Filter on lead_source: "api", or send "notify_webhooks": false when you create leads.
  • Questions or a bug? Email support@fieldstacker.com.

Get your API key

Start free, then open Settings → API & webhooks. Using the API means you agree to the API Terms.