# Onboard a patient in one request

Operation ID: `fieldagent.onboardPatient`

Runs the patient-onboarding workflow — register patient, create encounter, submit vitals, submit questionnaire responses — as a single request for field agents, instead of the four separate calls the Patient/CDC app makes. Reuses the exact same service calls as those individual endpoints (RegistrationService.register, EncountersService.create, VitalsService.upsert, HealthServicesService.create_response) — no business logic is duplicated. 

Requires a valid field-agent Bearer JWT; the calling agent's own FHIR Person id (resolved from the token) is stamped as created_by on the new patient and, if requested, the encounter. 

Execution order and atomicity: patient registration (step 1) always runs first and is the prerequisite for every later step — if it fails, nothing else is attempted and nothing was created, so overall_status is 'failed' (HTTP 400) with no ids to resume from. Once registration succeeds, encounter (step 2), vitals (step 3) and questionnaire response (step 4) each run independently in that order; a failure in one does not roll back or block the others — an already-created patient (and encounter, if it succeeded) stays committed even if a later step fails. There is no cross-service distributed transaction, so overall_status is 'completed' (HTTP 201) only when every requested step succeeded, and 'partial' (HTTP 207) when registration succeeded but at least one requested downstream step failed. Each step result carries its own id (fhir_patient_id, fhir_id, questionnaire_fhir_id) so a caller can resume a partial onboarding by calling the corresponding individual endpoint directly instead of re-registering the patient. Retrying this same request after a partial failure creates a brand-new patient rather than resuming the previous one — there is no idempotency key. 

Optional inputs: encounter, vitals and questionnaire may each be omitted; an omitted section is reported back with status 'skipped' and is never attempted. patient.password is optional — if omitted, a random password meeting the platform's complexity policy is generated server-side and never returned (see patient.temp_password_generated); the field agent must relay a reset flow to the patient separately. 

The onboarded patient's email verification follows the standard Patient-API registration flow. patient.flags.AUTO_VERIFY_EMAIL=true requests immediate email verification and an attempted login; when it is absent or false, email_verified starts false and an email OTP is sent (patient.email_otp_sent reflects whether SendGrid delivery succeeded). This service's AUTO_VERIFY_EMAIL environment variable only affects fieldagent.register, the agent's own account. No SMS OTP is sent during onboarding.

## Public method

`onboardPatient`

Signature: `fieldAgent.onboardPatient(request)`

Return type: `Promise<OnboardPatientResponse>`

## Authentication

Classification: **AUTHENTICATED**

Schemes: `bearerAuth`

## Prerequisites

None documented.

## HTTP

`POST /onboardpatients`

## Path parameters

None.

## Query parameters

None.

## Body parameters

| Name | Type | Required | Format | Allowed values | Default | Nullable | Description |
|---|---|---:|---|---|---|---:|---|
| `body` | [`OnboardPatientRequest`](../models/OnboardPatientRequest.md) | Yes |  |  |  | No |  |

Request model: [`OnboardPatientRequest`](../models/OnboardPatientRequest.md)

## Request example

```json
{
  "encounter": {
    "appointment_id": "string",
    "created_date": "string",
    "diagnoses": [
      {
        "condition_display": "string",
        "condition_id": "string",
        "rank": 1,
        "use_code": "CC"
      }
    ],
    "encounter_class": "AMB",
    "encounter_id": "string",
    "fhir_id": "string",
    "hospitalization": {
      "admit_source_code": "string",
      "destination_id": "string",
      "discharge_disposition": "home",
      "origin_id": "string",
      "pre_admission_id": "string",
      "re_admission_code": "string"
    },
    "length_minutes": 0,
    "locations": [
      {
        "location_display": "string",
        "location_id": "string",
        "period_end": "2026-01-01T09:00:00Z",
        "period_start": "2026-01-01T09:00:00Z",
        "status": "active"
      }
    ],
    "participants": [
      {
        "participant_type": "PPRF",
        "period_end": "2026-01-01T09:00:00Z",
        "period_start": "2026-01-01T09:00:00Z",
        "practitioner_display": "string",
        "practitioner_id": "string"
      }
    ],
    "period_end": "string",
    "period_start": "string",
    "priority_code": "string",
    "priority_display": "string",
    "reason_code": "string",
    "reason_display": "string",
    "service_provider_display": "string",
    "service_provider_id": "string",
    "service_type_code": "string",
    "service_type_display": "string",
    "status": "planned",
    "type_code": "string",
    "type_display": "string"
  },
  "patient": {
    "addresses": [],
    "attributes": {
      "INITIAL_CONVERSATION": "string"
    },
    "date_of_birth": "string",
    "email": "string",
    "first_name": "string",
    "flags": {
      "AUTO_VERIFY_EMAIL": false
    },
    "last_name": "string",
    "password": "string",
    "phone": "string",
    "race": "american_indian_or_alaska_native",
    "sex_at_birth": "male"
  },
  "questionnaire": {
    "definition": {
      "items": [
        {
          "link_id": "string",
          "text": "string",
          "type": "string"
        }
      ],
      "name": "string",
      "status": "active",
      "title": "string"
    },
    "items": [
      {
        "answers": [
          {
            "value_boolean": true,
            "value_integer": 0,
            "value_string": "string"
          }
        ],
        "link_id": "string"
      }
    ],
    "questionnaire_id": "string",
    "status": "completed"
  },
  "vitals": {
    "diastolic": 0,
    "heart_rate": 0,
    "height_cm": 0,
    "oxygen_saturation": 0,
    "systolic": 0,
    "temperature": 0,
    "weight_kg": 0
  }
}
```

