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?


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:

statusbusinessStatus.displayMeaning
readyPENDINGConsent accepted; pipeline not yet started
in-progressRETRIEVINGPipeline is actively fetching records
completedRETRIEVEDRecords fetched and stored successfully
failedERRORRetrieval failed; check task.output for details
rejectedREJECTEDUser 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

MethodReturnsHow to read it
sdk.activity.getTasks(...)BWellQueryResult<TaskResponse, BaseManagerError>result.data (property), result.error (property), result.hasError() (method). No .success().

Task types

codeDescription
care-needClinical recommendations: things the user should do for their health (e.g., schedule a screening).
health-activityActivities the user can take to improve health: nutrition, fitness, sleep, emotional health, promotions.
network-data-retrievalSmart Connect query status task. Tracks the lifecycle of a network data retrieval job.
data-connectionTasks related to data source connections (e.g., linking an insurance account).
notificationIn-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.

StatusMeaning
readyTask created and waiting to be picked up.
in-progressTask is actively being worked on.
completedTask finished successfully.
failedTask encountered an error. Check task.output for details.
rejectedTask was rejected (e.g., user revoked consent).
cancelledTask was cancelled before completion.

GetTasksRequest fields

FieldTypeNotes
codeSearchTokenFilter by task type. Use system: 'https://www.icanbwell.com/activityType' and code set to a task type code.
statusSearchTokenFilter by lifecycle status. Use the value subfield; it gets lowercased and underscore-to-dash normalized.
idSearchStringFetch a specific task by its FHIR resource ID.
identifierSearchTokenFilter by a business identifier.
tagSearchTokenFilter by resource tag.
performerSearchTokenOverride 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.
subjectSearchReferenceFilter by the patient/subject reference. Usually not required, as the SDK scopes to the authenticated user by default.
pagenumberZero-based page index. Required. Pass 0 for the first page.
pageSizenumberNumber 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:

FieldTypeNotes
idstring
statusstring | nullLowercase. One of: ready, in-progress, completed, failed, rejected, cancelled.
descriptionstring | nullHuman-readable label for the task.
codeCodeableConcept | nullTask type. Read via task.code?.coding?.[0]?.code.
businessStatusCodeableConcept | nullUser-facing status label (e.g., PENDING, RETRIEVING, RETRIEVED, ERROR). Read via task.businessStatus?.coding?.[0]?.display.
prioritystring | null'routine' or 'urgent'.
executionPeriodPeriod | null{ start: stringnull, end: stringnull } When the task started/ended.
lastModifiedstring | nullISO 8601 timestamp of the last status update.
forReference | nullThe patient/user this task belongs to.
basedOn(Reference | null)[] | nullThe consent(s) that created this task.
focusReference | nullThe resource this task is acting on (e.g., CommonWell patient reference for TEFCA IAS tasks).
output(TaskOutput | null)[] | nullError details when status === 'failed'. Each entry has type, valueString, and valueCodeableConcept.
identifier(Identifier | null)[] | null
metaMeta | 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.

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.


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().)


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 : [].


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.


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.


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.


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: 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".


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.



Did this page help you?