Bookt: API guide

Three ways to connect

  1. Excel: Units tab, download the template, fill it in, upload it. No IT needed.
  2. ServiceM8: paste your ServiceM8 API key in Settings. Units and staff sync in, and bookings are written back onto the calendar.
  3. Anything else: this API plus webhooks. Works from your own code or from Zapier / Make.

Authentication

The owner creates a key in Settings > Connect another system. Send it on every request. Keys are shown once, can be revoked at any time, and only ever reach your own company's data. Limit: 180 requests a minute.

Authorization: Bearer sp_live_…

Endpoints

Units (installed systems)

GET  /api/v1/units
POST /api/v1/units
{"units": [{"job_no": "AC-1001", "customer": "Jane Citizen", "email": "jane@example.com",
            "phone": "0411 222 333", "address": "12 Smith St, Parramatta NSW 2150",
            "unit_type": "split", "model": "Daikin 7.1kW", "installed": "2024-03-01",
            "interval_months": 12, "last_service": "2025-03-04"}]}

Same job_no = update. unit_type is split or ducted. Returns counts and any row errors.

Technicians

GET  /api/v1/technicians
POST /api/v1/technicians
{"technicians": [{"name": "Ryan West", "phone": "0400 111 222", "address": "8 Depot Rd, Blacktown NSW 2148",
                  "skills": "split, ducted", "days": "Mon-Fri", "start": "7:00", "finish": "15:30"}]}

Send a booking link

POST /api/v1/booking-links
{"job_no": "AC-1001", "kind": "service", "send": true}
→ {"url": "https://…/b/…", "sent": true}

kind: service, repair or breakdown. "send": false returns the link for you to send yourself.

Ask for a booking (e.g. the client rang you)

POST /api/v1/requests
{"job_no": "AC-1001", "kind": "repair", "offers": [["2026-12-01", "9-12"], ["2026-12-03", "any"]], "notes": "E5 error"}
→ {"request_id": 42, "best": {"tech": "Ryan West", "date": "2026-12-01", "arrival_txt": "9am", "star": true, …}}

Windows: 7-10, 9-12, 12-230, any. With auto-book on, a clean best pick books itself and you get booking.created.

Bookings

GET /api/v1/bookings?from=2026-12-01&to=2026-12-31

Webhooks

Set your https address in Settings and create a signing secret. Each event is POSTed as JSON. Failures are retried for about 2 days.

Events: booking.created, booking.cancelled, request.created, request.held, payment.paid.

{"id": 17, "type": "booking.created", "created": "2026-11-06T13:02:11",
 "data": {"job_no": "AC-1001", "date": "2026-12-01", "start": "9am", "end": "10am",
          "technician": "Ryan West", "customer": "Jane Citizen", "address": "…", "kind": "service"}}

Check the signature

Header X-SP-Signature: t=<unix time>,v1=<hex>, where v1 = HMAC-SHA256(secret, t + "." + raw body). Reject anything older than 5 minutes.

import hmac, hashlib, time
def verify(secret, raw_body, header):
    parts = dict(p.split("=", 1) for p in header.split(","))
    mac = hmac.new(secret.encode(), (parts["t"] + ".").encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(mac, parts["v1"]) and abs(time.time() - int(parts["t"])) < 300