API Documentation

B5N Booking REST API v1.0

OpenAPI Spec

Authentication

All API requests require an API key passed in the X-API-Key header.

curl -X GET "https://api.b5n.io/api/availability?date=2026-01-20" \
  -H "X-API-Key: oxb_your_api_key_here"

Security Note: API keys are only shown once when created. Store them securely - if lost, you'll need to generate a new key.

API Scopes

ScopeDescription
availability:readCheck available appointment slots
appointments:readView appointment details
appointments:writeCreate and update appointments
appointments:deleteCancel appointments
employees:readView employee information
services:readView service types

Availability

Appointments

Recurring Appointments

Create and manage recurring appointment series for customers with regular visits. Perfect for weekly therapy sessions, bi-weekly cleanings, monthly check-ups, and more.

Key Concepts

Series ID

Each recurring series has a unique series_id that links all appointments together. Use this to identify and manage the series.

Parent Appointment

The first appointment in a series is the parent. All others reference it viaparent_appointment_id.

Conflict Detection

When creating a series, all occurrences are checked for conflicts. If any date/time is unavailable, the entire series creation fails with a list of conflicting dates.

Individual Updates

Each appointment in a series can be updated independently usingPUT /api/appointments/:id.

Recurrence Patterns

PatternDescriptionExample
weeklyEvery week on the same dayEvery Monday at 2pm
biweeklyEvery 2 weeksEvery other Monday
monthlyOnce per month on the same date15th of each month
customCustom interval (requires interval + interval_unit)Every 3 days, every 6 weeks

End Conditions

Specify when the series should end using either count orend_date (not both):

By Count

"recurrence": {
  "pattern": "weekly",
  "count": 10  // Create 10 appointments
}

By End Date

"recurrence": {
  "pattern": "weekly",
  "end_date": "2026-06-30"  // Until June 30
}

Cancellation Scopes

When cancelling a recurring appointment, use the scope parameter to control what gets cancelled:

single

Cancel only this appointment

Default behavior. Other appointments in the series are unaffected.

future

Cancel this and all future

Cancels the specified appointment and all later appointments in the series.

all

Cancel entire series

Cancels all scheduled/confirmed appointments in the series. Completed appointments are not affected.

Best Practices

  • Check availability first: Verify the time slot is available for all occurrences
  • Use count wisely: Maximum 52 occurrences (about 1 year of weekly appointments)
  • Store series_id: Save the series_id from the response to manage the series later
  • Notify customers: When cancelling a series, send appropriate notifications about all affected appointments

Employees

Services

AI Agent Integration

This API is designed for LLM/AI agent tool calling. Each response includes a human-readablesummaryfield that can be used directly in conversation.

// Example response with AI-friendly summary
{
  "available": true,
  "slots": [...],
  "summary": "3 slots available on January 20th: 9am with Mike, 10am with Mike, 2pm with Sarah"
}

AI-Friendly Input Handling

  • Empty strings are treated as null/omitted - safe to pass "" for optional fields
  • Array wrapper accepted - request body can be [{...}] and will be unwrapped automatically
  • Extra fields are ignored - safe to include metadata like action in requests
  • Type coercion supported - duration_minutes: "60" works as well as 60

Rate Limiting

API requests are rate limited to 100 requests per minute per API key. Exceeding this limit will result in a 429 Too Many Requests response.

n8n Integration

Use n8n to automate appointment creation from forms, chatbots, or other triggers. Here's how to set up an n8n workflow to create appointments via the B5N Booking API.

Step 1: Create a Webhook Trigger

Add a Webhook node as your trigger. This will receive data from your form, chatbot, or other source.

  • • Set HTTP Method to POST
  • • Copy the webhook URL to use in your form/chatbot
  • • The webhook will receive customer data as JSON

Step 2: Add an HTTP Request Node

Connect an HTTP Request node to call the B5N Booking API.

HTTP Request Node Settings:
━━━━━━━━━━━━━━━━━━━━━━━━━━━
Method: POST
URL: https://your-domain.com/api/appointments

Headers:
  X-API-Key: oxb_your_api_key_here
  Content-Type: application/json

Body (JSON):
{
  "start_time": "{{ $json.appointment_time }}",
  "employee_id": "{{ $json.employee_id }}",
  "customer_name": "{{ $json.customer_name }}",
  "customer_phone": "{{ $json.customer_phone }}",
  "customer_email": "{{ $json.customer_email }}",
  "service_type": "{{ $json.service_type }}",
  "notes": "{{ $json.notes }}"
}

