Spaces:
Running
Running
| # E-commerce Appointments API Quick Reference | |
| ## Base URL | |
| ``` | |
| /appointments | |
| ``` | |
| ## Endpoints | |
| ### 1. Book Appointment | |
| ```http | |
| POST /appointments/book | |
| ``` | |
| **Request:** | |
| ```json | |
| { | |
| "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:** | |
| ```json | |
| { | |
| "success": true, | |
| "message": "Appointment booked successfully", | |
| "appointment": { | |
| "appointment_id": "uuid", | |
| "merchant_id": "5starsaloon", | |
| "customer_id": "customer_123", | |
| "status": "booked", | |
| ... | |
| } | |
| } | |
| ``` | |
| --- | |
| ### 2. Get Appointment | |
| ```http | |
| GET /appointments/{appointment_id} | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "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) | |
| ```http | |
| POST /appointments/list | |
| ``` | |
| **Request (Full Response):** | |
| ```json | |
| { | |
| "merchant_id": "5starsaloon", | |
| "status": "booked", | |
| "from_date": "2026-02-01", | |
| "to_date": "2026-02-28", | |
| "limit": 20, | |
| "offset": 0 | |
| } | |
| ``` | |
| **Request (With Projection - Minimal Response):** | |
| ```json | |
| { | |
| "merchant_id": "5starsaloon", | |
| "status": "booked", | |
| "limit": 20, | |
| "offset": 0, | |
| "projection_list": ["appointment_id", "customer_name", "start_time", "status"] | |
| } | |
| ``` | |
| **Response (Full):** | |
| ```json | |
| { | |
| "appointments": [ | |
| { | |
| "appointment_id": "uuid", | |
| "merchant_id": "5starsaloon", | |
| "customer_name": "Jane Smith", | |
| ... | |
| } | |
| ], | |
| "pagination": { | |
| "limit": 20, | |
| "offset": 0, | |
| "total": 5 | |
| } | |
| } | |
| ``` | |
| **Response (With Projection):** | |
| ```json | |
| { | |
| "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 | |
| ```http | |
| POST /appointments/available-slots | |
| ``` | |
| **Request:** | |
| ```json | |
| { | |
| "merchant_id": "5starsaloon", | |
| "appointment_date": "2026-02-10", | |
| "service_duration": 60, | |
| "staff_id": "staff_456" | |
| } | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "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 | |
| ```http | |
| DELETE /appointments/{appointment_id}/cancel | |
| ``` | |
| **Request:** | |
| ```json | |
| { | |
| "cancellation_reason": "Customer requested reschedule" | |
| } | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "success": true, | |
| "message": "Appointment cancelled successfully", | |
| "appointment": { | |
| "appointment_id": "uuid", | |
| "status": "cancelled", | |
| ... | |
| } | |
| } | |
| ``` | |
| --- | |
| ### 6. Get My Appointments | |
| ```http | |
| GET /appointments/customer/my-appointments?limit=20&offset=0 | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "detail": "Appointment time must be in the future" | |
| } | |
| ``` | |
| ### 404 Not Found | |
| ```json | |
| { | |
| "detail": "Appointment not found" | |
| } | |
| ``` | |
| ### 500 Internal Server Error | |
| ```json | |
| { | |
| "detail": "Failed to book appointment" | |
| } | |
| ``` | |
| --- | |
| ## Performance Tips | |
| 1. **Use Projection List**: Reduce payload size by 50-90% | |
| ```json | |
| { | |
| "projection_list": ["appointment_id", "customer_name", "start_time"] | |
| } | |
| ``` | |
| 2. **Limit Results**: Use pagination for large datasets | |
| ```json | |
| { | |
| "limit": 10, | |
| "offset": 0 | |
| } | |
| ``` | |
| 3. **Filter Wisely**: Use specific filters to reduce query time | |
| ```json | |
| { | |
| "merchant_id": "5starsaloon", | |
| "appointment_date": "2026-02-10", | |
| "status": "booked" | |
| } | |
| ``` | |
| --- | |
| ## Integration Examples | |
| ### React/Next.js | |
| ```typescript | |
| // 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 | |
| ```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' | |