@healthcloudai/hc-healthservice-connector
v0.2.2
Published
Healthcheck Healthservice SDK with TypeScript
Downloads
187
Maintainers
Readme
Healthcheck Healthservice Connector
The Healthservice connector supports the authenticated patient screening flow. It allows an application to retrieve the health services and pending actions available to the patient, load the screening session for a selected service, and submit the completed screening answers.
HCHealthServiceClient uses the authenticated patient session provided by HCLoginClient. The connector applies the required authentication context internally and returns the complete API response produced by each operation without unwrapping or reshaping it.
Installation
npm install @healthcloudai/hc-healthservice-connector \
@healthcloudai/hc-login-connector \
@healthcloudai/hc-httpImport
import { HCHealthServiceClient } from "@healthcloudai/hc-healthservice-connector";
import { HCLoginClient } from "@healthcloudai/hc-login-connector";
import { FetchClient } from "@healthcloudai/hc-http";Setup
Create the shared HTTP client, configure and authenticate the patient through HCLoginClient, and then create the Healthservice client with the same authenticated login instance.
const httpClient = new FetchClient();
const authClient = new HCLoginClient(httpClient);
authClient.configure("demo-tenant", "dev");
await authClient.login(
"<PATIENT_EMAIL>",
"<PATIENT_PASSWORD>"
);
const healthserviceClient = new HCHealthServiceClient(
httpClient,
authClient
);HCHealthServiceClient does not perform a separate login step. The patient session must already be established through the supplied HCLoginClient instance before calling the documented methods.
Optional API Key
When an environment requires an API key header, configure it on the Healthservice client:
const apiKey = process.env.HEALTHCLOUD_API_KEY;
if (!apiKey) {
throw new Error("HEALTHCLOUD_API_KEY is required.");
}
healthserviceClient.setApiKey("x-api-key", apiKey);The configured API key header is included in Healthservice requests together with the authenticated patient context.
API Contracts
Requests that require a body are sent in the standard Healthcloud request envelope:
export interface APIRequest<T> {
Data: T;
}Responses are returned in the standard Healthcloud response envelope:
export interface APIResponse<T> {
Data: T;
IsOK: boolean;
ErrorMessage: string | null;
}The connector returns the full APIResponse<T> value from the API. It does not return only Data, nor does it replace backend ErrorMessage values.
Public Methods
| Method | Returns | Purpose |
| --- | --- | --- |
| listHealthServices() | Promise<APIResponse<HealthcareServiceStart>> | Retrieves available services together with pending patient actions. |
| getScreening(healthServiceId) | Promise<APIResponse<ScreeningSession>> | Retrieves the screening session for a selected health service. |
| submitScreening(submission) | Promise<APIResponse<ScreeningOutcome>> | Submits completed screening answers. |
Typical Screening Flow
const servicesResponse = await healthserviceClient.listHealthServices();
if (!servicesResponse.IsOK || !servicesResponse.Data?.Services.length) {
throw new Error(
servicesResponse.ErrorMessage ?? "No health services are available."
);
}
const selectedService = servicesResponse.Data.Services[0];
const screeningResponse = await healthserviceClient.getScreening(
selectedService.ID
);
if (!screeningResponse.IsOK || !screeningResponse.Data) {
throw new Error(
screeningResponse.ErrorMessage ?? "Unable to load screening."
);
}
const screening = screeningResponse.Data;
const submissionResponse = await healthserviceClient.submitScreening({
HealthServiceID: screening.HealthServiceID,
Title: screening.Title,
Questions: [
{
Question: screening.Questions[0].Question,
ActualAnswers: [
{
FHIRID: "",
Text: "No",
Outcome: null
}
]
}
],
Reasons: screening.Reasons,
HPI: screening.HPI ?? ""
});
if (!submissionResponse.IsOK || !submissionResponse.Data) {
throw new Error(
submissionResponse.ErrorMessage ?? "Unable to submit screening."
);
}listHealthServices()
Retrieves the health services and pending actions available for the authenticated patient.
Signature
healthserviceClient.listHealthServices(): Promise<APIResponse<HealthcareServiceStart>>Behavior
Use this method to load the health service options that can begin a screening flow for the authenticated patient. The response also contains any pending patient actions returned together with those services.
Parameters
This method does not require any parameters.
Returns
Promise<APIResponse<HealthcareServiceStart>>Returns a HealthcareServiceStart object in Data, containing:
Services: health services available for the patient.PendingActions: pending patient actions returned with the service list.
Usage
const response = await healthserviceClient.listHealthServices();
const services = response.Data?.Services ?? [];
const pendingActions = response.Data?.PendingActions ?? [];API Request Sent Internally
This operation does not send a request body.
API Response Example
{
"Data": {
"Services": [
{
"ID": "health-service-id-example",
"Name": "Oral Cancer Screening",
"ScreeningSNOMEDCode": null,
"Description": "Example health service description.",
"ImageURL": "data:image/png;base64,image-data-example",
"IntroImageURL": null,
"Category": "Urgent Care",
"CQLID": null,
"CQL": null,
"Documents": [],
"Reasons": [
{
"ID": "reason-id-example",
"Name": "Oral Cancer Screening"
}
],
"Outcomes": [
{
"Name": "Example linked test",
"GTIN": "example-gtin"
}
],
"AlternativeKBSummary": null,
"ScreeningGenerationAdditionalInstructions": null,
"CQLGenerationAdditionalInstructions": null,
"AgentID": null,
"AdditionalAgentInstructions": null,
"SelectedAccountIDs": [],
"TenantID": null
}
],
"PendingActions": [
{
"ID": "action-id-example",
"IsDefault": false,
"IsRequired": true,
"DeliveryTypes": [
"AGENT_NOTIFICATION"
],
"Message": "Example pending action message.",
"Icon": "",
"LinkText": "Open",
"Link": "patient/action",
"Created": "2026-01-01T00:00:00Z",
"Notified": null
}
]
},
"IsOK": true,
"ErrorMessage": null
}getScreening(...)
Retrieves the screening session for a selected health service.
Signature
healthserviceClient.getScreening(
healthServiceId: string
): Promise<APIResponse<ScreeningSession>>Behavior
Use this method after the patient selects a health service. The returned screening session contains the questions, possible answers, reasons, and screening outcome data needed to render the flow and prepare the completed submission.
A question or possible answer may contain a configured Outcome value. When configured, that value may be returned as an object such as { Name, GTIN }; when no configured outcome exists, it may be null.
Parameters
| Parameter | Type | Required | Description |
| --- | --- | ---: | --- |
| healthServiceId | string | Yes | Identifier of the selected health service returned in Data.Services by listHealthServices(). |
Returns
Promise<APIResponse<ScreeningSession>>Returns the screening session in Data.
Usage
const response = await healthserviceClient.getScreening(
"health-service-id-example"
);API Request Sent Internally
This operation uses healthServiceId to retrieve the screening session and does not send a request body.
API Response Example
{
"Data": {
"ID": "health-service-id-example",
"HealthServiceID": "health-service-id-example",
"AgentID": null,
"Title": "Example Screening",
"Note": null,
"HPI": null,
"Questions": [
{
"Question": "Which test did you take?",
"ID": "Q1",
"Type": "SingleSelect",
"Default": "",
"Description": null,
"Next": "",
"Outcome": null,
"PossibleAnswers": [
{
"Text": "Example test option",
"Next": null,
"Outcome": {
"Name": "Example linked test",
"GTIN": "example-gtin"
}
}
],
"ActualAnswers": null,
"ImageURLs": null
}
],
"Outcome": [
{
"Message": "Based on the information you provided, we suggest you schedule a Telehealth appointment with a provider.",
"Action": "patient/book-appointment",
"Value": 0,
"IsDefault": false,
"ID": null,
"EncounterID": null
}
],
"Reasons": [
{
"ID": "reason-id-example",
"Name": "Example Screening"
}
]
},
"IsOK": true,
"ErrorMessage": ""
}submitScreening(...)
Submits completed screening answers for a selected health service.
Signature
healthserviceClient.submitScreening(
submission: SubmitScreeningData
): Promise<APIResponse<ScreeningOutcome>>Behavior
Use this method after the application has collected the patient answers for the selected screening session. The caller provides the submission data directly, and the connector constructs the required APIRequest<T> envelope internally.
The documented submission shape follows the current patient application payload, where submitted answer Outcome values are sent as a string or null.
Parameters
| Parameter | Type | Required | Description |
| --- | --- | ---: | --- |
| submission | SubmitScreeningData | Yes | Completed screening submission data. |
| submission.HealthServiceID | string | Yes | Identifier of the health service for the screening flow. |
| submission.Title | string | Yes | Title of the screening flow being submitted. |
| submission.Questions | ScreeningSubmissionQuestion[] | Yes | Submitted questions and their actual answers. |
| submission.Reasons | ReasonForVisit[] | Yes | Reasons associated with the selected health service. |
| submission.HPI | string | Yes | HPI value submitted with the screening flow. |
Returns
Promise<APIResponse<ScreeningOutcome>>Returns the resulting ScreeningOutcome in Data.
Usage
const response = await healthserviceClient.submitScreening({
HealthServiceID: "health-service-id-example",
Title: "Example Screening",
Questions: [
{
Question: "Were you diagnosed with the condition?",
ActualAnswers: [
{
FHIRID: "",
Text: "No",
Outcome: null
}
]
}
],
Reasons: [
{
ID: "reason-id-example",
Name: "Example Screening"
}
],
HPI: ""
});API Request Sent Internally
{
"Data": {
"HealthServiceID": "health-service-id-example",
"Title": "Example Screening",
"Questions": [
{
"Question": "Were you diagnosed with the condition?",
"ActualAnswers": [
{
"FHIRID": "",
"Text": "No",
"Outcome": null
}
]
}
],
"Reasons": [
{
"ID": "reason-id-example",
"Name": "Example Screening"
}
],
"HPI": ""
}
}API Response Example
{
"Data": {
"Message": "",
"Action": null,
"Value": 0,
"IsDefault": false,
"ID": "record-id-example",
"EncounterID": "encounter-id-example"
},
"IsOK": true,
"ErrorMessage": null
}Type Reference
ReasonForVisit
export interface ReasonForVisit {
ID: string;
Name: string;
}HealthcareService
export interface HealthcareService {
ID: string;
Name: string;
ScreeningSNOMEDCode: string | null;
Description: string;
ImageURL: string;
IntroImageURL: string | null;
Category: string;
CQLID: string | null;
CQL: string | null;
Documents: string[];
Reasons: ReasonForVisit[];
Outcomes: Array<Record<string, string | null>>;
AlternativeKBSummary: string | null;
ScreeningGenerationAdditionalInstructions: string | null;
CQLGenerationAdditionalInstructions: string | null;
AgentID: string | null;
AdditionalAgentInstructions: string | null;
SelectedAccountIDs: string[];
TenantID: string | null;
}PHCAction
export interface PHCAction {
ID: string;
IsDefault: boolean;
IsRequired: boolean;
DeliveryTypes: string[];
Message: string;
Icon: string;
LinkText: string;
Link: string;
Created: string;
Notified: string | null;
}HealthcareServiceStart
export interface HealthcareServiceStart {
Services: HealthcareService[];
PendingActions: PHCAction[];
}ScreeningSession
export type ScreeningOutcomeValue =
| Record<string, string | null>
| string
| null;
export interface ScreeningPossibleAnswer {
FHIRID?: string | null;
Text: string;
Next: string | null;
Outcome: ScreeningOutcomeValue;
}
export interface ScreeningQuestion {
Question: string;
ID: string;
Type: string;
Default: string;
Description: string | null;
Next: string | null;
Outcome: ScreeningOutcomeValue;
PossibleAnswers: ScreeningPossibleAnswer[];
ActualAnswers: ScreeningPossibleAnswer[] | null;
ImageURLs: string[] | null;
}
export interface ScreeningOutcome {
Message: string;
Action: string | null;
Value: number;
IsDefault: boolean;
ID: string | null;
EncounterID: string | null;
}
export interface ScreeningSession {
ID: string;
HealthServiceID: string;
AgentID: string | null;
Title: string;
Note: string | null;
HPI: string | null;
Questions: ScreeningQuestion[];
Outcome: ScreeningOutcome[];
Reasons: ReasonForVisit[];
}SubmitScreeningData
export interface ScreeningSubmissionAnswer {
FHIRID: string;
Text: string;
Outcome: string | null;
}
export interface ScreeningSubmissionQuestion {
Question: string;
ActualAnswers: ScreeningSubmissionAnswer[];
}
export interface SubmitScreeningData {
HealthServiceID: string;
Title: string;
Questions: ScreeningSubmissionQuestion[];
Reasons: ReasonForVisit[];
HPI: string;
}Notes
- All documented Healthservice methods use the authenticated patient context from
HCLoginClient. HCLoginClientmust be configured and the patient session established before calling these methods.- Pass the same authenticated
HCLoginClientinstance when constructingHCHealthServiceClient. listHealthServices()returns both available health services and pending patient actions inData.getScreening(...)retrieves aScreeningSessionfor the selected health service.submitScreening(...)acceptsSubmitScreeningDatadirectly and wraps it internally inAPIRequest<SubmitScreeningData>.- Connector methods return the complete
APIResponse<T>object without unwrapping or transforming backend responses.
Prerequisites
HCLoginClient must be configured and the patient must be logged in before calling any method on this connector.
import { HCLoginClient } from "@healthcloudai/hc-login-connector";
import { FetchClient } from "@healthcloudai/hc-http";
const httpClient = new FetchClient();
const loginClient = new HCLoginClient(httpClient);
loginClient.configure("healthcheck", "dev");
await loginClient.login("[email protected]", "ExamplePassword123!");See the hc-login-connector documentation for the full authentication flow.
Error Handling
All methods throw errors that extend APIError from @healthcloudai/hc-http.
Backend business failures (IsOK: false) are thrown as HCServiceError.
import { HCServiceError, APIError } from "@healthcloudai/hc-http";
try {
const result = await client.someMethod();
} catch (err) {
if (err instanceof HCServiceError) {
console.error("Backend error:", err.backendMessage);
} else if (err instanceof APIError) {
console.error("SDK error:", err.message, err.code);
}
}