cuatrolabs-ecomm-ms / APPOINTMENTS_API_QUICK_REF.md
MukeshKapoor25's picture
docs(appointments): Add API quick reference and PostgreSQL migration guide
2e76228

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_id
  • merchant_id
  • customer_id
  • customer_name
  • customer_phone
  • status
  • start_time
  • end_time
  • notes
  • created_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

  1. Use Projection List: Reduce payload size by 50-90%

    {
      "projection_list": ["appointment_id", "customer_name", "start_time"]
    }
    
  2. Limit Results: Use pagination for large datasets

    {
      "limit": 10,
      "offset": 0
    }
    
  3. 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'