Skip to content

API reference

API: Packs: home services

Markdown version

MethodPathWhat it doesScope
GET/v1/packs/home-services/estimatesEstimates being followed up (by status: open, paused, engaged, won, lost, stopped)packs:read
POST/v1/packs/home-services/estimatesAdd an estimate to follow up (the cadence starts from its sent date)packs:write
GET/v1/packs/home-services/estimates/:idAn estimate and its history (touches, replies read, pauses, wakes, hand-offs)packs:read
POST/v1/packs/home-services/estimates/:id/actionWon, 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/runRun the follow-up pass now: wake paused estimates, read replies, draft due touches (owners)settings:write
GET/v1/packs/home-services/fsm/availabilityLive technician availability on the connected board (Housecall Pro, Jobber or ServiceTitan)packs:read
GET/v1/packs/home-services/fsm/bookingsBookings proposed, booked, in conflict or failedpacks:read
POST/v1/packs/home-services/fsm/bookingsPropose 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/bookBook 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/cancelledRecord 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/rejectTurn down a proposed booking (it can be proposed again)packs:write
GET/v1/packs/home-services/missed-callsMissed calls and what happened (texted back, called back, booked, escalated)packs:read
POST/v1/packs/home-services/missed-calls/:id/actionMark a missed call contacted, closed or escalated, or reopen itpacks:write
POST/v1/packs/home-services/missed-calls/runRun missed-call recovery now (owners)settings:write
POST/v1/packs/home-services/oncall/callsAn 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 dispatchpacks:write
GET/v1/packs/home-services/oncall/incidentsAfter-hours calls from the call to the job's completionpacks:read
GET/v1/packs/home-services/oncall/incidents/:idOne after-hours call with every page sent up the ladderpacks:read
POST/v1/packs/home-services/oncall/incidents/:id/actionConfirm, 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/runRun the on-call pass now: escalate pages nobody confirmed, triage new after-hours calls (owners)settings:write
GET/v1/packs/home-services/oncall/shiftsOn-call shifts (current and upcoming)packs:read
POST/v1/packs/home-services/oncall/shiftsAdd an on-call shift: primary, backup and manager (owners)settings:write
DELETE/v1/packs/home-services/oncall/shifts/:idRemove an on-call shift (owners)settings:write
GET/v1/packs/home-services/qualificationsRecent qualifications with their route and dispositionpacks:read
POST/v1/packs/home-services/qualifyQualify 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 missingpacks:write
GET/v1/packs/home-services/service-areasBranches and their service areas (ZIP lists, radius)packs:read
POST/v1/packs/home-services/serviceabilityIs 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/triagePreview how the triage policy reads a caller's words (nothing is paged)packs:read
GET/v1/packs/home-services/triage-rulesThe triage policy: keyword → class → action (gas and CO are always a safety redirect)packs:read
POST/v1/packs/home-services/triage-rulesAdd a triage rule (owners)settings:write
DELETE/v1/packs/home-services/triage-rules/:idRemove 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/:idChange 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.

Send feedback

Tell us what's broken, confusing or missing on this page, or an idea. It goes to the team that builds the product.

Please don't include passwords or card numbers.
Only to reply about this. Never added to any mailing list.