Search & Establish Data Connections

Application APIs

This workflow demonstrates how to search for healthcare providers, practices, and insurance companies, then establish secure data connections to retrieve patient health records. You'll use the SearchHealthResources query to find available data sources by keyword (such as "Sandbox Health System" or "Dr. Smith"), then initiate an OAuth connection flow to grant access to the user's health data from that source.


Prerequisites

  • health.network - This workflow requires health.network to be enabled for access to b.well's Patient Access API connections.
  • End-User Authentication - User must be authenticated with the health.network scope
  • Account Creation and Consent - User account and consent must be completed

Environment URL:

  • Client-Sandbox: https://api.client-sandbox.icanbwell.com/v1/graphql


Workflow Steps

Step 1: Search for Healthcare Resources by Keyword

Use the SearchHealthResources GraphQL query to search for healthcare providers, practices, or insurance companies by keyword, location, or other criteria. The query returns connection endpoint details needed to establish data access.

Common search patterns:

  • By keyword: Search for "Sandbox Health", "West Coast Health Clinic", or "UnitedHealthcare"
  • By location: Filter results by geographic coordinates or zip code
  • By type: Limit results to practices, individual practitioners, or insurance companies

Example GraphQL Query:

query SearchHealthResources($searchInput: SearchHealthResourcesInput) {
  searchHealthResources(searchInput: $searchInput) {
    pagingInfo {
      pageNumber
      pageSize
      totalItems
      totalPages
    }
    results {
      type
      id
      content
      logoUrl
      location {
        name
        address {
          line
          city
          state
          postalCode
          country
        }
        position {
          latitude
          longitude
        }
        distanceInMiles
      }
      organization {
        name
        logoUrl
        endpoint {
          name
          status
        }
      }
      partOf {
        id
        content
        endpointName
        logoUrl
      }
      npi
      gender
      endpoint {
        name
        status
      }
    }
  }
}

Example Variables:

This example searches for "Sandbox Health" near Sacramento, CA, filtering for practices, practitioners, and insurance companies with available data connections.

{
  "searchInput": {
    "search": "sandbox health",
    "searchLocation": {
      "lat": 38.5712412,
      "lon": -121.4802025,
      "zipCode": 10011
    },
    "filters": {
      "includePopulatedProaOnly": true,
      "type": [
        "PRACTICE",
        "PRACTITIONER",
        "INSURANCE"
      ]
    },
    "orderBy": [
      {
        "field": "RELEVANCE",
        "order": "DESC"
      }
    ],
    "paging": {
      "pageNumber": 0,
      "pageSize": 15
    },
    "client": [
      {
        "dataSets": [
          "CONNECTHUB",
          "NPPES"
        ],
        "config": "client_config"
      }
    ]
  }
}

Key Parameters:

  • search: Keyword to search for (provider name, practice name, insurance company)
  • searchLocation: Geographic filtering by latitude/longitude or zip code (preference given to lat/lon if both provided)
  • filters.type: Resource types to include (PRACTICE, PRACTITIONER, INSURANCE)
  • filters.includePopulatedProaOnly: Only return results with active data connection endpoints
  • paging: Control result pagination
  • logoUrl: Optional. Add to your selection set to receive organization logo images. See Step 4: Display Organization Logos

Step 2: Check Endpoint Connections

Before initiating a connection, check the endpoint.status field to determine whether the connection is currently available. This field indicates the operational health of the data connection and helps your application provide appropriate messaging to users. It is updated nightly based on percent connect success by end point.

Endpoint Status Values

StatusMeaningRecommended Client Behavior
activeHealthy : Connection is working normallyProceed with connection flow
errorUnstable : Connection is unreliable; may or may not succeedCan show warning (e.g., "This connection is currently experiencing issues. You can try, but it may not work.") Can allow the user to attempt.
suspendedUnder maintenance : Connection is temporarily unavailableCan show a message (e.g., "This connection is under maintenance. Please try again later.") Block or hide the connection option.
testComing soon : Connection is planned but not yet liveCan show a message (e.g., "This connection is coming soon.") or can block/hide the connection option

Note: Endpoints with status off (deactivated) will not appear in search results at all.


Step 3: Extract Connection Endpoint Details

From the SearchHealthResources response, extract the endpoint.name value which serves as the connectionId for initiating the OAuth connection flow.

Scenario 1: Endpoint in Main Result

If the result includes an endpoint array at the top level, extract the endpoint.name directly.

Example Response:

{
  "type": "PRACTICE",
  "content": "Johns Hopkins Medicine",
  "location": [
    {
      "name": "Johns Hopkins Medicine",
      "address": {
        "line": [
          "1650 Orleans St"
        ],
        "city": "Baltimore",
        "state": "MD",
        "postalCode": "21287"
      }
    }
  ],
  "partOf": null,
  "endpoint": [
    {
      "name": "example_endpoint_name",
      "status": "active"
    }
  ]
}

