Developers · API v1

ServicePros Hub API

The API behind the ServicePros Hub integration for Zapier. It lets a business connect its own ServicePros Hub account to other apps: new requests, accepted proposals, completed jobs and paid invoices go out, and customers and requests come in. Every request is scoped to the one business whose API key is used.

AuthenticationLimits and errorsTest the key New requestsAccepted proposalsCompleted jobsPaid invoices Create a customerCreate a requestSupport

Authentication

Base URL: https://serviceproshub.com/api/zapier/v1. HTTPS only.

An owner creates an API key in ServicePros Hub under Settings › Integrations › Zapier, with Create key. The key starts with sph_live_ and is shown once; only a hash of it is stored. Revoking it in the same place stops it at once. Send it on every request:

Authorization: Bearer sph_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

An X-API-Key: sph_live_… header works too.

Limits and errors

Up to 120 requests a minute per key. Lists return the 50 newest items, newest first; every item has a stable id, so polling can skip items it has already seen. Times are ISO 8601 in UTC (2026-10-13T14:40:05Z). Money is a decimal string in US dollars ("925.54").

StatusBodyMeaning
401{"error":"API key required"}No key was sent.
401{"error":"Invalid API key"}The key is wrong or was revoked.
400{"error":"name is required"}A required field is missing (the message says which).
429rate limitMore than 120 requests in a minute. Wait and retry.
500{"error":"…"}Something failed on our side. Retry later.

Test the key

GET/auth/test

Checks the key and returns the business it belongs to.

{ "company_id": 17, "company": "Action Tree Service" }

New requests

GET/requests

Estimate visits on the Work board: requests from the Book now page, from the API, and ones added in the app.

FieldTypeDescription
idintegerThe visit's ID.
titlestringWhat the visit is for.
statusstringestimate (to visit) or estimate_done (visited).
addressstring or nullWhere the work is.
customer_idintegerThe customer's ID.
customerstringThe customer's name (the company name for a business customer).
created_atstringWhen the request came in.
[{ "id": 1290, "title": "Oak trimming estimate", "status": "estimate", "address": "412 Oak St, Abilene, TX",
   "customer_id": 1188, "customer": "Sarah Whitfield", "created_at": "2026-10-12T15:02:11Z" }]

Accepted proposals

GET/proposals/accepted

FieldTypeDescription
idintegerThe proposal's ID.
numberintegerThe proposal number.
totalstring or nullThe accepted total, in dollars.
job_idinteger or nullThe job it became.
customer_idintegerThe customer's ID.
customerstringThe customer's name.
accepted_atstringWhen the customer accepted it.
[{ "id": 455, "number": 455, "total": "1200.00", "job_id": 1302, "customer_id": 1188,
   "customer": "Sarah Whitfield", "accepted_at": "2026-10-12T18:20:44Z" }]

Completed jobs

GET/jobs/completed

FieldTypeDescription
idintegerThe job's ID.
titlestringThe job's title.
totalstring or nullThe job's total, in dollars.
addressstring or nullWhere the work was.
customer_idintegerThe customer's ID.
customerstringThe customer's name.
completed_atstringWhen the job was finished.
[{ "id": 1302, "title": "Tree Trimming", "total": "925.54", "address": "88 Pecan Dr, Abilene, TX",
   "customer_id": 1188, "customer": "Sarah Whitfield", "completed_at": "2026-10-13T16:05:00Z" }]

Paid invoices

GET/invoices/paid

FieldTypeDescription
idintegerThe invoice's ID.
numberstringThe invoice number.
totalstringThe invoice total, in dollars.
job_idinteger or nullThe job it bills.
customer_idintegerThe customer's ID.
customerstringThe customer's name.
paid_atstringWhen it was paid.
issued_atstring or nullWhen it was issued.
[{ "id": 812, "number": "INV-1044", "total": "925.54", "job_id": 1302, "customer_id": 1188,
   "customer": "Sarah Whitfield", "paid_at": "2026-10-13T19:30:12Z", "issued_at": "2026-10-13T00:00:00Z" }]

Create a customer

POST/customers

Adds a customer. If the business already has a customer with the same phone number or email, that customer is returned instead of a duplicate, so a retried request is safe. Nobody is texted or emailed.

FieldTypeDescription
namestring, requiredThe customer's name.
emailstringEmail address.
phonestringPhone number.
address, city, state, zipstringTheir address.
company_namestringFor a business customer.
is_businessbooleanTrue for a business customer (also true when company_name is given).
POST /api/zapier/v1/customers
{ "name": "Sarah Whitfield", "email": "sarah@example.com", "phone": "(325) 555-0121", "address": "412 Oak St", "city": "Abilene", "state": "TX", "zip": "79601" }

201 { "id": 1188, "created": true }      // or 200 { "id": 1188, "created": false } when found

Create a request

POST/requests

A request for a visit, the same way a homeowner's Book now request arrives: it is checked for spam, matched to a customer (or a new one is added), put on the Work board as an estimate visit, and the owner is alerted.

FieldTypeDescription
namestring, requiredWho is asking.
email, phonestring, one requiredHow to reach them.
address, city, state, zipstringWhere the work is.
descriptionstringWhat they need done.
service_idintegerOne of the business's services, when known.
201 { "request_id": 640, "job_id": 1290, "status": "new" }

status: new (on the Work board, with its job_id), filtered (held as likely spam, in the Book now Filtered list), received (still being processed), or failed.

Support

Questions about the API or the Zapier integration: support@serviceproshub.com.