FlexpaFlexpa
Developer PortalGet a DemoTry it yourself

Guides

  • Home
  • Quickstart
  • Agent guide
  • Claims data guide
  • Financial data guide
  • Parsing FHIR data

Network

  • Network guide
  • Endpoint directory
  • CHPL directoryNew
  • Directory MCP server

Consent

  • OAuth
  • Patient linking
  • Usage patterns
  • Patient access

Records

  • FHIR API
  • Webhooks
  • DestinationsNew
  • Data Sheet
  • Node SDK
    • Installation
    • Initialize
    • OAuth PKCE Utilities
    • Link API
    • FHIR API
    • Error Handling
    • Utilities
  • SMART Health Links API
  • Terminology
  • Claims to clinicalNew

Misc

  • ChangelogNew
  • Support
  • Flexpa OS
  • We're hiring

Node SDK

The Node SDK is a TypeScript library for interacting with the Flexpa API. It handles OAuth 2.0 authentication, token management, and FHIR resource operations.

#Installation

Requires Node.js 19+ (uses the global Web Crypto API).

Install

npm install @flexpa/node-sdk

Import FlexpaClient

import FlexpaClient from '@flexpa/node-sdk';

#Initialize

Choose an initialization method based on your use case:

  • fromBearerToken — You already have an access token
  • fromAuthorizationCode — Public clients (mobile apps, SPAs) using OAuth PKCE
  • fromClientCredentials — Server-to-server without patient context

#fromBearerToken

Initialize from an existing access token.

Parameters

bearerTokenstringRequired

Access token

From Bearer Token

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');

#fromAuthorizationCode

Exchange an OAuth 2.0 authorization code from the PKCE flow.

Parameters

codestringRequired

Authorization code received from the OAuth redirect

codeVerifierstringRequired

The original code verifier used to generate the code challenge (43-128 characters)

redirectUristringRequired

Must match the redirect URI used in the authorization request

publishableKeystringRequired

Publishable Key. See API Keys.

From Authorization Code

// In your callback handler, after user authorizes
const flexpaClient = await FlexpaClient.fromAuthorizationCode(
  code,               // From URL query params
  codeVerifier,       // Retrieved from secure storage
  'https://your-app.com/callback',
  'pk_live_...'
);

// Store the token for future API calls
const accessToken = flexpaClient.getAccessToken();

#fromClientCredentials

Obtain an application access token for server-to-server calls without patient context. Tokens are valid for 30 minutes.

Note: Requires live mode API keys. Test mode keys return a 403 error.

Parameters

publishableKeystringRequired

Publishable Key. See API Keys.

secretKeystringRequired

Secret Key. See API Keys.

From Client Credentials

const flexpaClient = await FlexpaClient.fromClientCredentials(
  'pk_live_...',
  'sk_live_...'
);

#OAuth PKCE Utilities

The SDK provides helper functions to implement the OAuth 2.0 PKCE flow (RFC 7636).

#generateCodeVerifier

Generate a cryptographically random code verifier for PKCE. This is an async function that resolves to a 43-character URL-safe random string, so it must be awaited.

Store the code verifier securely on the client. You'll need it to exchange the authorization code for tokens.

Generate Code Verifier

const codeVerifier = await FlexpaClient.generateCodeVerifier();
// Example: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

#generateCodeChallenge

Generate a code challenge from a code verifier using the S256 method. This is an async function and returns a Promise<string>, so it must be awaited.

Parameters

codeVerifierstringRequired

The code verifier to hash

Generate Code Challenge

const codeVerifier = await FlexpaClient.generateCodeVerifier();
const codeChallenge = await FlexpaClient.generateCodeChallenge(codeVerifier);
// Example: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

#buildAuthorizationUrl

Build the authorization URL for initiating the OAuth 2.0 PKCE flow. Open this URL in a browser to start patient authorization.

Parameters

publishableKeystringRequired

Your publishable key (client_id)

redirectUristringRequired

Must match a registered redirect URI for your application

codeChallengestringRequired

The S256 code challenge generated from your code verifier

externalIdstringRequired

Your application's unique identifier for this user. Enables tracking authorizations and correlating patient data across sessions.

scopestring[]

OAuth scopes (default: ['launch/patient']). Include 'offline_access' to enable token refresh for MULTIPLE usage authorizations.

statestring

Optional state parameter for CSRF protection

endpointIdstring

Optional endpoint ID to pre-select a specific health plan

resumeboolean

Set to true to resume an in-progress consent workflow. Emits flexpa_resume=true.

