Skip to main content

Services

Services are what clients book (appointments and classes) or buy. A service has a price, a duration, the team members who deliver it, and optionally variants (for example 60 and 90 minutes at different prices), a sale price and a deposit.

  • Your own id: send externalId and POST /v1/services with the same externalId updates that service, so you can sync a catalogue without storing our ids.
  • Partial updates: PUT and upserts change only the fields you send.
  • Delete archives: the service is hidden from lists and booking, and kept for past bookings and invoices.
  • Plan: creating and changing services needs the Bookings or Sales add-on.
API regionapi.whautomate.com

List services​

GET /v1/services

Lists services (not archived), newest update first. externalId finds the service with your own id.

Headers
x-api-keystringrequired
Your Whautomate API key.
Query parameters
locationIdstring
Location (workspace) id. Get ids from GET /v1/locations.
limitinteger
Results per page (default 10, max 100).
pageinteger
Page number, from 1 (default 1).
serviceTypestring
Only services of this type, for example APPOINTMENT or CLASS.
searchTextstring
Text to search for.
externalIdstring
Your own id for the record.
Response 200
idstring
externalIdstring
Your own id for the service (1 to 200 characters, unique in the account; null when not set). POST with a known externalId updates that service. Send an empty string to clear it.
serviceTypestring (enum)required
One of: APPOINTMENT, CLASS, ADD_ON.
namestringrequired
locationobjectrequired
durationMinutesinteger
categoriesobject[]
staffsobject[]
numberOfParticipantsnumber
typestring (enum)
One of: LOCATION_VISIT, HOME_VISIT, VIRTUAL_SESSION.
sellingPricenumberrequired
Price charged. For a service with variants this mirrors the first variant.
regularPricenumber
Regular price shown struck through next to sellingPrice (a sale price anchor). Returned only when set. Send 0 to remove it (a value not above sellingPrice is not kept).
variantsobject[]

Variants of the service, priced by duration and staff. Returned only when the service has variants. On create or update, omit to keep the current variants, send [] to remove them all. The first variant is mirrored into sellingPrice and durationMinutes. Invalid variants return 400 with a message.

currencystring
Account currency from Business Settings, e.g. USD
taxOverridesobject[]
creditsPerBookinginteger
Credits one booking takes from a client's credit balance; null = the client's credits are not applied to this service automatically. Session packs always use 1 session. Peak pricing rules can add extra credits at booking time.
isCustomCreditboolean
Older form of creditsPerBooking (true when it is set)
creditsinteger
Older form of creditsPerBooking
activeboolean
allowOnlineBookingboolean
acceptPaymentOnlineboolean
paymentCollectionstring (enum)
FULL (default) charges the booking total online; DEPOSIT charges only a deposit (needs acceptPaymentOnline true, depositType and depositValue). The balance stays on a PENDING invoice. One of: FULL, DEPOSIT.
depositTypestring (enum)
FIXED (an amount, capped at the total) or PERCENTAGE (of the booking total, up to 100). One of: FIXED, PERCENTAGE.
depositValuenumber
Deposit amount or percentage, more than 0.
advanceSettingsobject
addOnAppliesTostring (enum)
One of: SELECTED_SERVICES, ALL_SERVICES.
addOnServicesobject[]
sortOrderinteger
createdAtstring
updatedAtstring
createdboolean
POST and PUT responses only: true when the call created the service
Request
curl -X GET "https://api.whautomate.com/v1/services?locationId=Le6dWjQF9K&serviceType=APPOINTMENT&limit=3" \
-H "x-api-key: YOUR_API_KEY"
Response 200
[
{
"id": "5z1k6h86AG",
"externalId": null,
"serviceType": "APPOINTMENT",
"name": "Signature Facial",
"location": {
"id": "Le6dWjQF9K",
"title": "Serene Wellness Studio"
},
"durationMinutes": 45,
"categories": [],
"staffs": [
{
"id": "XCRbjjnGrB",
"name": "Maya Lim"
}
],
"type": "LOCATION_VISIT",
"sellingPrice": 95,
"currency": "SGD",
"taxOverrides": [],
"creditsPerBooking": 3,
"isCustomCredit": true,
"credits": 3,
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": true,
"paymentCollection": "DEPOSIT",
"depositType": "PERCENTAGE",
"depositValue": 25,
"advanceSettings": {},
"sortOrder": 5,
"createdAt": "2026-10-29T11:42:18.891Z",
"updatedAt": "2026-10-29T11:43:42.036Z"
},
{
"id": "zMTqZwoHi1",
"externalId": null,
"serviceType": "APPOINTMENT",
"name": "Aromatherapy Massage",
"location": {
"id": "Le6dWjQF9K",
"title": "Serene Wellness Studio"
},
"durationMinutes": 60,
"categories": [],
"staffs": [
{
"id": "XCRbjjnGrB",
"name": "Maya Lim"
},
{
"id": "ZxkrjyVgDE",
"name": "Aisha Rahman"
}
],
"type": "LOCATION_VISIT",
"sellingPrice": 110,
"currency": "SGD",
"taxOverrides": [],
"creditsPerBooking": 4,
"isCustomCredit": true,
"credits": 4,
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": false,
"paymentCollection": "FULL",
"advanceSettings": {},
"sortOrder": 4,
"createdAt": "2026-10-29T11:42:18.868Z",
"updatedAt": "2026-10-29T11:43:41.976Z"
}
]

