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.
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>.
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
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
| Status | Meaning |
|---|---|
200 | Array of appointments |
401 | Missing or invalid credentials |
403 | API key is missing the appointments:read scope |
429 | API key rate limit exceeded |
default | Error response |
POST/api/appointments
Create an appointment
Creates an appointment. Requires the appointments:write scope. Fires the appointment.created webhook.
Responses
| Status | Meaning |
|---|---|
200 | The created appointment |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
appointmentId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The appointment |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
appointmentId required |
path | string |
Request body application/json
| Field | Type | Description |
|---|---|---|
_id |
string | |
salonId |
string | |
clientId |
string | |
startTime |
string | |
endTime |
string | |
status |
string | |
services |
array | |
reminders |
array | |
lastEditTime |
string |
Responses
| Status | Meaning |
|---|---|
200 | The updated appointment |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
appointmentId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The deleted appointment id |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
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
| Status | Meaning |
|---|---|
200 | Array of clients |
401 | Missing or invalid credentials |
403 | API key is missing the clients:read scope |
429 | API key rate limit exceeded |
default | Error response |
POST/api/clients
Create a client
Creates a client. Requires the clients:write scope. Fires the client.created webhook.
Responses
| Status | Meaning |
|---|---|
200 | The created client |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The client |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientId required |
path | string |
Request body application/json
| Field | Type | Description |
|---|---|---|
_id |
string | |
salonId |
string | |
name |
string | |
email |
string | |
phone |
string | |
language |
string | |
lastEditTime |
string |
Responses
| Status | Meaning |
|---|---|
200 | The updated client |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
clientId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The deleted client id |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fields |
query | string | Comma-separated projection of fields to return |
Responses
| Status | Meaning |
|---|---|
200 | Array of keys (without secrets) |
default | Error response |
Salons
GET/api/salons
List salons
Lists the salons of your organization. Requires the salons:read scope.
Responses
| Status | Meaning |
|---|---|
200 | Array of salons |
401 | Missing or invalid credentials |
403 | API key is missing the salons:read scope |
429 | API key rate limit exceeded |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
salonId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The salon |
404 | Not found (or owned by another organization) |
default | Error response |
Services
GET/api/services
List services
Lists the services of your organization. Requires the services:read scope. Optionally filter by salonId.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
salonId |
query | string | |
fields |
query | string | Comma-separated projection of fields to return |
Responses
| Status | Meaning |
|---|---|
200 | Array of services |
401 | Missing or invalid credentials |
403 | API key is missing the services:read scope |
429 | API key rate limit exceeded |
default | Error response |
POST/api/services
Create a service
Creates a service. Requires the services:write scope. Fires the service.created webhook.
Responses
| Status | Meaning |
|---|---|
200 | The created service |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
serviceId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The service |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
serviceId required |
path | string |
Request body application/json
| Field | Type | Description |
|---|---|---|
_id |
string | |
salonId |
string | |
name |
string | |
price |
string | |
duration |
integer | |
lastEditTime |
string |
Responses
| Status | Meaning |
|---|---|
200 | The updated service |
404 | Not found (or owned by another organization) |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
serviceId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The deleted service id |
404 | Not found (or owned by another organization) |
default | Error 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.
Responses
| Status | Meaning |
|---|---|
200 | Array of webhook subscriptions (without secrets) |
default | Error response |
POST/api/webhooksubscriptions
Create a webhook subscription
The response includes the signing secret exactly once — store it; it cannot be retrieved again.
Request body application/json
| Field | Type | Description |
|---|---|---|
salonId required |
string | |
url required |
string | |
events |
array | Empty array subscribes to all events |
Responses
| Status | Meaning |
|---|---|
200 | The created subscription, including its secret |
default | Error 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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookSubscriptionId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | The updated subscription (without secret) |
default | Error response |
DELETE/api/webhooksubscriptions/{webhookSubscriptionId}
Delete a webhook subscription
Delete a webhook subscription
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookSubscriptionId required |
path | string |
Responses
| Status | Meaning |
|---|---|
200 | Deleted |
default | Error response |