Ask for what changed#
Every paginated list accepts updated_since: customers, jobs, invoices, payments, price book items, estimates, maintenance plans, plan enrollments, equipment, notes, photos, time entries, schedule events and leads. It returns only records changed at or after the time you give.
curl "https://couplrfsm.com/api/v1/customers?updated_since=2026-11-14T15:00:00Z&per_page=100" \
-H "Authorization: Bearer YOUR_API_KEY"
How to use it:
- Before each run, note the current time.
- Request the list with
updated_sinceset to the time you noted on your previous run. Read every page. See Pagination. - Save each record by its
id, replacing your copy. - When the run succeeds, store the time from step 1 for next time.
Details that matter:
- The time is ISO 8601. An offset such as
+02:00is honored. A date alone, such as2026-11-14, means the start of that day in UTC. - The filter is inclusive, so a record changed in the same second as your last run comes back again. Saving by
idmakes that harmless. - A customer counts as changed when one of its addresses is added or edited.
- A payment counts as changed when its invoice changes, so a refund brings the payment back with its new
statusand refund amounts. - Lists stay in their usual order (newest first), not in order of change.
- A deleted record simply stops appearing in its list. To learn about deletions, ask for them: see Notice deletions below.
Notice deletions#
Customers, jobs, invoices and estimates can be removed in Couplr. Ask which ones were removed since your last run:
curl "https://couplrfsm.com/api/v1/deleted?since=2026-11-14T15:00:00Z&per_page=100" \
-H "Authorization: Bearer YOUR_API_KEY"
Each entry is a type (customer, job, invoice or estimate), the record's id (always a string) and when it was removed. Remove those records from your copy. Use the same saved time you use for updated_since.
- No extra ability is needed. You are shown removals for the kinds of record your key can already read.
- A record that someone restores from the Trash stops being listed here and comes back in its own list with a new
updated_at. - A removed record is listed for as long as Couplr keeps it in its Trash. If you sync rarely, compare against a full read from time to time as well.
- This only reports. Nothing can be deleted through the API.
Have events pushed to you#
An app can subscribe itself to events with a key that has the webhooks:manage ability. No one has to paste a URL into the Integrations page.
curl -X POST "https://couplrfsm.com/api/v1/webhook-subscriptions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_KEY" \
-d '{"url": "https://example.com/couplr-events", "events": ["invoice.paid", "job.completed"], "description": "Accounting sync"}'
Response (201):
{
"data": {
"id": 14,
"url": "https://example.com/couplr-events",
"description": "Accounting sync",
"events": ["invoice.paid", "job.completed"],
"active": true,
"disabled_reason": null,
"last_delivery_at": null,
"created_at": "2026-11-14T15:10:00+00:00",
"secret": "YOUR_SIGNING_SECRET"
}
}
secretis returned only in this response. Store it and use it to check the signature on every delivery. See Verify the signature.- The URL must start with
https://and use a public hostname. eventstakes names from the event list, or"*"for all of them.- Send
"active": falseto create a subscription switched off, then turn it on with an update when your receiver is ready. - List, change and delete subscriptions with the other webhook subscription endpoints.
Which to use#
| Need | Use |
|---|---|
| React within seconds, for example to a paid invoice | Webhook subscription |
| A nightly or hourly copy of records | updated_since |
| Not miss anything, even if your server was down | Both: events for speed, an updated_since sweep to catch up |
| Changes to records that have no event, such as an edited customer | updated_since |
Events exist for the moments listed in the event list. There is no event for every edit, so updated_since is the complete view and events are the fast one. Each event carries a short summary with the record's id; fetch the full record from the API when you need it.