Step 3: Example Workflow JSON

Import this workflow into n8n to get started quickly:

{
  "nodes": [
    {
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300],
      "parameters": {
        "httpMethod": "POST",
        "path": "book-appointment"
      }
    },
    {
      "name": "Create Appointment",
      "type": "n8n-nodes-base.httpRequest",
      "position": [450, 300],
      "parameters": {
        "method": "POST",
        "url": "https://your-domain.com/api/appointments",
        "headers": {
          "X-API-Key": "oxb_your_api_key_here"
        },
        "bodyParameters": {
          "start_time": "={{ $json.start_time }}",
          "employee_id": "={{ $json.employee_id }}",
          "customer_name": "={{ $json.customer_name }}",
          "customer_phone": "={{ $json.customer_phone }}"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [[{ "node": "Create Appointment", "type": "main", "index": 0 }]]
    }
  }
}

Step 4: Test Your Workflow

Send a test request to your webhook URL:

curl -X POST "https://your-n8n-instance.com/webhook/book-appointment" \
  -H "Content-Type: application/json" \
  -d '{
    "start_time": "2026-01-20T14:00:00Z",
    "employee_id": "e1111111-1111-1111-1111-111111111111",
    "customer_name": "John Smith",
    "customer_phone": "+15551234567",
    "customer_email": "john@example.com",
    "service_type": "drain-cleaning"
  }'

Pro Tips

  • • Use the /api/availability endpoint first to check available slots
  • • Store your API key in n8n Credentials for better security
  • • Add error handling nodes to notify you if booking fails
  • • Use the summary field from responses for chatbot replies

n8n AI Chat Agent (Full Integration)

Build a complete AI-powered booking assistant using n8n's chat interface and AI Agent node. This agent can answer questions about services, check employee availability, and book appointments through natural conversation.

Architecture Overview

💬
Chat Trigger
User conversation
🤖
AI Agent
OpenAI GPT-4
🔧
HTTP Tools
API integrations
📅
B5N Booking
Your API

Nodes Required

TRIGGERChat Trigger

Provides a chat interface for users. Enable "Public" to embed on your website or use the n8n chat URL directly.

AIAI Agent

The brain of your assistant. Configure with OpenAI GPT-4 and connect tools for each API endpoint.

System Prompt:

"You are a helpful booking assistant for [Company Name]. Help customers check available services, find appointment times, and book appointments. Always confirm details before booking. Be friendly and professional."

TOOLHTTP Request Tools (5 total)

Create separate HTTP Request nodes for each API capability:

get_services→ GET /api/services
get_employees→ GET /api/employees
check_availability→ GET /api/availability
book_appointment→ POST /api/appointments
lookup_appointment→ GET /api/appointments/lookup
MEMORYWindow Buffer Memory

Maintains conversation context so the agent remembers previous messages in the chat session.

Tool Configuration Examples

Each HTTP Request tool needs a description so the AI knows when to use it:

// get_services tool
Name: get_services
Description: Get a list of all available services with their names, durations, and prices. Use this when the customer asks what services are offered.

// check_availability tool
Name: check_availability
Description: Check available appointment slots for a specific date. Requires a date parameter in YYYY-MM-DD format. Optionally filter by employee_id or service_type.

// book_appointment tool
Name: book_appointment
Description: Book a new appointment. Requires: start_time (ISO format), employee_id, customer_name, customer_phone. Optional: customer_email, service_type, notes.

Sample Conversation

User:What services do you offer?
Agent:We offer the following services:
• Drain Cleaning (60 min) - $150
• Pipe Repair (90 min) - $200
• Water Heater Service (120 min) - $300
Would you like to book any of these?
User:Yes, I need drain cleaning. What's available tomorrow?
Agent:I found 3 available slots for drain cleaning tomorrow:
• 9:00 AM with Mike
• 2:00 PM with Mike
• 4:00 PM with Sarah
Which time works best for you?
User:2pm with Mike please. My name is John, phone 555-1234
Agent:I've booked your appointment:
✓ Drain Cleaning with Mike
✓ Tomorrow at 2:00 PM
✓ John - (555) 123-4567
You'll receive a confirmation. Is there anything else?

Complete Workflow JSON

Copy and import this workflow into n8n. Replace YOUR_API_URL andoxb_your_api_key with your actual values.

