bobbuilt.io
Overview
A small REST API for reading your agency's calendar, booking appointments, and syncing contacts — built for voice agents, quiz funnels, and your own automations. Every request is scoped to a single agency by its API key.
All endpoints accept and return JSON over HTTPS. Timestamps are ISO 8601 in UTC; dates and times you send for booking are interpreted in the agency's configured booking timezone, which every availability response echoes back. CORS is open and each endpoint answers OPTIONS preflight, so browser-based tools and no-code platforms can call the API directly.
Notice
API keys grant access to a single agency's calendar and contacts. Keep them server-side, never ship them in a browser bundle, and revoke any key you suspect has leaked. Contact us to report an issue or request access.
Inbound webhook endpoints use the agency webhook secret instead, since they are configured inside third-party tools like GoHighLevel.
Authenticated request
curl --location "https://bobbuilt.io/api/public/webhooks/contacts" \
--header "Authorization: Bearer $BOBBUILT_API_KEY"/book/availabilityList available dates
Returns every date in the requested range that has at least one open appointment slot, along with the agency's booking timezone and slot length.
Example Request
curl --location "https://bobbuilt.io/api/public/webhooks/book/availability?from=2026-08-10&to=2026-08-24" \
--header "Authorization: Bearer $BOBBUILT_API_KEY"Example Response
200 OK{
"agency_id": "8f1c...c2a1",
"timezone": "America/Chicago",
"slot_minutes": 30,
"from": "2026-08-10",
"to": "2026-08-24",
"available_dates": [
{ "date": "2026-08-10", "slots": 9 },
{ "date": "2026-08-11", "slots": 12 }
]
}/book/availability/{date}List slots for a date
Returns the open slots for a single date. time is the local wall clock in the agency's timezone; iso is the same instant in UTC and is the value the booking endpoint validates against.
Example Request
curl --location "https://bobbuilt.io/api/public/webhooks/book/availability/2026-08-11" \
--header "Authorization: Bearer $BOBBUILT_API_KEY"Example Response
200 OK{
"agency_id": "8f1c...c2a1",
"date": "2026-08-11",
"timezone": "America/Chicago",
"slot_minutes": 30,
"slots": [
{ "time": "09:00", "iso": "2026-08-11T14:00:00.000Z" },
{ "time": "09:30", "iso": "2026-08-11T14:30:00.000Z" }
]
}/bookBook an appointment
Books an appointment on the agency calendar. The contact is matched by phone number — an existing lead is updated, otherwise a new lead is created and marked as qualified. date and time are interpreted in the agency's booking timezone.
Example Request
curl --location --request POST "https://bobbuilt.io/api/public/webhooks/book" \
--header "Authorization: Bearer $BOBBUILT_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"date": "2026-08-11",
"time": "09:30",
"first_name": "Dana",
"last_name": "Ruiz",
"email": "dana@example.com",
"phone": "+15125550188",
"notes": "Wants term coverage, prefers mornings"
}'Example Response
200 OK{
"ok": true,
"appointment_id": "4c2e...9ab0",
"lead_id": "7d10...1f42",
"scheduled_at": "2026-08-11T14:30:00.000Z",
"agent_name": "Bob Kleffner"
}/contactsList contacts
Lists leads for the authenticated agency, newest first. Combine filters to narrow the result set.
Example Request
curl --location "https://bobbuilt.io/api/public/webhooks/contacts?q=ruiz&limit=25" \
--header "Authorization: Bearer $BOBBUILT_API_KEY"Example Response
200 OK{
"contacts": [
{
"id": "7d10...1f42",
"first_name": "Dana",
"last_name": "Ruiz",
"email": "dana@example.com",
"phone": "+15125550188",
"status": "qualified",
"source": "voice_ai",
"created_at": "2026-08-06T18:04:11.220Z"
}
]
}/contacts/{id}Get a contact
Returns one contact plus all of their appointments. The path segment accepts either the lead UUID or the contact's phone number.
Example Request
curl --location "https://bobbuilt.io/api/public/webhooks/contacts/+15125550188" \
--header "Authorization: Bearer $BOBBUILT_API_KEY"Example Response
200 OK{
"contact": {
"id": "7d10...1f42",
"first_name": "Dana",
"last_name": "Ruiz",
"email": "dana@example.com",
"phone": "+15125550188",
"status": "qualified",
"source": "voice_ai",
"created_at": "2026-08-06T18:04:11.220Z",
"quiz_answers": { "project_type": "Book a consultation", "service_level": "Premium" }
},
"appointments": [
{ "id": "4c2e...9ab0", "scheduled_at": "2026-08-11T14:30:00.000Z", "status": "scheduled" }
]
}/funnel/webhookCreate a lead from an external quiz
Accepts a flexible JSON payload from an external quiz or form. Known fields map to lead columns; anything else is preserved in quiz_answers. Returns a booking URL that already carries the lead token, so you can redirect the prospect straight into a tracked calendar.
Example Request
curl --location --request POST "https://bobbuilt.io/api/public/funnel/webhook" \
--header "Authorization: Bearer $AGENCY_WEBHOOK_SECRET" \
--header "Content-Type: application/json" \
--data '{
"first_name": "Dana",
"last_name": "Ruiz",
"email": "dana@example.com",
"phone": "+15125550188",
"dob": "July 4th, 1985",
"coverage_amount": 250000,
"utm_source": "facebook"
}'Example Response
200 OK{
"lead_token": "lt_9f2c...",
"booking_url": "https://bobbuilt.io/kleffner/book?lt=lt_9f2c..."
}/webhooks/ghlGoHighLevel contact webhook
Drop-in endpoint for a GoHighLevel workflow webhook action. Point a "Contact Created" (or form submitted) trigger at this URL with the agency webhook secret in the Authorization header and a custom JSON body containing agency_id and the contact fields. New leads fire the owner's new-lead notification email.
Example Request
curl --location --request POST "https://bobbuilt.io/api/public/webhooks/ghl" \
--header "Authorization: Bearer $AGENCY_WEBHOOK_SECRET" \
--header "Content-Type: application/json" \
--data '{
"agency_id": "8f1c...c2a1",
"first_name": "{{contact.first_name}}",
"last_name": "{{contact.last_name}}",
"email": "{{contact.email}}",
"phone": "{{contact.phone}}"
}'Example Response
200 OK{ "ok": true, "lead_id": "7d10...1f42" }MCP server
Bobbuilt also exposes a Model Context Protocol server so AI assistants can work with your workspace directly. Add the URL to any MCP-compatible client, sign in with your Bobbuilt account when prompted, and approve access. Tools run as you, with the same row-level permissions as the dashboard.
Server URL
https://bobbuilt.io/mcpErrors
Errors return the appropriate HTTP status with a JSON body of the shape { "error": "..." }.
Error body
4xx / 5xx{
"error": "Slot is no longer available"
}Recipe: booking from a voice agent
The intended flow for a voice assistant that books on the agency calendar during a live call.
- 1Look the caller up with GET /contacts?phone=… so the agent can greet a returning lead by name.
- 2Call GET /book/availability for the next 7–14 days to find dates with openings.
- 3Call GET /book/availability/{date} for the chosen day and read two or three times back to the caller.
- 4Call POST /book with the caller's details and the confirmed date and time.
- 5On 409, the slot was taken mid-call — re-read the returned availability and offer another time.
Need a key or have a question about the API? Get in touch.
Step 4 — book the slot
curl --location --request POST "https://bobbuilt.io/api/public/webhooks/book" \
--header "Authorization: Bearer $BOBBUILT_API_KEY" \
--header "Content-Type: application/json" \
--data '{"date":"2026-08-11","time":"09:30",
"first_name":"Dana","last_name":"Ruiz",
"email":"dana@example.com","phone":"+15125550188"}'