In this example, extract "example_endpoint_name" from endpoint[].name to use as the connectionId.

The status: "active" confirms this connection is healthy and available.

Scenario 2: Endpoint in Organization Array

If the main result does not include an endpoint, check the organization array. Organizations may contain their own endpoint.name values.

{
  "data": {
    "searchHealthResources": {
      "results": [
        {
          "type": "PRACTITIONER",
          "content": "STEVEN ROEY",
          "location": [
            {
              "name": "701 E. EL CAMINO REAL",
              "address": {
                "line": [
                  "701 E. EL CAMINO REAL"
                ],
                "city": "MOUNTAIN VIEW",
                "state": "CA",
                "postalCode": "94040"
              }
            }
          ],
          "organization": [
            {
              "name": "Cerner Soarian Sandbox",
              "endpoint": [
                {
                  "name": "cerner_soarian_sandbox",
                  "status": "active"
                }
              ]
            },
            {
              "name": "BWell PROA Demo",
              "endpoint": [
                {
                  "name": "proa_demo",
                  "status": "error"
                }
              ]
            },
            {
              "name": "Epic on FHIR Sandbox",
              "endpoint": [
                {
                  "name": "epic_on_fhir_sandbox",
                  "status": "active"
                }
              ]
            }
          ],
          "npi": [
            "1982709093"
          ],
          "endpoint": []
        }
      ]
    }
  }
}

In this example:

  • "cerner_soarian_sandbox" (status: "active"); healthy, available for connection.
  • "proa_demo" (status: "error"); unstable, connection may not succeed; show warning to user.
  • "epic_on_fhir_sandbox" (status: "active"); healthy, available for connection.

Extract any endpoint with status: "active" from endpoint[].name within the organization[] array to use as the connectionId. For endpoints with status: "error", we can inform the user that the connection is currently unstable.

Scenario 3: Endpoint in partOf Array

If the result is of type PRACTICE and includes a populated partOf array, the endpoint may be referenced through the parent organization relationship. Results with partOf set to null represent parent organizations, while results with a populated partOf array are child entities (such as individual clinic locations) that inherit their data connection from the parent.

{
  "type": "PRACTICE",
  "content": "Johns Hopkins Hospital",
  "location": [
    {
      "name": "Johns Hopkins Hospital",
      "address": {
        "line": [
          "600 N Wolfe St"
        ],
        "city": "Baltimore",
        "state": "MD",
        "postalCode": "21287"
      }
    }
  ],
  "partOf": {
    "id": "8d56a14d-65ee-59f6-ba83-90c96ad681e4",
    "content": "Johns Hopkins Medicine",
    "endpointName": "example_endpoint_name"
  },
  "endpoint": [
    {
      "name": "example_endpoint_name",
      "status": "active"
    }
  ]
}

In this example, extract "example_endpoint_name" from either partOf[].endpointName or endpoint[].name to use as the connectionId. The status: "active" on the endpoint confirms the inherited parent connection is healthy.

Since all child organizations share the same endpoint as their parent organization, you can use the values within the partOf array to group related results together in your UI. This allows you to display a single parent organization (e.g. "Johns Hopkins Medicine") with nested child results underneath, improving the user experience by reducing duplicate endpoint entries and providing organizational context.

Note: If a parent endpoint has status: "error" or status: "suspended", all child organizations inheriting that endpoint are equally affected. The status on the endpoint reflects the health for all organizations using that connection.



Step 4 (Optional): Display Organization Logos

Now that you know which endpoint each result connects to, you can also show users a logo so they can confirm they are choosing the right health system before they begin the OAuth flow. If your UI does not display logos, skip this step. The connection flow works the same either way.

logoUrl is a nullable String containing a public URL to the logo image. It is additive and opt-in. You receive it only if you add it to your selection set. Existing queries that do not request it are unaffected.

Where logoUrl appears

searchHealthResources can return logoUrl at three levels, mirroring the endpoint scenarios in Step 3. Which one is populated depends on the result's type.

Field pathPopulated forNotes
results[].logoUrlAny result typeThe organization's own logo
results[].organization[].logoUrlPRACTITIONER onlyLogos of affiliated health systems. Always empty for PRACTICE, INSURANCE, LABORATORY, and PHARMACY
results[].partOf.logoUrlPRACTICE onlyThe parent organization's logo. Always null for practitioner results

Requesting all three is safe. Whichever does not apply to a given result simply returns empty or null.

The field name is always camelCase: logoUrl, not logo_url.

Example Query

query SearchHealthResourcesWithLogo($searchInput: SearchHealthResourcesInput) {
  searchHealthResources(searchInput: $searchInput) {
    results {
      type
      content
      logoUrl
      organization {
        name
        logoUrl
      }
      partOf {
        id
        content
        endpointName
        logoUrl
      }
    }
  }
}

Example Response

