wittle labs

BUSINESSES & SCHEDULER VENDORS

Connect your scheduling

Your schedule stays where it lives today. Wittle reads open times from it, writes confirmed visits into it, and follows the rules you set.

Ways to connect

You useHow Wittle connectsCustomers get
Google CalendarConnect Google once, set up with you at onboarding. Wittle reads busy times and adds visits as events. (Today on a calendar Wittle creates for you; connecting your own main calendar is coming.)Real open slots, instant confirmation if you allow it
A field-service app (Jobber, Housecall Pro, Workiz, ServiceTitan, Square…)Direct integration, built per platform as businesses ask for it. Tell us what you use.Real open slots from your app
Nothing, or your own systemA signed booking request to your server or office, which you accept or decline (below).A request for a preferred time; your answer comes back to them

Your rules

Set up with you at onboarding, changeable any time:

  • Services and prices: diagnostic fee, fixed, “from”, or quote.
  • Where you work: ZIP codes, a radius from your base, or both.
  • What confirms instantly and what you review: by service, distance, urgency and notice, e.g. auto-confirm nearby inspections booked a day ahead, review everything else, “call us” for installs.
  • Notice and horizon: minimum hours ahead, how far out to book.
  • Your questions for customers before a visit, like the ones on your website’s request form.
  • A note shown to customers with every booking (“We text 30 minutes before arrival”).

Signed booking requests (webhook)

For businesses and vendors without a supported scheduler: when a customer confirms, Wittle sends the booking to your HTTPS endpoint, and you answer when the office accepts or declines.

1. Request Wittle sends

POST {your webhook URL}
Content-Type: application/json
X-Wittle-Timestamp: <unix seconds>
X-Wittle-Signature: sha256=<hex HMAC-SHA256 of "<timestamp>." + raw body>

{
  "provider_id": "…",
  "service_id": "…",
  "window_start": "2026-10-06T09:00:00-04:00",
  "window_end": "2026-10-06T11:00:00-04:00",
  "timezone": "America/New_York",
  "customer": { "name": "…", "phone": "+1…", "email": "…" },
  "address": { "line1": "…", "city": "…", "state": "NJ", "zip": "07003" },
  "job_details": { "problem": "Water leaking under the kitchen sink", "urgency": "soon" },
  "intake_answers": { "contact_time": ["Daytime"], "existing_customer": false },
  "idempotency_key": "…",
  "booking_mode": "REQUEST",
  "extensions": { "wittle:booking_id": "…" }
}
  • intake_answers holds the customer’s answers to your questions (absent if you have none).
  • The same idempotency_key may arrive more than once; treat repeats as the same request.

2. Verify the signature

The shared secret is agreed at onboarding. Compute HMAC-SHA256 over <X-Wittle-Timestamp>. followed by the exact request bytes, hex-encoded, and compare in constant time. Reject timestamps more than 5 minutes from your clock.

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, secret, signatureHeader, timestampHeader, now = Date.now()) {
  if (Math.abs(now - Number(timestampHeader) * 1000) > 5 * 60 * 1000) return false; // replay
  const expected = createHmac("sha256", secret).update(`${timestampHeader}.`).update(rawBody).digest();
  const provided = Buffer.from(signatureHeader.slice("sha256=".length), "hex");
  return expected.length === provided.length && timingSafeEqual(expected, provided);
}

3. Answer

POST https://scheduling.wittlelabs.ai/integrations/notify/{provider_id}/status
Content-Type: application/json
X-Wittle-Timestamp: <unix seconds>
X-Wittle-Signature: sha256=<same scheme>

{ "booking_id": "<extensions['wittle:booking_id']>", "status": "CONFIRMED" }
  • status is CONFIRMED or FAILED.
  • Wittle answers 200, 401 (bad signature or stale timestamp) or 409 (the booking can no longer move to that status).
  • Until you answer, the customer’s assistant shows the booking as waiting for you.

Your data

  • Customers’ assistants see only your open times, never your other appointments.
  • You receive the details a customer gives for their booking with you, and nothing about customers who booked elsewhere.
  • Credentials for your calendar or app are stored encrypted and used only for your bookings.

Get included

We’re onboarding our first local service businesses and scheduler partners. Email us with what you offer, where you work, and how you schedule today.