---
title: "Create a practitioner"
method: POST
path: "/shop/practitioners"
tags: ["Practitioners"]
---

# Create a practitioner

`POST /shop/practitioners`

Creates a new `Practitioner` attached to one or more sites. The
minimum body is `name` + `site_ids`; everything else has a sensible
default or `null`-equivalent. Returns the freshly created
practitioner.

The first entry in `site_ids` becomes the practitioner's "default"
site — zones, commission packages, and the user-uniqueness check
are evaluated against this site. The practitioner's `timezone` is
inherited from the default site at creation time.

Requires the `SETTINGS_MANAGE` permission on every site listed in
`site_ids`.

## Query parameters

- `site_id` string, required

## Request body

- object
  - `name` string, required — Display name of the practitioner shown to customers in the booking flow and to staff in the admin UI.
  - `site_ids` string[], required — One or more site IDs the practitioner works at. Must contain at least one site; the first entry becomes the practitioner's "default" site for zone- and commission-package lookups. The caller's user must be a member of every site listed.
  - `organisation_id` string, uuid — Optional organisation to attribute this practitioner to. The caller's user must belong to the organisation. Defaults to the caller's primary organisation when omitted.
  - `tag_ids` string[] — IDs of practitioner tags this person is associated with. Tags must already exist in the caller's primary organisation AND be marked `applies_to: Practitioner` — others are rejected with 422.
  - `avatar_id` string, object-id, nullable — ID of an uploaded `Media` to use as the practitioner's avatar. Shown next to the practitioner's name in the booking widget and admin UI.
  - `signature_id` string, object-id, nullable — ID of an uploaded `Media` to use as the practitioner's signature image. Shown on documents and receipts that require a practitioner signature.
  - `zone_ids` string[] — IDs of zones the practitioner is associated with. Zones must belong to the first site in `site_ids` — zones from other sites are rejected with 422.
  - `gender` 'male' | 'female' | 'non_binary', nullable — Optional gender used by the booking flow to honour customer preferences (e.g. "I'd prefer a female therapist").
  - `registration_number` string, nullable — Optional registration or license number for the practitioner. Used to track professional credentials or qualifications.
  - `external_id` string, nullable — Optional external identifier for correlating this practitioner with a record in a third-party system.
  - `commission_package_id` string, object-id, nullable — Optional `CommissionPackage` to attach to the practitioner. Drives payroll/commission reporting. Must belong to the first site in `site_ids`.
  - `user_id` string, uuid, nullable — Optional underlying `User` to link to this practitioner. The user must share an organisation with the caller. A given user can be linked to at most one practitioner per site — attempting to reuse a user on the same site is rejected with 422.

## Response `201`

The practitioner was created.

- object
  - `data` Practitioner, required — A bookable staff member — typically a therapist, instructor or stylist — that appointments and sessions can be assigned to. Practitioners own a working rota, optional commission rules, and the set of session/appointment types they are qualified to deliver.
    - `id` string, object-id, required — Stable identifier for the practitioner. Used when assigning sessions, appointments and rotas to the practitioner, and when the booking storefront resolves a slot to a specific staff member.
    - `appointment_restrictions` PractitionerAppointmentRestriction[], required
      - `id` string, required — The ID of the restriction
      - `applies_to_type` 'specific' | 'categories', required — The type of the restriction
      - `appointment_type_ids` string[] — The IDs of appointment types that this restriction applies to
      - `appointment_types` object[] — The appointment types associated with this product
        - `id` string, required
        - `name` string, required
      - `categories` object[] — The category associated with this product
        - `id` string, required
        - `name` string, required
      - `category_ids` string[] — The IDs of categories that this restriction applies to
      - `date_from` string, date, required — The first day that this restriction should apply
      - `date_to` string, date, required — The last date that this restriction should apply
      - `max_duration` integer — For a `max_duration` rule, this specifies the maximum number of minutes of the appointment type that the practitioner may offer each day.
      - `occupied_mins` integer
      - `type` 'cannot_offer' | 'max_duration' — The type of the restriction
    - `avatar` Media
      - `id` string, uuid, required — Unique identifier of the uploaded media item, returned from `createMedia`. Pass this ID into any field that accepts a media reference (logos, hero images, product images, etc.).
      - `file_name` string, required — Original filename of the uploaded asset, preserved as provided at upload time. Used for display in the media library and as a hint when serving downloads.
      - `mime_type` string, required — The mime type of the media item.
      - `original_url` string, required — The url of the media resource.
      - `size` integer, required — The size of the media item in bytes.
      - `url` string, required — The url of the converted media resource.
    - `signature` Media
      - `id` string, uuid, required — Unique identifier of the uploaded media item, returned from `createMedia`. Pass this ID into any field that accepts a media reference (logos, hero images, product images, etc.).
      - `file_name` string, required — Original filename of the uploaded asset, preserved as provided at upload time. Used for display in the media library and as a hint when serving downloads.
      - `mime_type` string, required — The mime type of the media item.
      - `original_url` string, required — The url of the media resource.
      - `size` integer, required — The size of the media item in bytes.
      - `url` string, required — The url of the converted media resource.
    - `can_offer_tags` string[], required
    - `gender` string, nullable — Self-identified gender of the practitioner, surfaced to guests who filter the booking storefront by practitioner gender. Free text — common values are `female`, `male` and `non-binary`. `null` when the practitioner hasn't supplied a value.
    - `name` string, required — Public display name of the practitioner. Shown to guests on the booking storefront and on receipts. Should be the name the practitioner wants to appear in front of guests — typically first name plus last initial or full name.
    - `registration_number` string, nullable — Optional registration or license number for the practitioner. Used to track professional credentials or qualifications.
    - `organisation_id` string, uuid, required — Organisation the practitioner belongs to. Practitioners are scoped to a single organisation and are not visible to API callers from other organisations.
    - `site_ids` string[], required
    - `tag_ids` string[], required
    - `tags` Tag[], required
      - `id` string, required
      - `name` string, required
      - `organisation_id` string, required
    - `zones` Zone[], required
      - `id` string, object-id, required — Unique identifier for the zone.
      - `name` string, required — Display name for the zone, shown wherever zones are listed or filtered. Plain text only.
      - `organisation_id` string, uuid, required — ID of the organisation that owns this zone. Inherited from the site on create.
      - `site_id` string, uuid, required — ID of the site this zone belongs to.
    - `commission_package_id` string, mongo-id, nullable — The commission package to use for this practitioner. If not set, the practitioner's default commission package will be the site's default commission package (as defined by `ShopSite.default_commission_package_id`).
    - `external_id` string, nullable, required — Optional external identifier for the practitioner, used to correlate this record with an entry in a third-party system (e.g. a PMS, payroll provider, or CRM). Not interpreted by the platform — treated as an opaque string.
    - `user_id` string, uuid, nullable, required — Staff `User` linked to this practitioner record, if any. Linking lets the user manage their own rota and view their appointments from the staff console. `null` for practitioners that don't have a login account.
    - `created_at` string, date-time, required — When then resource was created.
    - `updated_at` string, date-time, required — When then resource was last updated.

## Other responses

- `401` — The user is unauthenticated
- `403` — The authenticated user does not have permission.
- `422` — The request didn't pass validation

---

[API](https://skmtc.dev/try/apis/trybe-api.md) · [All operations](https://skmtc.dev/try/apis/trybe-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/try/trybe-api/revisions/f37f92702da5/schema)
