API reference
API: Packs: home services
| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | /v1/packs/home-services/estimates | Estimates being followed up (by status: open, paused, engaged, won, lost, stopped) | packs:read |
| POST | /v1/packs/home-services/estimates | Add an estimate to follow up (the cadence starts from its sent date) | packs:write |
| GET | /v1/packs/home-services/estimates/:id | An estimate and its history (touches, replies read, pauses, wakes, hand-offs) | packs:read |
| POST | /v1/packs/home-services/estimates/:id/action | Won, lost, stop, reopen, resume, pause until a day, or log the customer's reply (read for a pause) | packs:write |
| POST | /v1/packs/home-services/estimates/run | Run the follow-up pass now: wake paused estimates, read replies, draft due touches (owners) | settings:write |
| GET | /v1/packs/home-services/fsm/availability | Live technician availability on the connected board (Housecall Pro, Jobber or ServiceTitan) | packs:read |
| GET | /v1/packs/home-services/fsm/bookings | Bookings proposed, booked, in conflict or failed | packs:read |
| POST | /v1/packs/home-services/fsm/bookings | Propose a booking on the board (a person books it next; nothing reaches the board yet) | packs:write |
| POST | /v1/packs/home-services/fsm/bookings/:id/book | Book a proposal onto the board now (policy first; the window is re-checked live; a retry never books twice). Optionally pick another window. | packs:write |
| POST | /v1/packs/home-services/fsm/bookings/:id/cancelled | Record that a booked job was cancelled on the board (cancel it there; this frees the slot here) | packs:write |
| POST | /v1/packs/home-services/fsm/bookings/:id/reject | Turn down a proposed booking (it can be proposed again) | packs:write |
| GET | /v1/packs/home-services/missed-calls | Missed calls and what happened (texted back, called back, booked, escalated) | packs:read |
| POST | /v1/packs/home-services/missed-calls/:id/action | Mark a missed call contacted, closed or escalated, or reopen it | packs:write |
| POST | /v1/packs/home-services/missed-calls/run | Run missed-call recovery now (owners) | settings:write |
| POST | /v1/packs/home-services/oncall/calls | An after-hours call typed in by whoever answered: triaged; an emergency pages the on-call ladder; gas or CO gets the safety script, never a dispatch | packs:write |
| GET | /v1/packs/home-services/oncall/incidents | After-hours calls from the call to the job's completion | packs:read |
| GET | /v1/packs/home-services/oncall/incidents/:id | One after-hours call with every page sent up the ladder | packs:read |
| POST | /v1/packs/home-services/oncall/incidents/:id/action | Confirm, release, en route, on site, complete, cancel, reopen, re-page or escalate an after-hours call (the shift's people, ops and owners) | packs:write |
| POST | /v1/packs/home-services/oncall/run | Run the on-call pass now: escalate pages nobody confirmed, triage new after-hours calls (owners) | settings:write |
| GET | /v1/packs/home-services/oncall/shifts | On-call shifts (current and upcoming) | packs:read |
| POST | /v1/packs/home-services/oncall/shifts | Add an on-call shift: primary, backup and manager (owners) | settings:write |
| DELETE | /v1/packs/home-services/oncall/shifts/:id | Remove an on-call shift (owners) | settings:write |
| GET | /v1/packs/home-services/qualifications | Recent qualifications with their route and disposition | packs:read |
| POST | /v1/packs/home-services/qualify | Qualify a lead by its vertical's rules (budget, homeownership, insurance details, service area) and route it: a booking proposal on the board, the booking page, a live rep, or a task to collect what's missing | packs:write |
| GET | /v1/packs/home-services/service-areas | Branches and their service areas (ZIP lists, radius) | packs:read |
| POST | /v1/packs/home-services/serviceability | Is an address in the service area? (US Census geocoder, cached; then each branch's ZIP list or radius) | packs:read |
| POST | /v1/packs/home-services/triage | Preview how the triage policy reads a caller's words (nothing is paged) | packs:read |
| GET | /v1/packs/home-services/triage-rules | The triage policy: keyword → class → action (gas and CO are always a safety redirect) | packs:read |
| POST | /v1/packs/home-services/triage-rules | Add a triage rule (owners) | settings:write |
| DELETE | /v1/packs/home-services/triage-rules/:id | Remove a triage rule (owners; a seeded rule is turned off, so a reinstall doesn't bring it back) | settings:write |
| PUT | /v1/packs/home-services/triage-rules/:id | Change a triage rule (owners) | settings:write |
Examples
GET /v1/packs/home-services/estimates
Estimates being followed up (by status: open, paused, engaged, won, lost, stopped)
curl -s "https://api.closefinch.com/v1/packs/home-services/estimates" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/estimates`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/estimates
Add an estimate to follow up (the cadence starts from its sent date)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/estimates" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/estimates`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/estimates/$ID
An estimate and its history (touches, replies read, pauses, wakes, hand-offs)
curl -s "https://api.closefinch.com/v1/packs/home-services/estimates/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/estimates/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/estimates/$ID/action
Won, lost, stop, reopen, resume, pause until a day, or log the customer's reply (read for a pause)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/estimates/$ID/action" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/estimates/${id}/action`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/estimates/run
Run the follow-up pass now: wake paused estimates, read replies, draft due touches (owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/estimates/run" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/estimates/run`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/fsm/availability
Live technician availability on the connected board (Housecall Pro, Jobber or ServiceTitan)
curl -s "https://api.closefinch.com/v1/packs/home-services/fsm/availability" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/availability`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/packs/home-services/fsm/bookings
Bookings proposed, booked, in conflict or failed
curl -s "https://api.closefinch.com/v1/packs/home-services/fsm/bookings" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/bookings`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/fsm/bookings
Propose a booking on the board (a person books it next; nothing reaches the board yet)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/fsm/bookings" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/bookings`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/fsm/bookings/$ID/book
Book a proposal onto the board now (policy first; the window is re-checked live; a retry never books twice). Optionally pick another window.
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/fsm/bookings/$ID/book" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/bookings/${id}/book`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/fsm/bookings/$ID/cancelled
Record that a booked job was cancelled on the board (cancel it there; this frees the slot here)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/fsm/bookings/$ID/cancelled" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/bookings/${id}/cancelled`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/fsm/bookings/$ID/reject
Turn down a proposed booking (it can be proposed again)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/fsm/bookings/$ID/reject" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/fsm/bookings/${id}/reject`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/missed-calls
Missed calls and what happened (texted back, called back, booked, escalated)
curl -s "https://api.closefinch.com/v1/packs/home-services/missed-calls" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/missed-calls`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/missed-calls/$ID/action
Mark a missed call contacted, closed or escalated, or reopen it
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/missed-calls/$ID/action" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/missed-calls/${id}/action`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/missed-calls/run
Run missed-call recovery now (owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/missed-calls/run" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/missed-calls/run`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/oncall/calls
An after-hours call typed in by whoever answered: triaged; an emergency pages the on-call ladder; gas or CO gets the safety script, never a dispatch
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/oncall/calls" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/calls`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/oncall/incidents
After-hours calls from the call to the job's completion
curl -s "https://api.closefinch.com/v1/packs/home-services/oncall/incidents" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/incidents`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/packs/home-services/oncall/incidents/$ID
One after-hours call with every page sent up the ladder
curl -s "https://api.closefinch.com/v1/packs/home-services/oncall/incidents/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/incidents/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/oncall/incidents/$ID/action
Confirm, release, en route, on site, complete, cancel, reopen, re-page or escalate an after-hours call (the shift's people, ops and owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/oncall/incidents/$ID/action" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/incidents/${id}/action`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/oncall/run
Run the on-call pass now: escalate pages nobody confirmed, triage new after-hours calls (owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/oncall/run" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/run`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/oncall/shifts
On-call shifts (current and upcoming)
curl -s "https://api.closefinch.com/v1/packs/home-services/oncall/shifts" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/shifts`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/oncall/shifts
Add an on-call shift: primary, backup and manager (owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/oncall/shifts" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/shifts`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();DELETE /v1/packs/home-services/oncall/shifts/$ID
Remove an on-call shift (owners)
curl -s -X DELETE "https://api.closefinch.com/v1/packs/home-services/oncall/shifts/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/oncall/shifts/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/packs/home-services/qualifications
Recent qualifications with their route and disposition
curl -s "https://api.closefinch.com/v1/packs/home-services/qualifications" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/qualifications`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/qualify
Qualify a lead by its vertical's rules (budget, homeownership, insurance details, service area) and route it: a booking proposal on the board, the booking page, a live rep, or a task to collect what's missing
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/qualify" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/qualify`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/service-areas
Branches and their service areas (ZIP lists, radius)
curl -s "https://api.closefinch.com/v1/packs/home-services/service-areas" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/service-areas`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/serviceability
Is an address in the service area? (US Census geocoder, cached; then each branch's ZIP list or radius)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/serviceability" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/serviceability`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/packs/home-services/triage
Preview how the triage policy reads a caller's words (nothing is paged)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/triage" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/triage`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/packs/home-services/triage-rules
The triage policy: keyword → class → action (gas and CO are always a safety redirect)
curl -s "https://api.closefinch.com/v1/packs/home-services/triage-rules" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/triage-rules`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/packs/home-services/triage-rules
Add a triage rule (owners)
curl -s -X POST "https://api.closefinch.com/v1/packs/home-services/triage-rules" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/triage-rules`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();DELETE /v1/packs/home-services/triage-rules/$ID
Remove a triage rule (owners; a seeded rule is turned off, so a reinstall doesn't bring it back)
curl -s -X DELETE "https://api.closefinch.com/v1/packs/home-services/triage-rules/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/triage-rules/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/packs/home-services/triage-rules/$ID
Change a triage rule (owners)
curl -s -X PUT "https://api.closefinch.com/v1/packs/home-services/triage-rules/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/packs/home-services/triage-rules/${id}`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();Request and response schemas: https://www.closefinch.com/openapi.json. All resources: API reference.