Skip to content

Create a team member

Request

Creates a Team Member in the Location. After creating, set the working schedule (PATCH .../schedule) and link services — otherwise the member does not appear in availability search. Requires Idempotency-Key.

access_invitation is an atomic create-and-invite convenience for user-delegated Authorization Code credentials only: when present, the token must also carry team_members:manage_access. Client Credentials and restricted keys cannot use it in the first iteration. If the extra scope or credential class is not allowed, the request fails before creating the Team Member with 403 missing_scope.

Security
OAuth2(Required scopes: team_members:write) or RestrictedKey
Path
location_idintegerrequired

Identifier of the Location. Verified against the credential on every call — a Location the credential cannot access responds with 404.

Headers
Idempotency-Keystring, <= 255 charactersrequired

Client-generated unique key for this logical request (UUID recommended). A retry with the same key and body returns the original result; the same key with a different body fails with 409 idempotency_key_reused. Keys are retained at least 24 hours and are scoped to credential, Location, and operation; after expiry the value may be reused for a new logical request.

Bodyapplication/jsonrequired
namestringrequired
specializationstring, non-emptyrequired

Public profession label shown to clients (for example in online booking).

position_idinteger
servicesArray of objects(TeamMemberServiceLink)

Initial service links, the same link shape as on update.

access_invitationobject

Optional - atomically invite this Team Member to a system-access role on creation (role from listLocationAccessRoles). Requires an Authorization Code token with team_members:manage_access in addition to team_members:write; Client Credentials and restricted keys cannot use this convenience in the first iteration.

At least one of phone or email is required: the invitation is delivered to that address, and without it sendTeamMemberInvitation fails with 422 invitation_contact_required. These are the invited person's login contacts, used for delivery only - they are write-only and are never returned by team member reads.

is_billableboolean

Whether the new Team Member takes a paid seat in the Location's licence. Defaults to false, so a plain create never changes what the Location is charged: the member is created without schedule access and is not bookable. Send true to create a bookable member and accept the licence charge — the create fails with 422 when the licence has no free paid seat. Locations on the older licensing model ignore this field.

Default:false
curl -i -X POST \
  'https://developer.alteg.io/_mock/en/b2b-v3/openapi/locations/{location_id}/team_members' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: string' \
  -d '{
    "name": "Aigerim Bekova",
    "specialization": "Hairdresser",
    "position_id": 15,
    "services": [
      {
        "service_id": 100
      }
    ]
  }'

Responses

The created team member.

Headers
RateLimit-Remaininginteger, (int32), >= 0

Requests left in the most constrained policy window that applies to this request.

RateLimit-Resetinteger, (int32), >= 0

On 429, seconds until the most constrained policy frees up; it equals Retry-After there. On a successful response it reports the length of that policy's window rather than the time left in the current one, so treat it as the window size, not as a countdown — the counter to pace against is RateLimit-Remaining.

RateLimit-Policystring

Most constrained policy applied to the request, as <limit>;w=<window in seconds>.

Example:"10;w=60"
Locationstring

URL of the created resource.

ETagstring

Version tag of the returned resource. Send it back in If-Match on the next PATCH or DELETE.

X-Request-Idstring

Request identifier for support and log correlation.

Bodyapplication/json
idintegerread-onlyrequired
objectstringread-onlyrequired
Value:"team_member"
namestringrequired
specializationstringrequired

Public profession label shown to clients (for example in online booking).

position_idinteger or null

Position from listPositions.

service_idsArray of integers

Services this Team Member can be scheduled for.

is_bookablebooleanread-only

Derived — whether the member can currently receive appointments.

is_billableboolean

Whether this Team Member occupies a paid seat in the Location's licence, which is what the Location is charged for. A non-billable member cannot hold schedule access, so is_bookable is always false for one. Locations still on the older licensing model report false here and ignore the field on write — there the paid seat count follows schedule access instead.

created_atstring, (date-time)read-only

UTC.

updated_atstring, (date-time)read-only

UTC.

Response
{ "id": 321, "object": "team_member", "name": "Aigerim Bekova", "specialization": "Hairdresser", "position_id": 15, "service_ids": [ 100 ], "is_bookable": true, "created_at": "2026-06-01T08:00:00Z", "updated_at": "2026-07-01T08:00:00Z" }