Prufloop / Developers
Build with Prufloop.
We're building an open way for AI assistants and pro software to book, track and confirm real home service jobs. The test isn't whether an assistant can send a booking. It's whether it can tell the customer, truthfully, that the job is confirmed, and later that it's resolved.
The contract
One foundation plus five steps. Each step is what an assistant needs before it can say something true to the customer.
| Step | What the assistant needs | What we're building | What it can then say |
|---|---|---|---|
| Access | A documented, authorized way to act | Versioned HTTPS API with an OpenAPI document, OAuth with narrow scopes, a test environment, webhooks, and an MCP server. Plus a phone and text line and a booking page. | “I can book this for you.” |
| Verify | Proof the pro is licensed, insured and reliable | NC and SC license checks, insurance with an expiry date, and a Pruf Score built from real outcomes. | “Licensed, insured and on time 96% of the time.” |
| Expose | Terms a machine can compare, and real availability | Structured terms: pricing model, trip and diagnostic fees and whether they are credited, minimums, after-hours rates, the pro's warranty, and live slots from the pro's own schedule. | “$89 diagnostic, credited to the repair. Open at 2 pm.” |
| Book | A held slot and a confirmation it can trust | A 5-minute hold, the pro's accept, the job written to the pro's schedule, a confirmation ID and a booking.confirmed event. | “You're confirmed for 2 to 4 pm today.” (only after booking.confirmed) |
| Prove | A completion status tied to evidence | Photos, the customer's four answers and an invoice checked against the agreed terms, each sent as a job event. | “The pro marked it done and the invoice matches your quote.” |
| Pay | A final, explainable charge and a path if the fix fails | The invoice matched to the terms and approved changes, the pro's fee charged when the job is marked done, a 30-day check and dispute rules. | “Final price $412, as approved. If it comes back within 30 days, it's covered.” |
Access
- API: versioned HTTPS endpoints with an OpenAPI document and examples for every event and error.
- Auth: OAuth with narrow scopes. Read-only wherever possible, and writes only for the jobs we send.
- Test environment: sandbox pros, slots and jobs you can run end to end.
- Events: signed webhooks with retries, a stable job ID and a sequence number. If one fails, poll
GET /v1/jobs/{id}for the current state. - MCP server: the same actions for assistants that use the Model Context Protocol.
- Other doors: a phone and text line any assistant can call, and a booking page for people.
Job states and what an assistant may say
Every state change is an event. An assistant may say only what the current state supports.
| State | Event | The assistant may say |
|---|---|---|
| Requested | booking.requested | “I'm checking available pros.” |
| Held | booking.held | “I'm holding 2 to 4 pm while you decide.” |
| Confirmed | booking.confirmed | “You're confirmed for 2 to 4 pm today.” |
| Expired or declined | booking.expired booking.declined | “That slot fell through. Here are two others.” |
| Rescheduled or canceled | booking.rescheduled booking.canceled | “Your pro moved you to 3 to 5 pm.” |
| On the way, on site | job.en_route job.arrived | “Your pro is about 20 minutes away.” |
| Change pending | job.change_requested | “The pro found more work: $180 more. Approve?” |
| Change approved or declined | job.change_approved job.change_declined | “Approved. Work continues.” |
| Marked done | job.marked_done fee.charged | “The pro says it's done. Is it fixed?” |
| Fixed | job.confirmed_fixed | “Resolved.” |
| Unconfirmed | job.unconfirmed | “Done, according to the pro. You haven't confirmed yet.” |
| Disputed | job.disputed | “I've opened a dispute. You'll hear back within 7 days.” |
| Callback | job.recurrence_reported | “The pro is coming back under warranty, at no fee.” |
| Resolved after a dispute or callback | job.resolved | “It's resolved.” |
- "Confirmed" only after
booking.confirmed: the pro accepted and the job is on their calendar. A request, a hold or a voicemail is never a confirmation. - "Resolved" only after
job.confirmed_fixedorjob.resolved: the customer said it's fixed.
Errors
Each error comes with a plain explanation and what the assistant can say next.
slot_unavailablehold_expiredpro_not_verifiedterms_incompleteoutside_service_areaconsent_requiredscope_insufficientchange_requires_approvalidempotency_conflictrate_limited
{
"error": "hold_expired",
"message": "The 5-minute hold on slot 2026-11-04T14:00 lapsed.",
"job_id": "job_8f2c",
"retry": { "action": "GET /v1/availability", "alternatives": 2 },
"may_say": "That slot fell through. Here are two others."
}
Pro software
The pro's own system stays the schedule of record. Planned connections by stage; none are live yet.
| Stage | Scheduling | Invoicing and paid status |
|---|---|---|
| Launch, Q4 2026 | Prufloop Pro, Google Calendar, Microsoft Outlook, Jobber, Square Appointments | Prufloop Pro invoicing, QuickBooks Online, Square, Jobber |
| 2027 | Calendly, Acuity, Service Fusion, ServiceTitan (with ServiceTitan's certification) | Xero, FreshBooks, Stripe, GorillaDesk, ServiceTitan |
| Later | Housecall Pro, Workiz, Kickserv, FieldEdge | Same |
Some platforms need partner approval or a specific plan. Until a platform connects, the pro runs Prufloop jobs in Prufloop Pro.
Request early access
Building an assistant, an agent, or software for the trades? Tell us what you're working on and we'll reach out when the test environment opens.
We use your details only to contact you about developer access. See our privacy page.