HairDora API reference

Every endpoint of the HairDora REST API, generated from the API itself.

All endpoints are relative to https://api.hairdora.com. Create an API key in your HairDora dashboard, then authenticate every request with it.

apiKeyHTTP Basic auth carrying only the API key secret: Authorization: Basic base64(<key secret>).

accessTokenOperator session token issued by the HairDora dashboard: Authorization: Token <access token>.

Download the OpenAPI specification for use with your own tooling.

Appointments

GET/api/appointments

List appointments

Lists the appointments of your organization. Requires the appointments:read scope. Optionally filter by salonId, clientId and a startTime/endTime window.

appointments:readapiKeyaccessToken
Parameters
NameInTypeDescription
salonIdquerystring
clientIdquerystring
startTimequerystring
endTimequerystring
limitqueryinteger
skipqueryinteger
sortFieldquerystring
sortDirectionquerystring (ASC | DESC)
fieldsquerystringComma-separated projection of fields to return
Responses
StatusMeaning
200Array of appointments
401Missing or invalid credentials
403API key is missing the appointments:read scope
429API key rate limit exceeded
POST/api/appointments

Create an appointment

Creates an appointment. Requires the appointments:write scope. Fires the appointment.created webhook.

appointments:writeapiKeyaccessToken
Responses
StatusMeaning
200The created appointment
GET/api/appointments/{appointmentId}

Get an appointment

Returns a single appointment by id. Appointments belonging to another organization respond 404. Requires the appointments:read scope.

appointments:readapiKeyaccessToken
Parameters
NameInTypeDescription
appointmentIdrequiredpathstring
Responses
StatusMeaning
200The appointment
404Not found (or owned by another organization)
PUT/api/appointments/{appointmentId}

Update an appointment

Updates an appointment. Requires the appointments:write scope. Appointments owned by another organization respond 404. Fires the appointment.updated webhook.

appointments:writeapiKeyaccessToken
Parameters
NameInTypeDescription
appointmentIdrequiredpathstring
Responses
StatusMeaning
200The updated appointment
404Not found (or owned by another organization)
DELETE/api/appointments/{appointmentId}

Delete an appointment

Deletes an appointment by id. Requires the appointments:write scope. Appointments owned by another organization respond 404. Fires the appointment.deleted webhook.

appointments:writeapiKeyaccessToken
Parameters
NameInTypeDescription
appointmentIdrequiredpathstring
Responses
StatusMeaning
200The deleted appointment id
404Not found (or owned by another organization)

Clients

GET/api/clients

List clients

Lists the clients of your organization. Requires the clients:read scope. Optionally filter by salonId, _id, _ids, email or userId, and bound the result with limit/skip.

clients:readapiKeyaccessToken
Parameters
NameInTypeDescription
salonIdquerystring
emailquerystring
fieldsquerystringComma-separated projection of fields to return
limitqueryinteger
skipqueryinteger
Responses
StatusMeaning
200Array of clients
401Missing or invalid credentials
403API key is missing the clients:read scope
429API key rate limit exceeded
POST/api/clients

Create a client

Creates a client. Requires the clients:write scope. Fires the client.created webhook.

clients:writeapiKeyaccessToken
Responses
StatusMeaning
200The created client
GET/api/clients/{clientId}

Get a client

Returns a single client by id. Clients belonging to another organization respond 404. Requires the clients:read scope.

clients:readapiKeyaccessToken
Parameters
NameInTypeDescription
clientIdrequiredpathstring
Responses
StatusMeaning
200The client
404Not found (or owned by another organization)
PUT/api/clients/{clientId}

Update a client

Updates a client. Requires the clients:write scope. Clients owned by another organization respond 404. Fires the client.updated webhook.

clients:writeapiKeyaccessToken
Parameters
NameInTypeDescription
clientIdrequiredpathstring
Responses
StatusMeaning
200The updated client
404Not found (or owned by another organization)
DELETE/api/clients/{clientId}

Delete a client

Deletes a client by id. Requires the clients:write scope. Clients owned by another organization respond 404.

clients:writeapiKeyaccessToken
Parameters
NameInTypeDescription
clientIdrequiredpathstring
Responses
StatusMeaning
200The deleted client id
404Not found (or owned by another organization)