Get a service​

GET /v1/services/{serviceId}

Gets a service by id (404 when unknown).

Headers
x-api-keystringrequired
Your Whautomate API key.
Path parameters
serviceIdstringrequired
Service id. Get ids from GET /v1/services.
Response 200
idstring
externalIdstring
Your own id for the service (1 to 200 characters, unique in the account; null when not set). POST with a known externalId updates that service. Send an empty string to clear it.
serviceTypestring (enum)required
One of: APPOINTMENT, CLASS, ADD_ON.
namestringrequired
locationobjectrequired
durationMinutesinteger
categoriesobject[]
staffsobject[]
numberOfParticipantsnumber
typestring (enum)
One of: LOCATION_VISIT, HOME_VISIT, VIRTUAL_SESSION.
sellingPricenumberrequired
Price charged. For a service with variants this mirrors the first variant.
regularPricenumber
Regular price shown struck through next to sellingPrice (a sale price anchor). Returned only when set. Send 0 to remove it (a value not above sellingPrice is not kept).
variantsobject[]

Variants of the service, priced by duration and staff. Returned only when the service has variants. On create or update, omit to keep the current variants, send [] to remove them all. The first variant is mirrored into sellingPrice and durationMinutes. Invalid variants return 400 with a message.

currencystring
Account currency from Business Settings, e.g. USD
taxOverridesobject[]
creditsPerBookinginteger
Credits one booking takes from a client's credit balance; null = the client's credits are not applied to this service automatically. Session packs always use 1 session. Peak pricing rules can add extra credits at booking time.
isCustomCreditboolean
Older form of creditsPerBooking (true when it is set)
creditsinteger
Older form of creditsPerBooking
activeboolean
allowOnlineBookingboolean
acceptPaymentOnlineboolean
paymentCollectionstring (enum)
FULL (default) charges the booking total online; DEPOSIT charges only a deposit (needs acceptPaymentOnline true, depositType and depositValue). The balance stays on a PENDING invoice. One of: FULL, DEPOSIT.
depositTypestring (enum)
FIXED (an amount, capped at the total) or PERCENTAGE (of the booking total, up to 100). One of: FIXED, PERCENTAGE.
depositValuenumber
Deposit amount or percentage, more than 0.
advanceSettingsobject
addOnAppliesTostring (enum)
One of: SELECTED_SERVICES, ALL_SERVICES.
addOnServicesobject[]
sortOrderinteger
createdAtstring
updatedAtstring
createdboolean
POST and PUT responses only: true when the call created the service
Request
curl -X GET "https://api.whautomate.com/v1/services/NzzoDETgKg" \
-H "x-api-key: YOUR_API_KEY"
Response 200
{
"id": "NzzoDETgKg",
"externalId": null,
"serviceType": "APPOINTMENT",
"name": "Physiotherapy Consultation",
"location": {
"id": "Le6dWjQF9K",
"title": "Serene Wellness Studio"
},
"durationMinutes": 45,
"categories": [],
"staffs": [
{
"id": "XCRbjjnGrB",
"name": "Maya Lim"
},
{
"id": "XrHPepEL8A",
"name": "Wei Jie Tan"
}
],
"type": "LOCATION_VISIT",
"sellingPrice": 130,
"currency": "SGD",
"taxOverrides": [],
"creditsPerBooking": null,
"credits": 0,
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": false,
"paymentCollection": "FULL",
"advanceSettings": {},
"sortOrder": 6,
"createdAt": "2026-10-29T11:42:18.911Z",
"updatedAt": "2026-10-29T11:42:18.911Z"
}

