HairDora API 1.0.0

Public REST API for HairDora. Authenticate with an API key created in the HairDora dashboard: send the base64-encoded key secret with HTTP Basic auth. Each key carries per-resource scopes like appointments:read or clients:write.

Base URL https://api.hairdora.com
  • apiKey — HTTP Basic auth carrying only the API key secret: Authorization: Basic base64(<key secret>).
  • accessToken — Operator session token issued by the HairDora dashboard: Authorization: Token <access token>.

Download the OpenAPI specification

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
salonId query string
clientId query string
startTime query string
endTime query string
limit query integer default 0
skip query integer default 0
sortField query string
sortDirection query string ASC | DESC
fields query string Comma-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
defaultError response

POST/api/appointments

Create an appointment

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

Authentication apiKey accessToken

Responses

StatusMeaning
200The created appointment
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
appointmentId required path string

Responses

StatusMeaning
200The appointment
404Not found (or owned by another organization)
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
appointmentId required path string

Request body application/json

FieldTypeDescription
_id string
salonId string
clientId string
startTime string
endTime string
status string
services array
reminders array
lastEditTime string

Responses

StatusMeaning
200The updated appointment
404Not found (or owned by another organization)
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
appointmentId required path string

Responses

StatusMeaning
200The deleted appointment id
404Not found (or owned by another organization)
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
salonId query string
email query string
fields query string Comma-separated projection of fields to return
limit query integer default 0
skip query integer default 0

Responses

StatusMeaning
200Array of clients
401Missing or invalid credentials
403API key is missing the clients:read scope
429API key rate limit exceeded
defaultError response

POST/api/clients

Create a client

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

Authentication apiKey accessToken

Responses

StatusMeaning
200The created client
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
clientId required path string

Responses

StatusMeaning
200The client
404Not found (or owned by another organization)
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
clientId required path string

Request body application/json

FieldTypeDescription
_id string
salonId string
name string
email string
phone string
language string
lastEditTime string

Responses

StatusMeaning
200The updated client
404Not found (or owned by another organization)
defaultError response

DELETE/api/clients/{clientId}

Delete a client

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

Authentication apiKey accessToken

Parameters

NameInTypeDescription
clientId required path string

Responses

StatusMeaning
200The deleted client id
404Not found (or owned by another organization)
defaultError response

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.

Authentication accessToken

Parameters

NameInTypeDescription
fields query string Comma-separated projection of fields to return

Responses

StatusMeaning
200Array of keys (without secrets)
defaultError response

Salons

GET/api/salons

List salons

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

Authentication apiKey accessToken

Responses

StatusMeaning
200Array of salons
401Missing or invalid credentials
403API key is missing the salons:read scope
429API key rate limit exceeded
defaultError response

GET/api/salons/{salonId}

Get a salon

Returns a single salon by id. Readable anonymously, like the by-vanity-name lookup below. An authenticated caller still only sees a salon it owns: salons belonging to another organization respond 404. Requires the salons:read scope when called with an API key.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
salonId required path string

Responses

StatusMeaning
200The salon
404Not found (or owned by another organization)
defaultError response

Services

GET/api/services

List services

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

Authentication apiKey accessToken

Parameters

NameInTypeDescription
salonId query string
fields query string Comma-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
defaultError response

POST/api/services

Create a service

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

Authentication apiKey accessToken

Responses

StatusMeaning
200The created service
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
serviceId required path string

Responses

StatusMeaning
200The service
404Not found (or owned by another organization)
defaultError response

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.

Authentication apiKey accessToken

Parameters

NameInTypeDescription
serviceId required path string

Request body application/json

FieldTypeDescription
_id string
salonId string
name string
price string
duration integer
lastEditTime string

Responses

StatusMeaning
200The updated service
404Not found (or owned by another organization)
defaultError response

DELETE/api/services/{serviceId}

Delete a service

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

Authentication apiKey accessToken

Parameters

NameInTypeDescription
serviceId required path string

Responses

StatusMeaning
200The deleted service id
404Not found (or owned by another organization)
defaultError response

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.

Authentication accessToken

Responses

StatusMeaning
200Array of webhook subscriptions (without secrets)
defaultError response

POST/api/webhooksubscriptions

Create a webhook subscription

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

Authentication accessToken

Request body application/json

FieldTypeDescription
salonId required string
url required string
events array Empty array subscribes to all events

Responses

StatusMeaning
200The created subscription, including its secret
defaultError response

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.

Authentication accessToken

Parameters

NameInTypeDescription
webhookSubscriptionId required path string

Responses

StatusMeaning
200The updated subscription (without secret)
defaultError response

DELETE/api/webhooksubscriptions/{webhookSubscriptionId}

Delete a webhook subscription

Delete a webhook subscription

Authentication accessToken

Parameters

NameInTypeDescription
webhookSubscriptionId required path string

Responses

StatusMeaning
200Deleted
defaultError response