Docs

Users

Map each patient to one Doctronic user, store the ID on your backend, and collect the demographics each workflow needs.

A Doctronic user is the record for one patient in your organization. Create it once, store its ID with the patient record in your system, and send that ID as X-Doctronic-User-ID on every later request for the patient.

# Reuse the same key and body if you retry this request.
IDEMPOTENCY_KEY="$(uuidgen)"
# Email and phone number are unique per user, so this uses a fresh email and no phone number.
EMAIL="avery+$(uuidgen)@example.com"

curl --fail-with-body --request POST "$DOCTRONIC_API_URL/users/" \
  --header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
  --header "Idempotency-Key: $IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "firstName": "Avery",
    "lastName": "Chen",
    "dateOfBirth": "1990-06-15",
    "email": "'"$EMAIL"'",
    "sex": "female"
  }'
import { randomUUID } from 'node:crypto';

const baseUrl = process.env.DOCTRONIC_API_URL ?? 'https://staging-partners.doctronic.ai/api/v1';

const response = await fetch(`${baseUrl}/users/`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.DOCTRONIC_API_TOKEN}`,
    'Idempotency-Key': randomUUID(),
    'Content-Type': 'application/json',
  },
  // Email and phone number are unique per user, so this uses a fresh email and no phone number.
  body: JSON.stringify({
    firstName: 'Avery',
    lastName: 'Chen',
    dateOfBirth: '1990-06-15',
    email: `avery+${randomUUID()}@example.com`,
    sex: 'female',
  }),
});
if (!response.ok) throw new Error(`Doctronic ${response.status}: ${await response.text()}`);
const { data: user } = await response.json();
// Save user.id on the patient record in your system.
201 Created
{
  "code": "success",
  "message": "Request successful",
  "data": {
    "id": "mem_01K6JGGM2G2DB4Y9KB9H9MJJ6Q",
    "createdAt": "2026-08-31T14:30:00Z",
    "firstName": "Avery",
    "lastName": "Chen",
    "dateOfBirth": "1990-06-15",
    "email": "avery+0f8fad5b-d9cb-469f-a165-70867728950e@example.com",
    "phoneNumber": null,
    "sex": "female",
    "appointmentDemographicsComplete": false,
    "missingAppointmentFields": ["phoneNumber"]
  }
}

Creating a user takes the token alone; see request headers.

Store the mapping

Patient record in your system  ->  Doctronic user ID (mem_…)  ->  chats, appointments, consultation documents

Your backend owns this mapping, and it is the only link between the two records.

  • Look up the stored mapping first, and create a user only for a patient who has none.
  • Derive the user ID on your backend from the patient your system authenticated. Treat an ID sent by a browser, mobile app, or agent as untrusted until it matches your mapping.
  • Keep staging and production mappings apart. User IDs belong to one environment.

A timed-out create is safe to retry with the same Idempotency-Key and body; see idempotent requests. If the email or phone number already belongs to another user, the API returns 400 error.user.conflict and never merges or transfers users. Reconcile the patient against your mapping before you try again.

Collect demographics for each workflow

Every field on POST /users/ is optional, so you can create the user as soon as the patient starts a consultation. Later workflows return 400 when a field they need is missing:

WorkflowRequired on the userAlso requiredError when a field is missing
ConsultationNothingNoneNone
Appointment bookingfirstName, lastName, dateOfBirth, phoneNumberA complete address and a completed chaterror.appointments.missing_patient_demographics
Pharmacy selectionfirstName, lastName, dateOfBirth, sexNoneerror.pharmacy.missing_patient_demographics
Insurance coveragefirstName, lastName, dateOfBirth, sexNoneerror.coverage.missing_patient_demographics
FieldFormat
firstName, lastNameUp to 50 characters
dateOfBirthISO 8601 date
emailAn email address
phoneNumberE.164, such as +15555550100. When carrier lookup is enabled, the default policy accepts mobile and VoIP numbers and rejects landlines.
sexmale or female: sex assigned at birth, not gender

Check appointment readiness

Every user response includes appointmentDemographicsComplete, which is true when the four booking fields are present, and missingAppointmentFields, which lists the ones still missing. Collect them before you offer a visit. Both fields describe the user record only and don't authorize a booking; booking also checks the address and the chat.

Read and update a user

GET /users/ returns the profile for the user in X-Doctronic-User-ID, in the same shape as the create response. PATCH /users/ corrects or completes it. Send only the fields you want to change. Email and phone number are unique per user, so send the patient's own values:

# Reuse the same key if you retry this request.
IDEMPOTENCY_KEY="$(uuidgen)"

curl --fail-with-body --request PATCH "$DOCTRONIC_API_URL/users/" \
  --header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
  --header "X-Doctronic-User-ID: $DOCTRONIC_USER_ID" \
  --header "Idempotency-Key: $IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "dateOfBirth": "1990-06-15",
    "email": null
  }'
You sendResult
A field with a valueThe field changes.
A field set to nullThe field is cleared.
No entry for a fieldThe field keeps its current value.
A blank name or phone number400. Send null to clear the field.
Any field other than firstName, lastName, dateOfBirth, email, phoneNumber, or sex400

The SDKs follow the same rules. In Python, pass None to clear a field and leave the argument out to keep it. In TypeScript, pass null to clear a field and leave the key out, or set it to undefined, to keep it.

The user ID and existing chats stay the same. Changes apply to the profile and to future bookings, not to visits already booked or to past clinical content, so book from the same completed chat once the missing fields are filled in. A replayed update returns the original response; call GET /users/ for the current profile.

Handle stale mappings

ResponseMeaningAction
404 error.member.not_foundThe user ID doesn't exist, isn't active, or doesn't belong to the organization that owns the token.Check that the mapping and the token come from the same environment and organization.
404 on a user-scoped resourceThe resource is missing or belongs to a different user.Confirm the stored user ID for the patient before you retry.
No mapping for a returning patientYour system lost the link.Reconcile identity in your system before you create another user.

Limits

  • The API stores no external patient identifier and has no user search.
  • dateOfBirth accepts ages 18 through 120 only.
  • The API has no operation to delete a user. Plan retention and deletion with Doctronic during your security and privacy review.
  • The API doesn't verify that the patient owns the email address or phone number.

On this page