Create or update a service​

POST /v1/services

Creates a service, or updates the service with the same externalId (only the fields sent change). Response includes created. The body (ServiceUpsertRequest) has no required fields at the gateway, so an update by externalId may send only the fields that change; creating needs serviceType, name, location (or locationId), sellingPrice and active (bookable services also staffs, durationMinutes, allowOnlineBooking, acceptPaymentOnline), checked by the backend (400 Invalid parameters). Needs the Bookings or Sales module.

Headers
x-api-keystringrequired
Your Whautomate API key.
Body
externalIdstring
Your own id (1 to 200 characters, unique in the account). A known externalId updates that service. Send an empty string to clear it.
serviceTypestring (enum)
One of: APPOINTMENT, CLASS, ADD_ON.
namestring
locationobject

Location of a new service. A service cannot move to another location.

locationIdstring
Alternative to location.id
durationMinutesinteger
numberOfParticipantsnumber
Classes
typestring (enum)
One of: LOCATION_VISIT, HOME_VISIT, VIRTUAL_SESSION.
sellingPricenumber
regularPricenumber
Sale anchor shown struck through next to sellingPrice. Send 0 to remove it.
variantsobject[]

Omit to keep the current variants, send [] to remove them all

taxOverridesobject[]

Tax ids; replaces the list

creditsPerBookinginteger
Credits one booking takes from a client's credit balance; null = the client's credits are not applied to this service automatically. Session packs always use 1 session. Peak pricing rules can add extra credits at booking time.
isCustomCreditboolean
Older form of creditsPerBooking (true when it is set)
creditsinteger
Older form of creditsPerBooking
activeboolean
allowOnlineBookingboolean
acceptPaymentOnlineboolean
paymentCollectionstring (enum)
FULL (default) charges the booking total online; DEPOSIT charges only a deposit (needs acceptPaymentOnline true, depositType and depositValue). The balance stays on a PENDING invoice. One of: FULL, DEPOSIT.
depositTypestring (enum)
FIXED (an amount, capped at the total) or PERCENTAGE (of the booking total, up to 100). One of: FIXED, PERCENTAGE.
depositValuenumber
Deposit amount or percentage, more than 0.
staffsobject[]

Staff ids; replaces the list

categoriesobject[]

Service category ids; replaces the list

addOnAppliesTostring (enum)
One of: SELECTED_SERVICES, ALL_SERVICES.
addOnServicesobject[]

Add-on target service ids

advanceSettingsobject
sortOrderinteger
Response 200
idstring
externalIdstring
Your own id for the service (1 to 200 characters, unique in the account; null when not set). POST with a known externalId updates that service. Send an empty string to clear it.
serviceTypestring (enum)required
One of: APPOINTMENT, CLASS, ADD_ON.
namestringrequired
locationobjectrequired
durationMinutesinteger
categoriesobject[]
staffsobject[]
numberOfParticipantsnumber
typestring (enum)
One of: LOCATION_VISIT, HOME_VISIT, VIRTUAL_SESSION.
sellingPricenumberrequired
Price charged. For a service with variants this mirrors the first variant.
regularPricenumber
Regular price shown struck through next to sellingPrice (a sale price anchor). Returned only when set. Send 0 to remove it (a value not above sellingPrice is not kept).
variantsobject[]

Variants of the service, priced by duration and staff. Returned only when the service has variants. On create or update, omit to keep the current variants, send [] to remove them all. The first variant is mirrored into sellingPrice and durationMinutes. Invalid variants return 400 with a message.

