Appointments Endpoints
Manage appointment posts (post_type = wc_appointment) with full CRUD operations.
V1 Endpoints
List Appointments
GET /wc-appointments/v1/appointments
Get a collection of appointments.
Permissions: Published and public statuses readable. Requires authentication.
Collection Filters:
| Parameter | Type | Description |
|---|---|---|
product_id | int | Filter by product ID |
staff_id | int | Filter by staff ID; see Staff IDs Architecture |
customer_id | int | Filter by customer ID |
date_from | string | Filter from date (YYYY-MM-DD or datetime) |
date_to | string | Filter to date |
page | int | Page number |
per_page | int | Results per page |
order | string | Order direction (asc or desc) |
orderby | string | Order by field |
status | string | Filter by status |
Response Fields:
id(int)all_day(bool)cost(string/decimal)customer_id(int)date_created(datetime ISO8601)start(int, epoch seconds)end(int, epoch seconds)start_utc(int, epoch seconds)end_utc(int, epoch seconds)product_id(int)staff_ids(array<int>)status(string)qty(int)timezone(string)local_timezone(string)
Notes on UTC Fields:
start_utcandend_utcare computed by convertingstart/endto GMT using the site timezone- IANA timezone preferred (DST-aware); fixed offset used when only
gmt_offsetis set - Example: Site timezone
Europe/Berlinandstart = 1766674800yieldsstart_utc = 1766671200
Get Single Appointment
GET /wc-appointments/v1/appointments/{id}
Get a single appointment by ID.
Permissions: Requires authentication. Published appointments readable by non-store owners.
Response: Same fields as list endpoint.
Create Appointment
POST /wc-appointments/v1/appointments
Create a new appointment. If no order_id is provided, the controller auto-creates a WooCommerce order in pending state.
Permissions: Requires manage_woocommerce capability.
Required Fields:
product_id(int): ID of the appointable productstart(int|string): UNIX timestamp orstrtotime-parseable stringend(int|string): UNIX timestamp orstrtotime-parseable string
Optional Fields:
status(string): Appointment status (see Statuses section)customer_id(int)qty(int, default 1)all_day(bool)staff_id(int) orstaff_ids(array<int>); see Staff IDs Architecturecost(number): Line amount for appointment itemcost_includes_tax(bool, defaultfalse): Whether cost includes taxtimezone(string),local_timezone(string)start_human(string),end_human(string): Human-readable datetimes (parsed in UTC)order_id(int): If provided, auto-order creation is skippedgoogle_calendar_event_id(string)google_calendar_staff_event_ids(array<string>)meta_data(array):{ key, value, id? }entries
Behavior:
- When
order_idis omitted, creates a WooCommerce order with the product as a line item - If
costis missing, uses product's current price - Taxes calculated with product's tax class
- If only
startorendprovided, missing value inferred from product duration - Human-readable times parsed in UTC and converted to UNIX timestamps
- Response includes
order_idandorder_item_id
Example: Tax-inclusive cost
POST /wp-json/wc-appointments/v2/appointments
{
"status": "confirmed",
"product_id": 1234,
"customer_id": 5678,
"start": "2025-12-01 10:00",
"end": "2025-12-01 11:00",
"qty": 2,
"cost": 120.00,
"cost_includes_tax": true,
"timezone": "UTC"
}
Example: Tax-exclusive cost
POST /wp-json/wc-appointments/v2/appointments
{
"product_id": 1234,
"start": 1733044800,
"end": 1733048400,
"qty": 1,
"cost": 100.00,
"cost_includes_tax": false
}
Example: Provide only start (infer end)
POST /wp-json/wc-appointments/v2/appointments
{
"product_id": 1234,
"start_human": "2025-12-01 10:00",
"qty": 1
}
If the product duration is 1 hour, the API stores end as 2025-12-01 11:00 in the site's timezone.
Example: Provide only end (infer start)
POST /wp-json/wc-appointments/v2/appointments
{
"product_id": 1234,
"end": 1733048400,
"qty": 1
}
If the product duration is 30 minutes, the API stores start = 1733048400 - 1800.
Update Appointment
PUT|PATCH /wc-appointments/v1/appointments/{id}
Update an existing appointment.
Permissions: Requires manage_woocommerce capability.
Fields: Same as create endpoint. Only provided fields are updated.
Status Validation:
- Validates status transitions on update
- Valid values:
unpaid,pending-confirmation,confirmed,paid,cancelled - Invalid values return error code
woocommerce_appointments_invalid_statuswith HTTP 400
Example:
PATCH /wp-json/wc-appointments/v1/appointments/123
{
"status": "cancelled"
}
Delete Appointment
DELETE /wc-appointments/v1/appointments/{id}
Delete an appointment.
Permissions: Requires manage_woocommerce capability.
Response: Deleted appointment object or error.
Batch Operations
POST /wc-appointments/v1/appointments/batch
Perform batch create, update, or delete operations.
Permissions: Requires manage_woocommerce capability.
Request Body:
{
"create": [
{ /* appointment data */ }
],
"update": [
{ "id": 123, /* fields to update */ }
],
"delete": [ 456, 789 ]
}
V2 Endpoints
Same as V1
All V1 endpoints are available under wc-appointments/v2 namespace with the same functionality.
Additional Response Fields (V2 only):
cal_color(string): Calendar color for the appointment product (defaults to#0073aa)customer_first_name(string): Customer first namecustomer_last_name(string): Customer last namecustomer_full_name(string): Customer full name (first + last)customer_name(string): Customer display name
Notes:
- These additional fields are read-only and computed from related data
- Included to optimize admin calendar performance by eliminating separate API calls
- For occurrence reads at scale, prefer
GET /wc-appointments/v2/index
Appointment Statuses
Internal Statuses
unpaid- Appointment not yet paidpending-confirmation- Awaiting confirmationconfirmed- Confirmed appointmentpaid- Payment receivedcancelled- Cancelled appointmentcomplete- Completed appointmentin-cart- Currently in shopping cartwas-in-cart- Was in cart but removed
Customer Statuses
expected- Customer expected to arrivearrived- Customer has arrivedno-show- Customer did not show up
Status Validation
Update Validation:
- Incoming
statusvalues validated againstget_wc_appointment_statuses('validate') - Valid update values:
unpaid,pending-confirmation,confirmed,paid,cancelled - Invalid values return error code
woocommerce_appointments_invalid_statuswith HTTP 400
Extensibility:
- Filter
woocommerce_appointment_statuses_for_validation- Add/remove allowed update statuses - Filter
woocommerce_appointment_statuses_for_user- Control statuses shown to users - Filter
woocommerce_appointments_get_wc_appointment_statuses- Global status adjustment
Related Documentation
- Staff IDs Architecture - Understanding staff_id vs staff_ids
- Slots Endpoints - Get available slots
- Index Endpoint - For precomputed availability