Keys

GET/api/keys

List API keys

Lists the API keys of your organization. The signing secret is never included — it is returned only once, in the create response. Managed with an operator access token, not an API key.

accessToken
Parameters
NameInTypeDescription
fieldsquerystringComma-separated projection of fields to return
Responses
StatusMeaning
200Array of keys (without secrets)

Salons

GET/api/salons

List salons

Lists the salons of your organization. Requires the salons:read scope.

salons:readapiKeyaccessToken
Responses
StatusMeaning
200Array of salons
401Missing or invalid credentials
403API key is missing the salons:read scope
429API key rate limit exceeded
GET/api/salons/{salonId}

Get a salon

Returns a single salon by id. Salons belonging to another organization respond 404. Requires the salons:read scope.

salons:readapiKeyaccessToken
Parameters
NameInTypeDescription
salonIdrequiredpathstring
Responses
StatusMeaning
200The salon
404Not found (or owned by another organization)

Services

GET/api/services

List services

Lists the services of your organization. Requires the services:read scope. Optionally filter by salonId.

services:readapiKeyaccessToken
Parameters
NameInTypeDescription
salonIdquerystring
fieldsquerystringComma-separated projection of fields to return
Responses
StatusMeaning
200Array of services
401Missing or invalid credentials
403API key is missing the services:read scope
429API key rate limit exceeded
POST/api/services

Create a service

Creates a service. Requires the services:write scope. Fires the service.created webhook.

services:writeapiKeyaccessToken
Responses
StatusMeaning
200The created service
GET/api/services/{serviceId}

Get a service

Returns a single service by id. Services belonging to another organization respond 404. Requires the services:read scope.

services:readapiKeyaccessToken
Parameters
NameInTypeDescription
serviceIdrequiredpathstring
Responses
StatusMeaning
200The service
404Not found (or owned by another organization)
PUT/api/services/{serviceId}

Update a service

Updates a service. Requires the services:write scope. Services owned by another organization respond 404. Fires the service.updated webhook.

services:writeapiKeyaccessToken
Parameters
NameInTypeDescription
serviceIdrequiredpathstring
Responses
StatusMeaning
200The updated service
404Not found (or owned by another organization)
DELETE/api/services/{serviceId}

Delete a service

Deletes a service by id. Requires the services:write scope. Services owned by another organization respond 404.

services:writeapiKeyaccessToken
Parameters
NameInTypeDescription
serviceIdrequiredpathstring
Responses
StatusMeaning
200The deleted service id
404Not found (or owned by another organization)

Webhook subscriptions

GET/api/webhooksubscriptions

List webhook subscriptions

Webhook subscriptions deliver appointment.created, appointment.updated, appointment.deleted, client.created, client.updated, service.created and service.updated events to your server as signed POST requests (X-Hairdora-Signature: t=<timestamp>,v1=<hex HMAC-SHA256 of "timestamp.body">). An endpoint failing 20 times in a row is disabled automatically. Subscriptions are managed with an operator access token; the secret is only returned once, on create.

accessToken
Responses
StatusMeaning
200Array of webhook subscriptions (without secrets)
POST/api/webhooksubscriptions

Create a webhook subscription

The response includes the signing secret exactly once — store it; it cannot be retrieved again.

accessToken
Request body
FieldTypeDescription
salonIdrequiredstring
urlrequiredstring
eventsarray (appointment.created | appointment.updated | appointment.deleted | client.created | client.updated | service.created | service.updated)Empty array subscribes to all events
Responses
StatusMeaning
200The created subscription, including its secret
PUT/api/webhooksubscriptions/{webhookSubscriptionId}

Update a webhook subscription

url, events and active are editable; the secret and salon are immutable. Re-enabling an auto-disabled endpoint is done by setting active back to true.

accessToken
Parameters
NameInTypeDescription
webhookSubscriptionIdrequiredpathstring
Responses
StatusMeaning
200The updated subscription (without secret)
DELETE/api/webhooksubscriptions/{webhookSubscriptionId}

Delete a webhook subscription

accessToken
Parameters
NameInTypeDescription
webhookSubscriptionIdrequiredpathstring
Responses
StatusMeaning
200Deleted