Working with Tasks
Retrieve care needs, health activities, next best actions, and network retrieval tasks with the b.well TypeScript SDK (@icanbwell/bwell-sdk-ts)
What can you do?
-
Filter by task type (care needs, health activities, NBAs, data connections)
-
Need the full schema, enum list, or error reference? Jump to Reference or Troubleshooting.
Get all tasks for the current user
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
// Pass a GetTasksRequest to fetch all user-facing tasks.
// System tasks (performer.code = 'system') are excluded by default.
const result = await sdk.activity.getTasks(new GetTasksRequest({ page: 0 }));
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const tasks = entries.map((e) => e?.resource).filter(Boolean);
console.log`Found ${tasks.length} task(s)`);
tasks.forEach((t) => {
console.log(t.id, t.status, t.code?.coding?.[0]?.code, t.description);
});📘 Notes
- getTasks() returns a BWellQueryResult, so use result.data and result.error as properties and result.hasError() as a method. There is no .success() here.
- GetTasksRequest is required. There is no zero-arg overload.
- When the user has no tasks, result.data?.entry is null, guard with Array.isArray before mapping.
- System tasks are excluded by default. The SDK automatically adds a performer notEquals system filter. To override it, pass performer: {values: [...]}. Only the values array (plural) disables the exclusion. Using performer.value (singular) does not override it.
Filter by task type
Use the code field to retrieve a specific category of task. All b.well task types share the system https://www.icanbwell.com/activityType.
Retrieve only care-needs tasks :
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
// Retrieve only care-need tasks (clinical recommendations for the user).
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0,
code: {
value: {
system: 'https://www.icanbwell.com/activityType',
code: 'care-need',
},
},
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const careNeeds = entries.map((e) => e?.resource).filter(Boolean);
console.log`Found ${careNeeds.length} care need(s)`);
careNeeds.forEach((t) => console.log(t.id, t.description));
Retrieve care needs and health activities in one call :
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
const ACTIVITY_TYPE = 'https://www.icanbwell.com/activityType';
// Retrieve care needs AND health activities in one call.
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0,
code: {
values: [
{ system: ACTIVITY\_TYPE, code: 'care-need' },
{ system: ACTIVITY\_TYPE, code: 'health-activity' },
],
},
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const tasks = entries.map((e) => e?.resource).filter(Boolean);
console.log`Found ${tasks.length} task(s)`);
📘 Task type codes
The supported values for the code field are documented in the Task Types reference below. The most common ones for payer integrations are care-need, health-activity, and network-data-retrieval.
Filter by status
Use the status field to narrow results to tasks in a particular lifecycle state. Pass the status value in the value property of SearchTokenValue. The SDK normalizes it to lowercase with dashes automatically (e.g., IN_PROGRESS → in-progress).
Retrieve only active (in-progress) tasks :
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
// Retrieve only active (in-progress) tasks.
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0,
status: {
value: { value: 'in-progress' },
},
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const tasks = entries.map((e) => e?.resource).filter(Boolean);
console.log`Found ${tasks.length} in-progress task(s)`);
Retrieve tasks that are ready OR in-progress :
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
// Retrieve tasks that are ready OR in-progress (i.e., not yet resolved).
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0,
status: {
values: \[
{ value: 'ready' },
{ value: 'in-progress' },
],
},
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const tasks = entries.map((e) => e?.resource).filter(Boolean);
console.log`Found ${tasks.length} pending/active task(s)`);
📘 Status normalization
The SDK lowercases and converts underscores to dashes on the value field before sending to the server. You can pass 'IN_PROGRESS' or 'in-progress', but both resolve to 'in-progress'. The code and system subfields are not normalized.
Check Individual Access Service (IAS) network retrieval status
Use the Smart Connect flow to create a network-data-retrieval task when a user provides the necessary consent. Poll this task to surface the retrieval status to the user during the async gap between consent creation and data availability.
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
// IAS tasks are system tasks. You must pass performer.values to override the
// default system-task exclusion, otherwise this call returns empty results.
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0,
code: {
value: {
system: 'https://www.icanbwell.com/activityType',
code: 'network-data-retrieval',
},
},
performer: {
values: [
{ system: 'https://www.icanbwell.com/performerType', code: 'system' },
],
},
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
const [iasTask] = entries.map((e) => e?.resource).filter(Boolean);
if (!iasTask) {
console.log('No IAS task found — user has not yet provided IAS consent.');
} else {
const status = iasTask.status;
const label = iasTask.businessStatus?.coding?.[0]?.display;
const errors = iasTask.output ?? [];
console.log(`IAS status: ${status} (${label})`);
if (status === 'failed') {
const errorDetail = errors
.map((o) => o?.valueCodeableConcept?.coding?.[0]?.display)
.filter(Boolean)
.join(', ');
console.error('IAS retrieval error:', errorDetail);
}
}📘 Network data retrieval task lifecycle
The network data retrieval task is created when the user calls createConsent(category: 'IAS_IMPORT_RECORDS'). It transitions through these states:
| status | businessStatus.display | Meaning |
|---|---|---|
| ready | PENDING | Consent accepted; pipeline not yet started |
| in-progress | RETRIEVING | Pipeline is actively fetching records |
| completed | RETRIEVED | Records fetched and stored successfully |
| failed | ERROR | Retrieval failed; check task.output for details |
| rejected | REJECTED | User revoked IAS consent |
If no network data retrieval task is returned, the user has not yet provided the required consent.
🚧 System task visibility
The network-data-retrieval task is created with performer.code = 'system' and is excluded by default. A code filter alone does not override this. You must also pass performer: { values: [{ system: 'https://www.icanbwell.com/performerType', code: 'system' }] }. Without it, getTasks returns an empty result even when the task exists.
Paginate results
import { BWellSDK, GetTasksRequest } from '@icanbwell/bwell-sdk-ts';
const sdk = new BWellSDK({ clientKey: 'YOUR_CLIENT_KEY' });
await sdk.initialize();
await sdk.authenticate({ token: 'YOUR_ACCESS_TOKEN' });
const result = await sdk.activity.getTasks(
new GetTasksRequest({
page: 0, // zero-based
pageSize: 10,
})
);
if (result.hasError()) {
console.error('getTasks failed:', result.error);
process.exit(1);
}
const total = result.data?.total ?? 0;
const entries = Array.isArray(result.data?.entry) ? result.data.entry : [];
console.log`Page 1 of ${Math.ceil(total / 10)}: ${entries.length} task(s) (${total} total)`);📘 Pagination notes
- page is zero-based. Page 0 is the first page.
- pageSize defaults to the SDK's built-in default if omitted.
- result.data.total gives the total count across all pages (accurate mode is always enabled).
Reference
Result type cheat sheet
| Method | Returns | How to read it |
|---|---|---|
| sdk.activity.getTasks(...) | BWellQueryResult<TaskResponse, BaseManagerError> | result.data (property), result.error (property), result.hasError() (method). No .success(). |
Task types
| code | Description |
|---|---|
| care-need | Clinical recommendations: things the user should do for their health (e.g., schedule a screening). |
| health-activity | Activities the user can take to improve health: nutrition, fitness, sleep, emotional health, promotions. |
| network-data-retrieval | Smart Connect query status task. Tracks the lifecycle of a network data retrieval job. |
| data-connection | Tasks related to data source connections (e.g., linking an insurance account). |
| notification | In-app notification tasks. |
All task types share the system https://www.icanbwell.com/activityType.
Task status values
Pass these in the value field of SearchTokenValue. Casing and underscore-to-dash normalization is applied automatically.
| Status | Meaning |
|---|---|
| ready | Task created and waiting to be picked up. |
| in-progress | Task is actively being worked on. |
| completed | Task finished successfully. |
| failed | Task encountered an error. Check task.output for details. |
| rejected | Task was rejected (e.g., user revoked consent). |
| cancelled | Task was cancelled before completion. |
GetTasksRequest fields
| Field | Type | Notes |
|---|---|---|
| code | SearchToken | Filter by task type. Use system: 'https://www.icanbwell.com/activityType' and code set to a task type code. |
| status | SearchToken | Filter by lifecycle status. Use the value subfield; it gets lowercased and underscore-to-dash normalized. |
| id | SearchString | Fetch a specific task by its FHIR resource ID. |
| identifier | SearchToken | Filter by a business identifier. |
| tag | SearchToken | Filter by resource tag. |
| performer | SearchToken | Override the default system-task exclusion. By default, tasks with performer.code = 'system' are excluded. Pass values: [{system: 'https://www.icanbwell.com/performerType', code: 'system'}] to include them. Must use values (plural). Using value (singular) will not disable the exclusion. |
| subject | SearchReference | Filter by the patient/subject reference. Usually not required, as the SDK scopes to the authenticated user by default. |
| page | number | Zero-based page index. Required. Pass 0 for the first page. |
| pageSize | number | Number of results per page. Defaults to the SDK default page size. |
Task response shape
This is the Task resource as typed by the SDK. Most fields are nullable. Field types, in TypeScript terms:
| Field | Type | Notes | ||
|---|---|---|---|---|
| id | string | |||
| status | string | null | Lowercase. One of: ready, in-progress, completed, failed, rejected, cancelled. | ||
| description | string | null | Human-readable label for the task. | ||
| code | CodeableConcept | null | Task type. Read via task.code?.coding?.[0]?.code. | ||
| businessStatus | CodeableConcept | null | User-facing status label (e.g., PENDING, RETRIEVING, RETRIEVED, ERROR). Read via task.businessStatus?.coding?.[0]?.display. | ||
| priority | string | null | 'routine' or 'urgent'. | ||
| executionPeriod | Period | null | { start: string | null, end: string | null } When the task started/ended. |
| lastModified | string | null | ISO 8601 timestamp of the last status update. | ||
| for | Reference | null | The patient/user this task belongs to. | ||
| basedOn | (Reference | null)[] | null | The consent(s) that created this task. | ||
| focus | Reference | null | The resource this task is acting on (e.g., CommonWell patient reference for TEFCA IAS tasks). | ||
| output | (TaskOutput | null)[] | null | Error details when status === 'failed'. Each entry has type, valueString, and valueCodeableConcept. | ||
| identifier | (Identifier | null)[] | null | |||
| meta | Meta | null | |||
| extension | (Extension | null)[] | null |
Reading errors from a failed task
When task.status === 'failed', inspect task.output for machine-readable error details:
const errors = task.output ?? [];
const errorMessages = errors
.map((o) => ({
code: o?.valueCodeableConcept?.coding?.[0]?.code,
display: o?.valueCodeableConcept?.coding?.[0]?.display,
text: o?.valueString,
}))
.filter((e) => e.code || e.text);
console.log('Task errors:', errorMessages);
// Example output:
// [{ code: 'REGISTER_PATIENT_ERROR', display: 'Failed to register patient to CommonWell.', text: null }]Troubleshooting
Each heading below is the exact error string or symptom you'll encounter. Search this section by copying the message from your console.
Issue: getTasks returns 0 results but tasks exist in the system. The default performer filter excludes system tasks. Some task types (including IAS network-data-retrieval) are created with performer.code = 'system'.
Fix: Pass performer: { values: [{ system: 'https://www.icanbwell.com/performerType', code: 'system' }] } to disable the default exclusion. Note: only performer.values (the array) disables it. performer.value (singular) does not. A code filter alone will not override the exclusion.
Issue: IAS task not found (getTasks returns empty for network-data-retrieval) Either the user has not yet provided IAS consent via createConsent(category: 'IAS_IMPORT_RECORDS'), or the system-task exclusion is filtering it out.
Fix: Confirm the user has completed the IAS consent step first. Then query with both a code filter and performer.values. A code filter alone does not bypass the system-task exclusion:
new GetTasksRequest({
page: 0,
code: { value: { system: 'https://www.icanbwell.com/activityType', code: 'network-data-retrieval' } },
performer: { values: [{ system: 'https://www.icanbwell.com/performerType', code: 'system' }] },
})
If still empty after both filters, the consent was accepted but the pipeline has not yet created the task. Retry after a brief delay.
Issue: The status filter returns no results even though tasks exist. The status filter uses the value subfield, not code. Passing status: { value: { code: 'ready' } } will not work.
Fix: Use status: { value: { value: 'ready' } } . Pass the status string in the value property of SearchTokenValue.
Error: TypeError: result.data is not a function You called getTasks() and then result.data() with parentheses.
Fix: getTasks() returns a BWellQueryResult where data is a property. Use result.data (no parens) and result.hasError() to branch.
Error: TypeError: result.success is not a function You called getTasks() and then result.success().
Fix: BWellQueryResult has no .success() or .failure() method. Branch on result.hasError() instead. .success() / .failure() exist on BWellTransactionResult, which is what createConsent() returns, not getTasks().)
Error: Cannot read properties of null (reading 'map') on entry When the user has no tasks matching the filter, result.data?.entry is null, not [].
Fix: Guard before mapping: const entries = Array.isArray(result.data?.entry) ? result.data.entry : [].
Error: ValidationError: Either SearchToken value or values or notEquals must be provided You passed a SearchToken object but left all three fields value, values, notEquals) undefined.
Fix: Always populate at least one of value, values, or notEquals inside a SearchToken.
Error: Error: Uninitialized You called sdk.activity.getTasks() before sdk.initialize() resolved successfully.
Fix: Confirm await sdk.initialize() returned a result whose .success() is true. The error is a plain Error with message "Uninitialized".
Error: TypeError: sdk.activity.getTasks is not a function Usually an incorrect import path or a stale build.
Fix: Confirm you're importing from @icanbwell/bwell-sdk-ts and the installed version exposes ActivityManager.getTasks. Rebuild after package updates.
Updated about 1 month ago