{
  "name": "B5N Booking AI Chat Agent",
  "nodes": [
    {
      "parameters": {
        "public": true,
        "initialMessages": "Hi! 👋 I'm your booking assistant. I can help you:\n- View our services\n- Check appointment availability\n- Book an appointment\n- Look up existing bookings\n\nHow can I help you today?",
        "options": {}
      },
      "id": "chat-trigger",
      "name": "Chat Trigger",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [0, 0]
    },
    {
      "parameters": {
        "options": {
          "systemMessage": "You are a helpful booking assistant. Help customers:\n1. Learn about available services\n2. Check appointment availability for specific dates\n3. Book new appointments\n4. Look up existing appointments by phone number\n\nAlways be friendly and professional. Confirm all details before booking. Use the provided tools to interact with the booking system. When showing availability, format times clearly. After booking, confirm all details with the customer."
        }
      },
      "id": "ai-agent",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [220, 0]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "id": "openai-chat",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1,
      "position": [0, 200]
    },
    {
      "parameters": {},
      "id": "memory",
      "name": "Window Buffer Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.2,
      "position": [140, 200]
    },
    {
      "parameters": {
        "name": "get_services",
        "description": "Get all available services with names, durations, and prices. Use when customer asks what services are offered.",
        "method": "GET",
        "url": "=YOUR_API_URL/api/services",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "id": "tool-services",
      "name": "Get Services",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "typeVersion": 1.1,
      "position": [280, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "B5N Booking API Key"
        }
      }
    },
    {
      "parameters": {
        "name": "get_employees",
        "description": "Get all employees who can perform services. Returns employee IDs and names.",
        "method": "GET",
        "url": "=YOUR_API_URL/api/employees",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "id": "tool-employees",
      "name": "Get Employees",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "typeVersion": 1.1,
      "position": [420, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "B5N Booking API Key"
        }
      }
    },
    {
      "parameters": {
        "name": "check_availability",
        "description": "Check available appointment slots. Required parameter: date (YYYY-MM-DD format). Optional: employee_id, service_type, duration_minutes. Returns available time slots.",
        "method": "GET",
        "url": "=YOUR_API_URL/api/availability",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "parametersQuery": {
          "values": [
            { "name": "date", "value": "={{ $fromAI('date', 'The date to check in YYYY-MM-DD format') }}" },
            { "name": "employee_id", "value": "={{ $fromAI('employee_id', 'Optional employee ID to filter by', '') }}" },
            { "name": "service_type", "value": "={{ $fromAI('service_type', 'Optional service type slug', '') }}" }
          ]
        },
        "options": {}
      },
      "id": "tool-availability",
      "name": "Check Availability",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "typeVersion": 1.1,
      "position": [560, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "B5N Booking API Key"
        }
      }
    },
    {
      "parameters": {
        "name": "book_appointment",
        "description": "Book a new appointment. Required: start_time (ISO 8601), employee_id (UUID), customer_name, customer_phone. Optional: customer_email, service_type, duration_minutes, notes.",
        "method": "POST",
        "url": "=YOUR_API_URL/api/appointments",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"start_time\": \"{{ $fromAI('start_time', 'Appointment start time in ISO 8601 format') }}\",\n  \"employee_id\": \"{{ $fromAI('employee_id', 'The employee UUID') }}\",\n  \"customer_name\": \"{{ $fromAI('customer_name', 'Customer full name') }}\",\n  \"customer_phone\": \"{{ $fromAI('customer_phone', 'Customer phone number with country code') }}\",\n  \"customer_email\": \"{{ $fromAI('customer_email', 'Customer email address', '') }}\",\n  \"service_type\": \"{{ $fromAI('service_type', 'Service type slug', '') }}\",\n  \"notes\": \"{{ $fromAI('notes', 'Any special notes or requests', '') }}\"\n}",
        "options": {}
      },
      "id": "tool-book",
      "name": "Book Appointment",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "typeVersion": 1.1,
      "position": [700, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "B5N Booking API Key"
        }
      }
    },
    {
      "parameters": {
        "name": "lookup_appointment",
        "description": "Look up existing appointments by customer phone number. Use when customer wants to check or manage their bookings.",
        "method": "GET",
        "url": "=YOUR_API_URL/api/appointments/lookup",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "parametersQuery": {
          "values": [
            { "name": "phone", "value": "={{ $fromAI('phone', 'Customer phone number to look up') }}" }
          ]
        },
        "options": {}
      },
      "id": "tool-lookup",
      "name": "Lookup Appointment",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "typeVersion": 1.1,
      "position": [840, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "B5N Booking API Key"
        }
      }
    }
  ],
  "connections": {
    "Chat Trigger": {
      "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]]
    },
    "Window Buffer Memory": {
      "ai_memory": [[{ "node": "AI Agent", "type": "ai_memory", "index": 0 }]]
    },
    "Get Services": {
      "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
    },
    "Get Employees": {
      "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
    },
    "Check Availability": {
      "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
    },
    "Book Appointment": {
      "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
    },
    "Lookup Appointment": {
      "ai_tool": [[{ "node": "AI Agent", "type": "ai_tool", "index": 0 }]]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

Setup Instructions

1

Create API Credential in n8n

Go to Credentials → Add → Header Auth. Name it "B5N Booking API Key". Set header name to X-API-Key and value to your API key.

2

Add OpenAI Credential

Go to Credentials → Add → OpenAI API. Enter your OpenAI API key.

3

Import the Workflow

Copy the JSON above, go to n8n → Workflows → Import from JSON. Paste and save.

4

Update API URL

Find & replace YOUR_API_URL with your actual B5N Booking URL (e.g., https://booking.yourcompany.com).

5

Activate & Test

Activate the workflow. Click "Chat" in the canvas to open the chat interface and test your booking agent!

Embedding the Chat

To embed this chat on your website, enable "Public" in the Chat Trigger settings, then use the embed code:

<script src="https://your-n8n.com/webhook/chat/embed.js"></script>
<link href="https://your-n8n.com/webhook/chat/style.css" rel="stylesheet" />
<script>
  createChat({
    webhookUrl: 'https://your-n8n.com/webhook/CHAT_ID/chat',
    theme: { primaryColor: '#22c55e' }
  });
</script>

Embed Widget

Add a booking widget to any website. The embed system includes domain-based access control to prevent unauthorized websites from embedding your booking page.

Quick Start

<div id="oxen-booking" data-slug="your-org-slug"></div>
<script src="https://your-domain.com/embed.js" async></script>

Domain Security

Control which websites can embed your booking widget via Dashboard → Settings → Embed Widget.

SettingBehavior
Public mode ON, no domainsAll domains allowed
Public mode ON + domains configuredOnly configured domains allowed
Public mode OFF + domains configuredOnly configured domains allowed
Public mode OFF, no domainsAll domains blocked (403)

Full Documentation: See the Embed Widget Documentation for configuration options, JavaScript API, callbacks, styling, and troubleshooting.

Make.com Integration

Make.com (formerly Integromat) is a visual automation platform. Use it to connect B5N Booking with hundreds of apps like Typeform, Google Forms, HubSpot, Slack, and more.

Quick Setup

1

Create HTTP Connection

In Make.com → Connections → Add HTTP with Headers. Set X-API-Key header with your API key.

2

Add HTTP Request Module

Use HTTP → Make a request module to call B5N Booking API endpoints.

3

Map Your Data

Use Make.com expressions like {{1.field}} to map form data to API parameters.

Check Availability Module

HTTP Request Module Settings:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
URL: https://your-domain.com/api/availability
Method: GET
Query String:
  - date: {{formatDate(1.requested_date; "YYYY-MM-DD")}}
  - service_type: {{1.service_type}}
Headers:
  - X-API-Key: oxb_your_api_key_here

Book Appointment Module

HTTP Request Module Settings:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
URL: https://your-domain.com/api/appointments
Method: POST
Body Type: Raw
Content Type: JSON (application/json)
Request Content:
{
  "start_time": "{{2.body.slots[1].start}}",
  "employee_id": "{{2.body.slots[1].employee.id}}",
  "customer_name": "{{1.customer_name}}",
  "customer_phone": "{{1.customer_phone}}",
  "customer_email": "{{1.customer_email}}",
  "service_type": "{{1.service_type}}"
}

Popular Scenarios

📝Form to Booking

Typeform/Google Forms → Check Availability → Book Appointment → Send Confirmation Email

🔗CRM Integration

HubSpot Deal Stage Change → Book Appointment → Update Deal with Appointment Details

📅Calendar Sync

Webhook (appointment.created) → Create Google Calendar Event → Send Slack Notification

📱SMS Reminders

Webhook (appointment.reminder) → Twilio SMS → Log to Google Sheets

Data Mapping Reference

ExpressionReturns
{{X.body.available}}true/false
{{X.body.slots[1].start}}First slot start time
{{X.body.slots[1].employee.id}}Employee ID for booking
{{X.body.summary}}Human-readable summary
{{X.body.confirmation}}Booking confirmation text

Complete Guide

For detailed instructions, example scenarios, webhook setup, and troubleshooting, see ourMake.com Integration Guide.