Appointments
Appointment management. All endpoints require authentication.
Appointment Statuses (AASM)
confirmed → in_progress → completed → reviewed
↘ cancelled (terminal)
↘ no_show (terminal)
Initial status when created: confirmed.
Create Appointment
POST /api/v1/appointments
Create an appointment. The client books a slot.
Request
{
"appointment": {
"salon_id": "uuid",
"service_id": "uuid",
"master_id": "uuid",
"starts_at": "2026-04-07T10:00:00Z"
}
}
| Field | Required | Description |
|---|---|---|
salon_id | Yes | |
service_id | Yes | |
master_id | Yes | |
starts_at | Yes | ISO 8601, UTC |
Response 201
{
"success": true,
"status": "201",
"message": "Appointment created successfully",
"errors": null,
"data": {
"id": "uuid",
"status": "confirmed",
"starts_at": "2026-04-07T10:00:00Z",
"ends_at": "2026-04-07T10:30:00Z",
"total_amount": "150.0",
"salon": {
"salon_id": "uuid",
"name": "Barber House",
"address": "str. Pushkin 12"
},
"master": {
"master_id": "uuid",
"name": "Ion Popescu"
},
"service": {
"service_id": "uuid",
"name": "Men's Haircut",
"price_snapshot": "150.0",
"duration_min": 30
}
}
}
Get Appointment
GET /api/v1/appointments/:id
Details of a specific appointment. Accessible only to participants (client, master, salon owner, admin).
Response 200
Same body as POST /api/v1/appointments response.
Confirm Appointment
PATCH /api/v1/appointments/:id/confirm
Manually confirm an appointment. Salon owner or master only.
Currently appointments are created with status
confirmed. This endpoint is reserved for future manual confirmation.
Response 200
{
"success": true,
"status": "200",
"message": "Appointment confirmed successfully",
"errors": null,
"data": { ... }
}
Cancel Appointment
PATCH /api/v1/appointments/:id/cancel
Cancel an appointment. Available to client, master, and owner.
For clients, the cancellation policy (cancellation_hours_before) is enforced. Owner and admin can cancel without restrictions.
Response 200
{
"success": true,
"status": "200",
"message": "Appointment cancelled successfully",
"errors": null,
"data": { ... }
}
Complete Appointment
PATCH /api/v1/appointments/:id/complete
Mark an appointment as completed. Salon owner or master only.
Response 200
{
"success": true,
"status": "200",
"message": "Appointment completed successfully",
"errors": null,
"data": { ... }
}
Mark as No-show
PATCH /api/v1/appointments/:id/no_show
Mark the client as a no-show. Salon owner or master only.
Response 200
{
"success": true,
"status": "200",
"message": "Appointment marked as no-show",
"errors": null,
"data": { ... }
}
Submit Review
POST /api/v1/appointments/:id/review
Submit a review after an appointment is completed. Client only, after status completed.
After successful submission the appointment transitions to status reviewed.
Request
{
"review": {
"rating": 5,
"body": "Great master, will come again!"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
rating | integer | Yes | From 1 to 5 |
body | string | No | Review text |
Response 201
{
"success": true,
"status": "201",
"message": "Review submitted successfully",
"errors": null,
"data": {
"id": "uuid",
"rating": 5,
"body": "Great master, will come again!",
"created_at": "2026-04-07T11:00:00Z"
}
}
Response 422 — Appointment not completed
{
"success": false,
"status": "422",
"message": "Validation failed",
"errors": {
"appointment": ["must be completed before review"]
},
"data": null
}