## Success responses

| Status | Shape | Content type | Description |
|---|---|---|---|
| `201` | [`OnboardPatientResponse`](../models/OnboardPatientResponse.md) | application/json | Completed — every requested step succeeded. |
| `207` | [`OnboardPatientResponse`](../models/OnboardPatientResponse.md) | application/json | Partial — patient registration succeeded but at least one requested downstream step failed. This is a successful HTTP response (not an error): check overall_status and each step's own status/error to see what happened. |

## Success response examples

### 201

```json
{
  "encounter": {
    "error": null,
    "fhir_id": "encounter-example-001",
    "status": "success"
  },
  "overall_status": "completed",
  "patient": {
    "access_token": "example-access-token",
    "cognito_sub": "00000000-0000-4000-8000-000000000000",
    "email_otp_sent": false,
    "email_verified": true,
    "error": null,
    "expires_in": 3600,
    "fhir_patient_id": "patient-example-001",
    "id_token": "example-id-token",
    "status": "success",
    "telehealth_id": 1700000000,
    "temp_password_generated": false
  },
  "questionnaire_response": {
    "error": null,
    "fhir_id": "questionnaire-response-example-001",
    "questionnaire_fhir_id": "questionnaire-example-001",
    "status": "success"
  },
  "vitals": {
    "error": null,
    "observation_count": 4,
    "status": "success"
  }
}
```

### 207 — PARTIAL — patient registered, but the encounter step failed validation (real captured shape)

```json
{
  "encounter": {
    "error": "1 validation error for Encounter\nencounter_class\n  Input should be 'AMB', 'EMER', 'FLD', 'HH', 'ACUTE', 'NONAC', 'OBSENC', 'PRENC', 'SS' or 'VR'",
    "fhir_id": null,
    "status": "failed"
  },
  "overall_status": "partial",
  "patient": {
    "cognito_sub": "00000000-0000-4000-8000-000000000000",
    "email_otp_sent": true,
    "email_verified": false,
    "error": null,
    "fhir_patient_id": "patient-example-001",
    "status": "success",
    "telehealth_id": 1700000000,
    "temp_password_generated": true
  },
  "questionnaire_response": {
    "error": null,
    "fhir_id": null,
    "questionnaire_fhir_id": null,
    "status": "skipped"
  },
  "vitals": {
    "error": null,
    "observation_count": null,
    "status": "skipped"
  }
}
```

## Common errors

| Status | Shape | Content type | Description |
|---|---|---|---|
| `400` | `model` | application/json | Bad request — either the request itself is malformed (ErrorResponse shape), or patient registration (step 1) itself failed (OnboardPatientResponse shape, overall_status='failed'; every step is 'skipped' or 'failed', nothing was created). |
| `401` | [`fieldagent.ErrorResponse`](../models/fieldagent.ErrorResponse.md) | application/json | Authorization required |

## Error examples

### 400 — The request body has no patient object

```json
{
  "error": "patient object is required"
}
```

### 400 — FAILED — patient registration itself was rejected; nothing was created

```json
{
  "encounter": {
    "error": null,
    "fhir_id": null,
    "status": "skipped"
  },
  "overall_status": "failed",
  "patient": {
    "cognito_sub": null,
    "email_otp_sent": null,
    "email_verified": null,
    "error": "email already registered",
    "fhir_patient_id": null,
    "status": "failed",
    "telehealth_id": null,
    "temp_password_generated": null
  },
  "questionnaire_response": {
    "error": null,
    "fhir_id": null,
    "questionnaire_fhir_id": null,
    "status": "skipped"
  },
  "vitals": {
    "error": null,
    "observation_count": null,
    "status": "skipped"
  }
}
```

### 401

```json
{
  "error": "string"
}
```

## NodeJS / TypeScript implementation

```ts
import { HCSDK } from "@healthcloudai/hc-sdk";
import type { OnboardPatientRequest } from "@healthcloudai/hc-sdk";
```

