Spaces:
Running
Running
E-commerce Appointments API Quick Reference
Base URL
/appointments
Endpoints
1. Book Appointment
POST /appointments/book
Request:
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"start_time": "14:00",
"services": [
{
"service_id": "service_123",
"service_name": "Hair Cut & Styling",
"duration_minutes": 60,
"price": 500.0,
"staff_id": "staff_456",
"staff_name": "John Doe"
}
],
"customer_name": "Jane Smith",
"customer_phone": "+919876543210",
"customer_email": "jane@example.com",
"notes": "First time customer"
}
Response:
{
"success": true,
"message": "Appointment booked successfully",
"appointment": {
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_id": "customer_123",
"status": "booked",
...
}
}
2. Get Appointment
GET /appointments/{appointment_id}
Response:
{
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_id": "customer_123",
"customer_name": "Jane Smith",
"customer_phone": "+919876543210",
"appointment_date": "2026-02-10",
"start_time": "14:00",
"end_time": "15:00",
"total_duration": 60,
"services": [...],
"status": "booked",
"total_amount": 500.0,
"currency": "INR"
}
3. List Appointments (Standard with Projection Support)
POST /appointments/list
Request (Full Response):
{
"merchant_id": "5starsaloon",
"status": "booked",
"from_date": "2026-02-01",
"to_date": "2026-02-28",
"limit": 20,
"offset": 0
}
Request (With Projection - Minimal Response):
{
"merchant_id": "5starsaloon",
"status": "booked",
"limit": 20,
"offset": 0,
"projection_list": ["appointment_id", "customer_name", "start_time", "status"]
}
Response (Full):
{
"appointments": [
{
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_name": "Jane Smith",
...
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
Response (With Projection):
{
"items": [
{
"appointment_id": "uuid",
"customer_name": "Jane Smith",
"start_time": "2026-02-10T14:00:00",
"status": "booked"
}
],
"total": 5,
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
4. Get Available Slots
POST /appointments/available-slots
Request:
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"service_duration": 60,
"staff_id": "staff_456"
}
Response:
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"slots": [
{
"start_time": "09:00",
"end_time": "09:30",
"available": true
},
{
"start_time": "09:30",
"end_time": "10:00",
"available": false
}
],
"business_hours": {
"open": "09:00",
"close": "18:00"
}
}
5. Cancel Appointment
DELETE /appointments/{appointment_id}/cancel
Request:
{
"cancellation_reason": "Customer requested reschedule"
}
Response:
{
"success": true,
"message": "Appointment cancelled successfully",
"appointment": {
"appointment_id": "uuid",
"status": "cancelled",
...
}
}
6. Get My Appointments
GET /appointments/customer/my-appointments?limit=20&offset=0
Response:
{
"appointments": [...],
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
Filter Options for List Endpoint
| Filter | Type | Description |
|---|---|---|
merchant_id |
string | Filter by merchant |
customer_id |
string | Filter by customer |
appointment_date |
date | Filter by specific date |
status |
enum | Filter by status (booked, confirmed, cancelled, completed, no_show) |
from_date |
date | Filter from date (inclusive) |
to_date |
date | Filter to date (inclusive) |
limit |
int | Max records (1-100, default: 20) |
offset |
int | Records to skip (default: 0) |
projection_list |
array | Fields to include (optional) |
Projection List Fields
Available fields for projection:
appointment_idmerchant_idcustomer_idcustomer_namecustomer_phonestatusstart_timeend_timenotescreated_by
Note: When using projection_list, services are NOT included. Use full response to get service details.
Status Values
| Status | Description |
|---|---|
booked |
Initial state when customer books |
confirmed |
Merchant confirms the booking |
cancelled |
Customer or merchant cancels |
completed |
Service completed |
billed |
Payment processed (POS only) |
no_show |
Customer didn't show up |
Error Responses
400 Bad Request
{
"detail": "Appointment time must be in the future"
}
404 Not Found
{
"detail": "Appointment not found"
}
500 Internal Server Error
{
"detail": "Failed to book appointment"
}
Performance Tips
Use Projection List: Reduce payload size by 50-90%
{ "projection_list": ["appointment_id", "customer_name", "start_time"] }Limit Results: Use pagination for large datasets
{ "limit": 10, "offset": 0 }Filter Wisely: Use specific filters to reduce query time
{ "merchant_id": "5starsaloon", "appointment_date": "2026-02-10", "status": "booked" }
Integration Examples
React/Next.js
// Book appointment
const response = await fetch('/appointments/book', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
merchant_id: '5starsaloon',
appointment_date: '2026-02-10',
start_time: '14:00',
services: [{ service_id: 'svc_123', ... }],
customer_name: 'Jane Smith',
customer_phone: '+919876543210'
})
});
// List with projection
const response = await fetch('/appointments/list', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
merchant_id: '5starsaloon',
limit: 10,
projection_list: ['appointment_id', 'customer_name', 'start_time']
})
});
Python
import requests
# Book appointment
response = requests.post(
'http://localhost:8000/appointments/book',
json={
'merchant_id': '5starsaloon',
'appointment_date': '2026-02-10',
'start_time': '14:00',
'services': [{'service_id': 'svc_123', ...}],
'customer_name': 'Jane Smith',
'customer_phone': '+919876543210'
}
)
# List with projection
response = requests.post(
'http://localhost:8000/appointments/list',
json={
'merchant_id': '5starsaloon',
'limit': 10,
'projection_list': ['appointment_id', 'customer_name', 'start_time']
}
)
Notes
- All timestamps are in UTC
- Customer authentication via JWT (TODO: implement)
- Shared database with POS appointments
- Source field automatically set to 'online'
- Booking channel automatically set to 'app'