currencystring
Account currency from Business Settings, e.g. USD
taxOverridesobject[]
creditsPerBookinginteger
Credits one booking takes from a client's credit balance; null = the client's credits are not applied to this service automatically. Session packs always use 1 session. Peak pricing rules can add extra credits at booking time.
isCustomCreditboolean
Older form of creditsPerBooking (true when it is set)
creditsinteger
Older form of creditsPerBooking
activeboolean
allowOnlineBookingboolean
acceptPaymentOnlineboolean
paymentCollectionstring (enum)
FULL (default) charges the booking total online; DEPOSIT charges only a deposit (needs acceptPaymentOnline true, depositType and depositValue). The balance stays on a PENDING invoice. One of: FULL, DEPOSIT.
depositTypestring (enum)
FIXED (an amount, capped at the total) or PERCENTAGE (of the booking total, up to 100). One of: FIXED, PERCENTAGE.
depositValuenumber
Deposit amount or percentage, more than 0.
advanceSettingsobject
addOnAppliesTostring (enum)
One of: SELECTED_SERVICES, ALL_SERVICES.
addOnServicesobject[]
sortOrderinteger
createdAtstring
updatedAtstring
createdboolean
POST and PUT responses only: true when the call created the service
Request
curl -X POST "https://api.whautomate.com/v1/services" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"serviceType": "APPOINTMENT",
"name": "Hot Stone Massage",
"locationId": "Le6dWjQF9K",
"durationMinutes": 75,
"sellingPrice": 140,
"regularPrice": 160,
"staffs": [
{
"id": "ZxkrjyVgDE"
}
],
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": false,
"externalId": "svc-hot-stone-75"
}'
Response 200
{
"created": true,
"id": "0zJd3wC2yO",
"externalId": "svc-hot-stone-75",
"serviceType": "APPOINTMENT",
"name": "Hot Stone Massage",
"location": {
"id": "Le6dWjQF9K",
"title": "Serene Wellness Studio"
},
"durationMinutes": 75,
"categories": [],
"staffs": [
{
"id": "ZxkrjyVgDE",
"name": "Aisha Rahman"
}
],
"type": "",
"sellingPrice": 140,
"regularPrice": 160,
"currency": "SGD",
"taxOverrides": [],
"creditsPerBooking": null,
"credits": 0,
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": false,
"paymentCollection": "FULL",
"advanceSettings": {},
"sortOrder": 16,
"createdAt": "2026-10-29T12:40:09.467Z",
"updatedAt": "2026-10-29T12:40:09.467Z"
}

Update a service​

PUT /v1/services/{serviceId}

Updates a service; only the fields sent change. Response includes created (false). Needs the Bookings or Sales module.

Headers
x-api-keystringrequired
Your Whautomate API key.
Path parameters
serviceIdstringrequired
Service id. Get ids from GET /v1/services.
Response 200
idstring
externalIdstring
Your own id for the service (1 to 200 characters, unique in the account; null when not set). POST with a known externalId updates that service. Send an empty string to clear it.
serviceTypestring (enum)required
One of: APPOINTMENT, CLASS, ADD_ON.
namestringrequired
locationobjectrequired
durationMinutesinteger
categoriesobject[]
staffsobject[]
numberOfParticipantsnumber
typestring (enum)
One of: LOCATION_VISIT, HOME_VISIT, VIRTUAL_SESSION.
sellingPricenumberrequired
Price charged. For a service with variants this mirrors the first variant.
regularPricenumber
Regular price shown struck through next to sellingPrice (a sale price anchor). Returned only when set. Send 0 to remove it (a value not above sellingPrice is not kept).
variantsobject[]

Variants of the service, priced by duration and staff. Returned only when the service has variants. On create or update, omit to keep the current variants, send [] to remove them all. The first variant is mirrored into sellingPrice and durationMinutes. Invalid variants return 400 with a message.

