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.
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").
| Status | Body | Meaning |
|---|---|---|
| 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). |
| 429 | rate limit | More 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.
| Field | Type | Description |
|---|---|---|
| id | integer | The visit's ID. |
| title | string | What the visit is for. |
| status | string | estimate (to visit) or estimate_done (visited). |
| address | string or null | Where the work is. |
| customer_id | integer | The customer's ID. |
| customer | string | The customer's name (the company name for a business customer). |
| created_at | string | When 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
| Field | Type | Description |
|---|---|---|
| id | integer | The proposal's ID. |
| number | integer | The proposal number. |
| total | string or null | The accepted total, in dollars. |
| job_id | integer or null | The job it became. |
| customer_id | integer | The customer's ID. |
| customer | string | The customer's name. |
| accepted_at | string | When 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
| Field | Type | Description |
|---|---|---|
| id | integer | The job's ID. |
| title | string | The job's title. |
| total | string or null | The job's total, in dollars. |
| address | string or null | Where the work was. |
| customer_id | integer | The customer's ID. |
| customer | string | The customer's name. |
| completed_at | string | When 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
| Field | Type | Description |
|---|---|---|
| id | integer | The invoice's ID. |
| number | string | The invoice number. |
| total | string | The invoice total, in dollars. |
| job_id | integer or null | The job it bills. |
| customer_id | integer | The customer's ID. |
| customer | string | The customer's name. |
| paid_at | string | When it was paid. |
| issued_at | string or null | When 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.
| Field | Type | Description |
|---|---|---|
| name | string, required | The customer's name. |
| string | Email address. | |
| phone | string | Phone number. |
| address, city, state, zip | string | Their address. |
| company_name | string | For a business customer. |
| is_business | boolean | True 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.
| Field | Type | Description |
|---|---|---|
| name | string, required | Who is asking. |
| email, phone | string, one required | How to reach them. |
| address, city, state, zip | string | Where the work is. |
| description | string | What they need done. |
| service_id | integer | One 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.