```ts
const request = {
  "encounter": {
    "appointment_id": "string",
    "created_date": "string",
    "diagnoses": [
      {
        "condition_display": "string",
        "condition_id": "string",
        "rank": 1,
        "use_code": "CC"
      }
    ],
    "encounter_class": "AMB",
    "encounter_id": "string",
    "fhir_id": "string",
    "hospitalization": {
      "admit_source_code": "string",
      "destination_id": "string",
      "discharge_disposition": "home",
      "origin_id": "string",
      "pre_admission_id": "string",
      "re_admission_code": "string"
    },
    "length_minutes": 0,
    "locations": [
      {
        "location_display": "string",
        "location_id": "string",
        "period_end": "2026-01-01T09:00:00Z",
        "period_start": "2026-01-01T09:00:00Z",
        "status": "active"
      }
    ],
    "participants": [
      {
        "participant_type": "PPRF",
        "period_end": "2026-01-01T09:00:00Z",
        "period_start": "2026-01-01T09:00:00Z",
        "practitioner_display": "string",
        "practitioner_id": "string"
      }
    ],
    "period_end": "string",
    "period_start": "string",
    "priority_code": "string",
    "priority_display": "string",
    "reason_code": "string",
    "reason_display": "string",
    "service_provider_display": "string",
    "service_provider_id": "string",
    "service_type_code": "string",
    "service_type_display": "string",
    "status": "planned",
    "type_code": "string",
    "type_display": "string"
  },
  "patient": {
    "addresses": [],
    "attributes": {
      "INITIAL_CONVERSATION": "string"
    },
    "date_of_birth": "string",
    "email": "string",
    "first_name": "string",
    "flags": {
      "AUTO_VERIFY_EMAIL": false
    },
    "last_name": "string",
    "password": "string",
    "phone": "string",
    "race": "american_indian_or_alaska_native",
    "sex_at_birth": "male"
  },
  "questionnaire": {
    "definition": {
      "items": [
        {
          "link_id": "string",
          "text": "string",
          "type": "string"
        }
      ],
      "name": "string",
      "status": "active",
      "title": "string"
    },
    "items": [
      {
        "answers": [
          {
            "value_boolean": true,
            "value_integer": 0,
            "value_string": "string"
          }
        ],
        "link_id": "string"
      }
    ],
    "questionnaire_id": "string",
    "status": "completed"
  },
  "vitals": {
    "diastolic": 0,
    "heart_rate": 0,
    "height_cm": 0,
    "oxygen_saturation": 0,
    "systolic": 0,
    "temperature": 0,
    "weight_kg": 0
  }
};

const result = await fieldAgent.onboardPatient(request);
```

## cURL

```bash
curl -X POST \
  -H 'Authorization: Bearer <ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"encounter":{"appointment_id":"string","created_date":"string","diagnoses":[{"condition_display":"string","condition_id":"string","rank":1,"use_code":"CC"}],"encounter_class":"AMB","encounter_id":"string","fhir_id":"string","hospitalization":{"admit_source_code":"string","destination_id":"string","discharge_disposition":"home","origin_id":"string","pre_admission_id":"string","re_admission_code":"string"},"length_minutes":0,"locations":[{"location_display":"string","location_id":"string","period_end":"2026-01-01T09:00:00Z","period_start":"2026-01-01T09:00:00Z","status":"active"}],"participants":[{"participant_type":"PPRF","period_end":"2026-01-01T09:00:00Z","period_start":"2026-01-01T09:00:00Z","practitioner_display":"string","practitioner_id":"string"}],"period_end":"string","period_start":"string","priority_code":"string","priority_display":"string","reason_code":"string","reason_display":"string","service_provider_display":"string","service_provider_id":"string","service_type_code":"string","service_type_display":"string","status":"planned","type_code":"string","type_display":"string"},"patient":{"addresses":[],"attributes":{"INITIAL_CONVERSATION":"string"},"date_of_birth":"string","email":"string","first_name":"string","flags":{"AUTO_VERIFY_EMAIL":false},"last_name":"string","password":"string","phone":"string","race":"american_indian_or_alaska_native","sex_at_birth":"male"},"questionnaire":{"definition":{"items":[{"link_id":"string","text":"string","type":"string"}],"name":"string","status":"active","title":"string"},"items":[{"answers":[{"value_boolean":true,"value_integer":0,"value_string":"string"}],"link_id":"string"}],"questionnaire_id":"string","status":"completed"},"vitals":{"diastolic":0,"heart_rate":0,"height_cm":0,"oxygen_saturation":0,"systolic":0,"temperature":0,"weight_kg":0}}' \
  'https://dev-api-fieldagent.health.cloud/onboardpatients'
```

## Notes

None.

## Prepared Test Console scenario

No canonical scenario is currently associated.

## Real response

No approved real integration response is currently published. Unapproved candidates are never rendered as examples.
