Create Staff Member¶
Creates a staff member through onboarding and assigns them to clinics.
Endpoint¶
Request Body¶
| Parameter | Type | Required | Description |
|---|---|---|---|
first_name |
string | Yes | |
last_name |
string | Yes | |
email |
string | Yes | Becomes the user's EMR username at publish. |
roles |
array of string | Yes | Roles for an onboarding-managed staff member — set only when creating or updating through onboarding. One of ADMIN, JUNIOR_DOCTOR, STUDENT, RECEPTIONIST, TECH, BILLER. JUNIOR_DOCTOR and STUDENT require is_cosign_required; supervising_provider_id is required when is_cosign_required is true and rejected otherwise. Only JUNIOR_DOCTOR may carry npi; only supervised roles accept schedule. TECH cannot combine with other roles; JUNIOR_DOCTOR combines only with STUDENT. |
clinic_ids |
array of string | Yes | Operational clinic ids for published staff; onboarding clinic ids for a not-yet-published record. |
middle_name |
string | No | |
mobile |
string | No | |
npi |
string | No | |
is_cosign_required |
boolean | No | Whether this staff member's actions require a supervising provider's cosign. Required (and must be true) for JUNIOR_DOCTOR and STUDENT. |
supervising_provider_id |
string | No | The supervising provider, required for a supervised role. |
schedule |
array | No | Working-hours entries for a supervised role (JUNIOR_DOCTOR / STUDENT), passed through from onboarding's own shape. |
Request¶
curl --location '{base_url}/v2/staff' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"first_name": "Morgan",
"last_name": "Delgado",
"email": "m.delgado@example.com",
"roles": [
"JUNIOR_DOCTOR"
],
"clinic_ids": [
"5831"
],
"middle_name": null,
"mobile": "+1-555-0155",
"npi": "1740398215",
"is_cosign_required": true,
"supervising_provider_id": "d27a6b10-9f34-4e82-b5c1-7a03e8946fd2",
"schedule": null
}'
Response¶
Success Response¶
Code: 201 Created
{
"id": "7106",
"onboarding_user_id": "f14a2c88-6d31-4b09-9e77-3c8d1a52f9e6",
"role": null,
"roles": [
"JUNIOR_DOCTOR"
],
"first_name": "Morgan",
"middle_name": null,
"last_name": "Delgado",
"email": "m.delgado@example.com",
"mobile": "+1-555-0155",
"clinic_ids": [
"5831"
],
"status": "ACTIVE",
"is_cosign_required": true,
"supervising_provider_id": "d27a6b10-9f34-4e82-b5c1-7a03e8946fd2",
"npi": "1740398215",
"schedule": null,
"access_revoked": false,
"created_at": "2026-08-27T14:30:00Z",
"updated_at": "2026-08-27T14:30:00Z"
}
The Location header carries the URL of the created resource.
Response Fields¶
| Field | Type | Description |
|---|---|---|
id |
string or null | The staff member's id. |
onboarding_user_id |
string or null | The staff member's onboarding-record UUID. Present when this staff member is managed through onboarding. |
role |
string or null | The staff member's role. Clinical roles are providers, not staff. |
roles |
array of string | Roles for an onboarding-managed staff member — set only when creating or updating through onboarding. One of ADMIN, JUNIOR_DOCTOR, STUDENT, RECEPTIONIST, TECH, BILLER. JUNIOR_DOCTOR and STUDENT require is_cosign_required; supervising_provider_id is required when is_cosign_required is true and rejected otherwise. Only JUNIOR_DOCTOR may carry npi; only supervised roles accept schedule. TECH cannot combine with other roles; JUNIOR_DOCTOR combines only with STUDENT. |
first_name |
string or null | |
middle_name |
string or null | |
last_name |
string or null | |
email |
string or null | |
mobile |
string or null | |
clinic_ids |
array of string | Operational clinic ids for published staff; onboarding clinic ids for a not-yet-published record. |
status |
string | ACTIVE/INACTIVE for published staff; ONBOARDING for an unpublished onboarding record, REVOKED once access is revoked before publish. |
is_cosign_required |
boolean | Whether this staff member's actions require a supervising provider's cosign. Required (and must be true) for JUNIOR_DOCTOR and STUDENT. |
supervising_provider_id |
string or null | The supervising provider, required for a supervised role. |
npi |
string or null | |
schedule |
any | Working-hours entries for a supervised role (JUNIOR_DOCTOR / STUDENT), passed through from onboarding's own shape. |
access_revoked |
boolean | Whether this staff member's onboarding access has been revoked. |
created_at |
string (date-time) or null | |
updated_at |
string (date-time) or null |
Error Response¶
Code: 400 Bad Request
{
"code": "bad_request",
"message": "Validation failed",
"errors": [
{
"field": "patient_id",
"message": "must be a string"
}
]
}
Every error has the same shape — a machine-readable code, a message, and an errors[] array that's empty when there's nothing field-specific to report. The HTTP status is authoritative.
| Status | code |
Meaning |
|---|---|---|
400 Bad Request |
bad_request |
The request body or parameters failed validation. errors[] names the offending fields. |
401 Unauthorized |
unauthorized |
The access token is missing, malformed or expired. |
403 Forbidden |
forbidden |
The request references a resource outside the token's organisation or clinic scope. |
404 Not Found |
not_found |
No such resource, or it's outside your scope. |
409 Conflict |
conflict |
The record conflicts with existing state — see the endpoint's notes. |
412 Precondition Failed |
precondition_failed |
If-Match is stale. Re-read the resource and retry. |
423 Locked |
locked |
The organisation has a publish in progress. Retry once it finishes. |
428 Precondition Required |
precondition_required |
If-Match is required on this write. |
429 Too Many Requests |
rate_limited |
Rate limit exceeded. Back off and retry. |
500 Internal Server Error |
internal_error |
Unexpected server error. |
502 Bad Gateway |
upstream_error |
Upstream service failed or timed out. |
Notes¶
- On create,
clinic_idsmust be onboarding clinic ids (from List Onboarding Clinics); an operational clinic id is rejected. The record you get back carries onboarding clinic ids until it is published, operational ids after. rolestakes onboarding's roles, not the singleroleused elsewhere in this reference.