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.
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 for use with your own tooling.
List appointments
Lists the appointments of your organization. Requires the appointments:read scope. Optionally filter by salonId, clientId and a startTime/endTime window.
| Name | In | Type | Description |
|---|---|---|---|
| salonId | query | string | |
| clientId | query | string | |
| startTime | query | string | |
| endTime | query | string | |
| limit | query | integer | |
| skip | query | integer | |
| sortField | query | string | |
| sortDirection | query | string (ASC | DESC) | |
| fields | query | string | Comma-separated projection of fields to return |
| 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 |
Create an appointment
Creates an appointment. Requires the appointments:write scope. Fires the appointment.created webhook.
| Status | Meaning |
|---|---|
| 200 | The created appointment |
Get an appointment
Returns a single appointment by id. Appointments belonging to another organization respond 404. Requires the appointments:read scope.
| Name | In | Type | Description |
|---|---|---|---|
| appointmentIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The appointment |
| 404 | Not found (or owned by another organization) |
Update an appointment
Updates an appointment. Requires the appointments:write scope. Appointments owned by another organization respond 404. Fires the appointment.updated webhook.
| Name | In | Type | Description |
|---|---|---|---|
| appointmentIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The updated appointment |
| 404 | Not found (or owned by another organization) |
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.
| Name | In | Type | Description |
|---|---|---|---|
| appointmentIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The deleted appointment id |
| 404 | Not found (or owned by another organization) |
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.
| Name | In | Type | Description |
|---|---|---|---|
| salonId | query | string | |
| query | string | ||
| fields | query | string | Comma-separated projection of fields to return |
| limit | query | integer | |
| skip | query | integer |
| 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 |
Create a client
Creates a client. Requires the clients:write scope. Fires the client.created webhook.
| Status | Meaning |
|---|---|
| 200 | The created client |
Get a client
Returns a single client by id. Clients belonging to another organization respond 404. Requires the clients:read scope.
| Name | In | Type | Description |
|---|---|---|---|
| clientIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The client |
| 404 | Not found (or owned by another organization) |
Update a client
Updates a client. Requires the clients:write scope. Clients owned by another organization respond 404. Fires the client.updated webhook.
| Name | In | Type | Description |
|---|---|---|---|
| clientIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The updated client |
| 404 | Not found (or owned by another organization) |
Delete a client
Deletes a client by id. Requires the clients:write scope. Clients owned by another organization respond 404.
| Name | In | Type | Description |
|---|---|---|---|
| clientIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The deleted client id |
| 404 | Not found (or owned by another organization) |
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.
| Name | In | Type | Description |
|---|---|---|---|
| fields | query | string | Comma-separated projection of fields to return |
| Status | Meaning |
|---|---|
| 200 | Array of keys (without secrets) |
List salons
Lists the salons of your organization. Requires the salons:read scope.
| 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 |
Get a salon
Returns a single salon by id. Salons belonging to another organization respond 404. Requires the salons:read scope.
| Name | In | Type | Description |
|---|---|---|---|
| salonIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The salon |
| 404 | Not found (or owned by another organization) |
List services
Lists the services of your organization. Requires the services:read scope. Optionally filter by salonId.
| Name | In | Type | Description |
|---|---|---|---|
| salonId | query | string | |
| fields | query | string | Comma-separated projection of fields to return |
| 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 |
Create a service
Creates a service. Requires the services:write scope. Fires the service.created webhook.
| Status | Meaning |
|---|---|
| 200 | The created service |
Get a service
Returns a single service by id. Services belonging to another organization respond 404. Requires the services:read scope.
| Name | In | Type | Description |
|---|---|---|---|
| serviceIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The service |
| 404 | Not found (or owned by another organization) |
Update a service
Updates a service. Requires the services:write scope. Services owned by another organization respond 404. Fires the service.updated webhook.
| Name | In | Type | Description |
|---|---|---|---|
| serviceIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The updated service |
| 404 | Not found (or owned by another organization) |
Delete a service
Deletes a service by id. Requires the services:write scope. Services owned by another organization respond 404.
| Name | In | Type | Description |
|---|---|---|---|
| serviceIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The deleted service id |
| 404 | Not found (or owned by another organization) |
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.
| Status | Meaning |
|---|---|
| 200 | Array of webhook subscriptions (without secrets) |
Create a webhook subscription
The response includes the signing secret exactly once — store it; it cannot be retrieved again.
| Field | Type | Description |
|---|---|---|
| salonIdrequired | string | |
| urlrequired | string | |
| events | array (appointment.created | appointment.updated | appointment.deleted | client.created | client.updated | service.created | service.updated) | Empty array subscribes to all events |
| Status | Meaning |
|---|---|
| 200 | The created subscription, including its secret |
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.
| Name | In | Type | Description |
|---|---|---|---|
| webhookSubscriptionIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | The updated subscription (without secret) |
Delete a webhook subscription
| Name | In | Type | Description |
|---|---|---|---|
| webhookSubscriptionIdrequired | path | string |
| Status | Meaning |
|---|---|
| 200 | Deleted |