Skip to main content

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:

ParameterTypeDescription
product_idintFilter by product ID
staff_idintFilter by staff ID; see Staff IDs Architecture
customer_idintFilter by customer ID
date_fromstringFilter from date (YYYY-MM-DD or datetime)
date_tostringFilter to date
pageintPage number
per_pageintResults per page
orderstringOrder direction (asc or desc)
orderbystringOrder by field
statusstringFilter 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_utc and end_utc are computed by converting start/end to GMT using the site timezone
  • IANA timezone preferred (DST-aware); fixed offset used when only gmt_offset is set
  • Example: Site timezone Europe/Berlin and start = 1766674800 yields start_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 product
  • start (int|string): UNIX timestamp or strtotime-parseable string
  • end (int|string): UNIX timestamp or strtotime-parseable string

Optional Fields:

  • status (string): Appointment status (see Statuses section)
  • customer_id (int)
  • qty (int, default 1)
  • all_day (bool)
  • staff_id (int) or staff_ids (array<int>); see Staff IDs Architecture
  • cost (number): Line amount for appointment item
  • cost_includes_tax (bool, default false): Whether cost includes tax
  • timezone (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 skipped
  • google_calendar_event_id (string)
  • google_calendar_staff_event_ids (array<string>)
  • meta_data (array): { key, value, id? } entries

Behavior:

  • When order_id is omitted, creates a WooCommerce order with the product as a line item
  • If cost is missing, uses product's current price
  • Taxes calculated with product's tax class
  • If only start or end provided, missing value inferred from product duration
  • Human-readable times parsed in UTC and converted to UNIX timestamps
  • Response includes order_id and order_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_status with 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 name
  • customer_last_name (string): Customer last name
  • customer_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 paid
  • pending-confirmation - Awaiting confirmation
  • confirmed - Confirmed appointment
  • paid - Payment received
  • cancelled - Cancelled appointment
  • complete - Completed appointment
  • in-cart - Currently in shopping cart
  • was-in-cart - Was in cart but removed

Customer Statuses

  • expected - Customer expected to arrive
  • arrived - Customer has arrived
  • no-show - Customer did not show up

Status Validation

Update Validation:

  • Incoming status values validated against get_wc_appointment_statuses('validate')
  • Valid update values: unpaid, pending-confirmation, confirmed, paid, cancelled
  • Invalid values return error code woocommerce_appointments_invalid_status with 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