currencystring
Account currency from Business Settings, e.g. USD
taxOverridesobject[]
creditsPerBookinginteger
Credits one booking takes from a client's credit balance; null = the client's credits are not applied to this service automatically. Session packs always use 1 session. Peak pricing rules can add extra credits at booking time.
isCustomCreditboolean
Older form of creditsPerBooking (true when it is set)
creditsinteger
Older form of creditsPerBooking
activeboolean
allowOnlineBookingboolean
acceptPaymentOnlineboolean
paymentCollectionstring (enum)
FULL (default) charges the booking total online; DEPOSIT charges only a deposit (needs acceptPaymentOnline true, depositType and depositValue). The balance stays on a PENDING invoice. One of: FULL, DEPOSIT.
depositTypestring (enum)
FIXED (an amount, capped at the total) or PERCENTAGE (of the booking total, up to 100). One of: FIXED, PERCENTAGE.
depositValuenumber
Deposit amount or percentage, more than 0.
advanceSettingsobject
addOnAppliesTostring (enum)
One of: SELECTED_SERVICES, ALL_SERVICES.
addOnServicesobject[]
sortOrderinteger
createdAtstring
updatedAtstring
createdboolean
POST and PUT responses only: true when the call created the service
Request
curl -X PUT "https://api.whautomate.com/v1/services/0zJd3wC2yO" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sellingPrice": 145,
"durationMinutes": 80
}'
Response 200
{
"created": false,
"id": "0zJd3wC2yO",
"externalId": "svc-hot-stone-75",
"serviceType": "APPOINTMENT",
"name": "Hot Stone Massage",
"location": {
"id": "Le6dWjQF9K",
"title": "Serene Wellness Studio"
},
"durationMinutes": 80,
"categories": [],
"staffs": [
{
"id": "ZxkrjyVgDE",
"name": "Aisha Rahman"
}
],
"type": "",
"sellingPrice": 145,
"regularPrice": 160,
"currency": "SGD",
"taxOverrides": [],
"creditsPerBooking": null,
"credits": 0,
"active": true,
"allowOnlineBooking": true,
"acceptPaymentOnline": false,
"paymentCollection": "FULL",
"advanceSettings": {},
"sortOrder": 16,
"createdAt": "2026-10-29T12:40:09.467Z",
"updatedAt": "2026-10-29T12:40:09.546Z"
}

Archive a service​

DEL /v1/services/{serviceId}

Archives a service (the app has no service delete): hidden from every list and from booking, kept for past bookings and invoices.

Headers
x-api-keystringrequired
Your Whautomate API key.
Path parameters
serviceIdstringrequired
Service id. Get ids from GET /v1/services.
Response 200
idstring
archivedboolean
Request
curl -X DELETE "https://api.whautomate.com/v1/services/0zJd3wC2yO" \
-H "x-api-key: YOUR_API_KEY"
Response 200
{
"id": "0zJd3wC2yO",
"archived": true
}

Bulk​

Each item runs on its own, so check every result.

Create or update services in bulk​

POST /v1/services/bulk

Creates or updates up to 100 services; items with serviceId or a known externalId update. Each item runs on its own. Needs the Bookings or Sales module.

Headers
x-api-keystringrequired
Your Whautomate API key.
Body
itemsobject[]required

Up to 100. Items with serviceId or a known externalId update, others create.

Response 200
createdinteger
Items created
updatedinteger
Items updated
failedinteger
Items that failed
resultsobject[]
Request
curl -X POST "https://api.whautomate.com/v1/services/bulk" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"serviceId": "0zJd3wC2yO",
"sellingPrice": 150
},
{
"serviceId": "doesNotExist1",
"sellingPrice": 99
}
]
}'
Response 200
{
"created": 0,
"updated": 1,
"failed": 1,
"results": [
{
"index": 0,
"ok": true,
"created": false,
"id": "0zJd3wC2yO",
"externalId": "svc-hot-stone-75"
},
{
"index": 1,
"ok": false,
"error": "Service not found in the account."
}
]
}

Archive services in bulk​

POST /v1/services/bulk/archive

Archives up to 100 services by serviceIds and/or externalIds.

Headers
x-api-keystringrequired
Your Whautomate API key.
Body
serviceIdsstring[]
externalIdsstring[]
Response 200
succeededinteger
failedinteger
resultsobject[]
Request
curl -X POST "https://api.whautomate.com/v1/services/bulk/archive" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"serviceIds": [
"mP0pBw7er8"
]
}'
Response 200
{
"succeeded": 1,
"failed": 0,
"results": [
{
"id": "mP0pBw7er8",
"ok": true,
"archived": true
}
]
}