A PRACTITIONER result with a populated organization and no partOf, followed by two PRACTICE results where organization is always empty but partOf may be populated:

{
  "data": {
    "searchHealthResources": {
      "results": [
        {
          "type": "PRACTITIONER",
          "content": "Dr. Jane Smith, MD",
          "logoUrl": null,
          "organization": [
            {
              "name": "Example Healthcare",
              "logoUrl": "https://cdn.example.com/logos/example_healthcare.png"
            }
          ],
          "partOf": null
        },
        {
          "type": "PRACTICE",
          "content": "EXAMPLE HEALTHCARE",
          "logoUrl": "https://cdn.example.com/logos/example_healthcare_clinic.png",
          "organization": [],
          "partOf": {
            "id": "c86f9970-bdcd-5a3d-a8b7-88dc282f5fd3",
            "content": "Example Healthcare Inc",
            "endpointName": "example_healthcare",
            "logoUrl": "https://cdn.example.com/logos/example_healthcare.png"
          }
        },
        {
          "type": "PRACTICE",
          "content": "Example Healthcare Inc",
          "logoUrl": null,
          "organization": [],
          "partOf": null
        }
      ]
    }
  }
}

The second result shows the case worth handling explicitly: a practice whose own logoUrl is populated and whose parent carries a different logo. The third shows a practice with neither.

Choosing Which Logo to Display

Prefer the most specific logo available, then fall back:

  1. results[].logoUrl is the result's own logo.
  2. For PRACTICE results, results[].partOf.logoUrl is the parent organization's logo.
  3. For PRACTITIONER results, results[].organization[0].logoUrl is an affiliated organization's logo.
  4. Your own local placeholder.

Because child organizations inherit their endpoint from a parent (see Step 3, Scenario 3), the parent's logo is usually the right visual anchor when you group child results under a parent in your UI.

📘

The null contract

When an organization has no logo on file, logoUrl is returned as null.

Treat the field as optional in your data model, check for null before use, and ship your own placeholder image like a generic building icon or an initial-based avatar to render in its place.

Fetching the Image

  • No authentication. The URL is public. Fetch it with a standard image request and do not attach your API credentials, bearer token, or any custom headers.

With an endpoint name (and, if you chose to, a logo) for each result, your user can pick a connection. Next, use the selected endpoint.name to request the OAuth authorization URL.



Step 5: Retrieve OAuth Authorization URL

Before calling getOauthUrl, verify that the endpoint's status is "active" (or "error" if you choose to allow unstable connection attempts with a user warning). Do not initiate OAuth for endpoints with status: "suspended" or "test".

Using the endpoint.name extracted in Step 3 as the connectionId, query getOauthUrl to retrieve the OAuth authorization URL for the selected healthcare provider.

query getOauthUrl($connectionId: String!) {
  getOauthUrl(connectionId: $connectionId) {
    redirectUrl
  }
}

Example Variables:

{
  "connectionId": "proa_demo"
}

Example Response:

{
  "data": {
    "getOauthUrl": {
      "redirectUrl": "https://auth.provider.com/oauth/authorize?client_id=..."
    }
  }
}


Step 6: Launch Authentication Flow

Direct the user to the redirectUrl returned by getOauthUrl. This URL initiates the OAuth authentication flow where the user securely logs into their healthcare provider's portal and authorizes b.well to access their health records.

Once the user completes the OAuth flow, they will be redirected back to your application. See the OAuth Connection Flow Guide for detailed implementation options for handling OAuth completion, including postMessage listeners, URL polling, and custom redirect URLs.


Endpoint Status Reference


endpoint.statusConnection HealthUser Can Attempt?Recommended UX
activeHealthy✅ YesCan show normally, proceed to OAuth
errorUnstable⚠️ Yes, with warningCan show with warning badge/message
suspendedUnder maintenance❌ NoCan show as unavailable or hide
testComing soon❌ NoCan show as "coming soon" or hide
offDeactivated-Will not appear in results

Example: Handling Mixed Status in UI

When search results contain endpoints with different statuses, your application should handle them appropriately:

{
  "type": "PRACTITIONER",
  "content": "DR. JANE SMITH",
  "organization": [
    {
      "name": "Regional Medical Center",
      "endpoint": [
        {
          "name": "regional_medical_center",
          "status": "active"
        }
      ]
    },
    {
      "name": "Community Health Partners",
      "endpoint": [
        {
          "name": "community_health_partners",
          "status": "error"
        }
      ]
    },
    {
      "name": "New City Hospital",
      "endpoint": [
        {
          "name": "new_city_hospital",
          "status": "test"
        }
      ]
    }
  ],
  "endpoint": []
}

Recommended rendering:

  • Regional Medical Center, Can show as available/healthy connection
  • Community Health Partners, Can show with warning: "This connection is currently experiencing issues"
  • New City Hospital, Can show as "Coming Soon".

Did this page help you?