flowAuthorizationFlow

Opt into a non-default flow. Discriminated union — either { type: 'ial2' } for TEFCA / IAL2 identity-verified flow, or { type: 'search', hints?: { firstName?, lastName?, dob? } } for the search-mode patient match flow. Omit for the standard payer/provider flow.

Build Authorization URL

// 1. Generate PKCE credentials (both helpers are async)
const codeVerifier = await FlexpaClient.generateCodeVerifier();
const codeChallenge = await FlexpaClient.generateCodeChallenge(codeVerifier);

// 2. Build the authorization URL
const authUrl = FlexpaClient.buildAuthorizationUrl({
  publishableKey: 'pk_live_...',
  redirectUri: 'https://your-app.com/callback',
  codeChallenge,
  externalId: 'user-123',
});

// 3. Store codeVerifier securely, then redirect user to authUrl

TEFCA / IAL2 flow

const authUrl = FlexpaClient.buildAuthorizationUrl({
  publishableKey: 'pk_live_...',
  redirectUri: 'https://your-app.com/callback',
  codeChallenge,
  externalId: 'user-123',
  flow: { type: 'ial2' },
});

#Link API

#introspect

Retrieve token metadata including sync status, patient ID, and available resources. See the Introspect API reference for the full response schema.

Introspect

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const tokenDetails = await flexpaClient.introspect();

#tokenRefresh

Refresh the access token to extend access to patient data. Only available for MULTIPLE usage authorizations.

Returns a new access token. You should update your stored token with the returned value.

Parameters

publishableKeystringRequired

Publishable Key

secretKeystringRequired

Secret Key

Token Refresh

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const { access_token } = await flexpaClient.tokenRefresh(
  'pk_live_...',
  'sk_live_...'
);
// Store the new access_token for future requests

#revoke

Revoke the access token

Parameters

secretKeystringRequired

Secret Key

Revoke

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
await flexpaClient.revoke('sk_live_...');

#FHIR API

FHIR methods include built-in retry logic to handle 429 rate limiting during the initial sync period.

#getCapabilityStatement

Retrieve the FHIR capability statement

Get Capability Statement

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const capabilityStatement = await flexpaClient.getCapabilityStatement();

#read

Read a FHIR resource

Parameters

resourceTypestringRequired

Supported FHIR Resource

idstringRequired

Resource ID

options{ numRetries?: number; delayMs?: number }

Retry options object passed as the third argument. numRetries is the number of retries (default: 10); delayMs is the delay in milliseconds between retries (default: 1000).

Read

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const patient = await flexpaClient.read('Patient', 'patient-id', { numRetries: 5, delayMs: 2000 });

#search

Search a FHIR resource

Parameters

resourceTypestringRequired

Supported FHIR Resource

searchParamsRecord<string, string>Required

FHIR search parameters as key-value pairs

options{ numRetries?: number; delayMs?: number }

Optional retry options. numRetries — number of retries (default: 10); delayMs — delay in milliseconds between retries (default: 1000)

Search

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const patients = await flexpaClient.search('Patient',
  { given: 'John' },
  { numRetries: 10, delayMs: 1000 }
);
const observations = await flexpaClient.search('Observation',
  { patient: 'patient-id' }
);

#Patient $everything

Retrieve all the resources for the patient

$everything

const flexpaClient = FlexpaClient.fromBearerToken('your-access-token');
const patientData = await flexpaClient.$everything();

#Error Handling

The Node SDK throws HttpError instances for API failures. These errors include the full HTTP response for detailed inspection.

Common Error Codes:

  • 429 - Data still processing (see sync jobs)
  • 422 - Processing error during sync
  • 401 - Invalid credentials
  • 404 - Resource not found

Error Handling

import { HttpError } from '@flexpa/node-sdk';

try {
  const patient = await flexpaClient.read('Patient', 'invalid-id');
} catch (error) {
  if (error instanceof HttpError) {
    console.log('Status:', error.response.status);

    // Parse error details
    const errorData = await error.json();
    console.log('Error details:', errorData);
  }
}

#Utilities

#getAccessToken

Retrieve the access token from the client for storage or use with other HTTP clients.

Get Access Token

const flexpaClient = await FlexpaClient.fromAuthorizationCode(...);

// Store for later use with fromBearerToken
const accessToken = flexpaClient.getAccessToken();
Status TwitterGitHub

© 2026 Flexpa. All rights reserved.

FHIR® is the registered trademark of Health Level Seven International and its use does not constitute endorsement by HL7.