Flexpa
Developer PortalFeedbackContact usOnboard

All docs

Consent

  • How it works
  • What you need

Using Flexpa Link

  • Create
  • Open
  • Exchange public token
  • Sync

Detailed Auth flow

    Mobile applications

    • iOS

    Workflow Ideas

    • Onboarding
    • Integration
    • Additional techniques

    Best practices

    • Explain the benefit
    • Set expectations
    • Present as default
    • Security
    • Polish your flow
    • Allow for multiple links

    Technical Configurations

    • Django COOP Configuration

    Next steps

      Link SDK

      #Consent

      Link SDK is a secure, embeddable, user-facing consent application for Records retrieval.

      Link SDK can be used in web and mobile apps.

      Let us know if we can help support your records retrieval consent.

      #How it works

      1. Embed the secure, <iframe> or WebView based Link SDK consent flow in your web or mobile app
      2. Users consent to retrieve and exchange their health insurance claims, plan details, and medical records from any of our (covered network)
      3. Users finalize the consent process by providing a digital authorization

      #What you need

      There are a few things that you will need as part of your app to use Flexpa Link effectively:

      • A pair of API Keys. Register in the Flexpa Portal today or contact us about enterprise plans.
      • A frontend app to add the Flexpa Link component
      • A backend web server to complete the Exchange step. (The exchange step requires passing your secret key. This key should be kept secret. Thats why it can't be stored on the frontend)
      Flexpa Link

      #Getting started?

      Quickstart

      Get started with a cloneable quickstart project

      Try it out →
      Questions? Contact support→

      #Looking for a demo?

      MyFlexpa

      Go through a Patient Access API flow yourself! See exactly what patients will see

      Try out MyFlexpa →

      #Using Flexpa Link

      You can add Flexpa Link to your application within a couple of minutes.

      Inside an HTML document add the <script> tag to create a global FlexpaLink object in your application.

      When using a Cross-Origin-Opener-Policy you must use same-origin-allow-popups or unsafe-none. This is especially important when running a Django server - see Django COOP Configuration for implementation details.

      Once the script is added to your user-facing application there are 4 main steps when using Flexpa Link:

      1. Create - Calling FlexpaLink.create({...}) will start a new authorization flow.
      2. Open - Calling FlexpaLink.open({...}) will open the Flexpa Link component to allow the user to select an ednpoint and sign in.
      3. Exchange - Exchanging your tokens is how you access the Flexpa API
      4. Sync - Use our FHIR API to pull user data into your app.

      Let's detail each of these steps below.

      Add script tag

      <head>
        ...
        <script src="https://js.flexpa.com/v1/"></script>
      </head>
      

      #Create

      First, initialize FlexpaLink by calling create(). This starts a new authorization flow so you will want to pass in some options to the create() method call. We recommend passing in publishableKey, user, usage and onSuccess at a minimum.

      Parameters

      publishableKeystringRequired

      The unique key to identify your app provided to you during registration at portal.flexpa.com.

      userobjectRequired

      An object specifying information about the end user who will be linking their account. Providing this object yields the following outcomes:

      • 1. The user is associated with multiple Patient Access Tokens, allowing for improved insights into user behavior.
      • 2. Flexpa enforces logical isolation of the user's data between family members if the payer does not implement appropriate Access Control Limits.
      externalIdstringRequired

      A unique identifier of the user that is owned by the host application.

      usagestringRequired

      The usage parameter controls how long the patient's data is accessible through Flexpa Link. For more information see our usage guide.

      ONE_TIMEstring

      When passing ONE_TIME, Flexpa expunges user data and revokes access after 24 hours. After this time has passed, the user will need to walk through the auth flow again and re-authorize.

      This usage pattern is suitable for applications that do not need to maintain long-term access to patient data.

      MULTIPLEstring

      Using MULTIPLE indicates that your app would like access to refreshed patient data over time. This is ideal for applications that require ongoing access to a patient's data.

      The authorization will be kept valid for as long as the payer allows. When selected, you will receive a refresh_token at the exchange step that can be used to get a new access_token.

      If you pass MULTIPLE but the endpoint doesn't provide long-term access to patient data then we will change it to ONE_TIME for you and you will not incur additional billing.

      onSuccess(publicToken: string) => voidRequired

      A callback for when a patient completes the authentication flow in full.

      A publicToken is provided for use in the Exchange step to obtain an access_token.

      onSyncing(publicToken: string) => void

      A callback for when a patient has completed the authentication flow, but data synchronization has not completed. If you use this callback, you must be prepared to handle 429 response status codes. A publicToken is provided for use in the Exchange step to complete the authentication flow.

      onLoad() => void

      A callback for when Flexpa Link has finished loading after calling open.

      onExit(error?: { code: string }) => void

      A callback for when a patient exits without completing the authentication flow either due to an error or abandonment. If there was an error, the first argument will be an object with a code property. The code property can be one of the following values:

      AUTHORIZATION_CODE_EXCHANGEstring

      The payer's endpoint returned an error after authorization when exchanging an authorization code for an access token.

      INVALID_ENDPOINTstring

      The optional endpoint ID parameter provided to FlexpaLink is invalid.

      INVALID_ENDPOINT_MODEstring

      The optional endpoint ID parameter provided to FlexpaLink does not match the mode of the publishableKey (test or live).

      INVALID_PUBLISHABLE_KEYstring

      The unique key provided to FlexpaLink to identify your app is invalid.

      INVALID_REQUESTstring

      The callback from payer's endpoint was not properly formatted.

      INVALID_STATEstring

      The payer's endpoint returned an invalid state parameter.

      INVALID_USERstring

      The required FlexpaLink user object is either invalid or was not provided.

      INVALID_USAGEstring

      The required FlexpaLink usage parameter is either invalid or was not provided.

      SYNC_FAILEDstring

      Flexpa was unable to synchronize the patient's data successfully after authorization.

      QUERY_REJECTEDstring

      The payer's endpoint did not grant access to the patient. This may occur if the patient clicks "do not consent" on some payer consent screens but can also occur for other reasons.

      QUERY_TIMEOUTstring

      The payer's endpoint timed out before it could fulfill the request.

      QUERY_INELIGIBLEstring

      The payer has not made the selected plan accessible via their API. This may occur if the payer does not support API access for certain plan types.

      QUERY_UNKNOWNstring

      The payer's endpoint did not understand the request.

      QUERY_SERVER_ERRORstring

      The payer's endpoint experienced an internal server error.

      QUERY_INVALID_CONFIGstring

      The payer's endpoint configuration needs to be updated by a Flexpa admin.

      QUERY_INVALID_SCOPEstring

      The payer's scope configuration needs to be updated by a Flexpa admin.

      If code contains a value which is not listed above, please submit a bug report to support@flexpa.com.

      endpointstring

      An optional UUID string for an Endpoint. Providing this value skips the search-and-select health plan step in the authentication flow.

      autoExitboolean

      An optional boolean to control the exit behavior on successful authorizations. When false, the success screen will not automatically close and will require the patient to click continue. Defaults to true.

      skipSyncingboolean

      An optional boolean to control whether to show the patient the syncing screen. When true, the syncing screen will be skipped and the patient will be taken directly to the success screen. Defaults to false.

      skipExplainerboolean

      An optional boolean to control whether to show the explainer screen. When true, the explainer screen will be skipped and the patient will be taken to their payer authorization after the consent screen. Defaults to false.

      requestedResourcesarray

      An optional array specifying the supported FHIR resource types that should be synced for the patient. If not provided, all supported resource types will be synced.

      Providing a requestedResources array allows you to define specific resource types that are synced for the patient, which can reduce the amount of time you and your patients will wait for the sync to complete. Flexpa will resolve all references within the requested resources to ensure there are no missing dependencies. For example, if you request Coverage and a Coverage resource references an Organization then Flexpa will sync that Organization resource too.

      Please note that this argument only controls which resources Flexpa will attempt to sync. This does not guarantee that they will be available in the patient's data.

      Create

      FlexpaLink.create({
        // Replace with your publishable key
        publishableKey: 'pk_test_...',
        // Replace with your application's user ID
        user: {
          externalId: 'usr_1234'
        },
        // Send `publicToken` to your backend to
        // exchange it for a patient `access_token`
        // https://www.flexpa.com/docs/sdk/login#exchange
        onSuccess: (publicToken) => {
          console.log('publicToken: ', publicToken);
        },
        // Indicates data usage
        usage: 'ONE_TIME',
      });
      

      #Open

      Once Flexpa Link has been configured we can move on to the part where users get involved. We want to trigger opening Flexpa Link with some user initiated event. You can use window.onload, button.onClick, video.on('ended') or any other event to trigger the FlexpaLink.open() call. By default, this will open the search and select window for a patient to select their health insurance plan.

      For example, opening on a button click.

      Parameters

      endpointstring

      An optional UUID string for an Endpoint. Providing this value skips the search-and-select health plan step in the authentication flow. This value also overrides the same-named value provided to the Create step.

      Open

      <button onclick="FlexpaLink.open()">
        Connect your health data
      </button>
      

      #Exchange public token

      When a user successfully links a health data source, FlexpaLink calls the onSuccess callback defined in the Create step. This callback receives a public_token. For security reasons, this public_token cannot be used to access the Flexpa API directly. Instead, it must be exchanged for an access_token. We call this the exchange.

      For additional security, a public_token is only valid for 30 minutes and can only be used once.

      Your application can send the public_token and the secret_key in exchange for an access_token and a refresh_token. The access_token can be used to make subsequent requests to Flexpa API

      You will only receive a refresh_token if you indicated you wanted MULTIPLE usage and the endpoint selected by the patient was refreshable.

      You will also receive an expires_in value (e.g. 86400). This represents the time in seconds for which the access_token is valid, after which your application will be required to make an API request to https://api.flexpa.com/link/token.

      For MULTIPLE usage, you will additionally receive a refresh_token. This token can be used to obtain new access_token values using the token refresh route without requiring the user to re-authorize.

      If available, you will additionally receive a refresh_expires_in value (e.g. 7776000). This represents the time in seconds for which the access_token is refreshable, after which the user will be required to re-authorize your application to the payer. The availability of refresh_expires_in is subject to the payer's support of the feature.

      During the process of exchanging a public token for an access token, Flexpa Link stores the patient ID received in the response from the server in a wildcard, $PATIENT_ID. You should use the wildcard in subsequent API requests.

      See the API reference documentation for full details →

      Exchange

      POST
      https://api.flexpa.com/link/exchange
      curl -X POST https://api.flexpa.com/link/exchange \
        -H 'Content-Type: application/json' \
        -d '{
          "public_token": "public_token_...",
          "secret_key": "sk_test..."
        }'
      

      #Sync

      Once the patient successfully authorizes their health plan via FlexpaLink, Flexpa immediately retrieves the patient's data from the payer's FHIR server. The initial sync period typically lasts less than 1 minute. After Flexpa syncs the data to their servers, you may then use your access_token to begin making calls to our FHIR API to retrieve any available patient data.

      Request

      GET
      /fhir/Patient/$PATIENT_ID/$everything
      ACCESS_TOKEN=flexpa-link-access-token
      
      curl 'https://api.flexpa.com/fhir/Patient/$PATIENT_ID/$everything' \
        -H "Authorization: Bearer $ACCESS_TOKEN"
      

      #Detailed Auth flow

      One of the core flows Flexpa enables is authenticating users and then having them authorize Flexpa to access their insurance and clinical data. There is a secondary authentication flow where your app must authenticate with

      Flexpa API and be authorized to pull the data synced from a the user's payer.

      The diagram below shows how you can use Flexpa Link to enable both of those core workflows.

      Flexpa Developer Portal

      The flow starts when a patient wants to connect their health plan data to your app. Your frontend loads Flexpa Link via a <script> tag as described in the install step.

      Your app calls FlexpaLink.create() with your publishableKey. Then your app calls FlexpaLink.open() to start the authorization flow.

      After a patient completes the authorization flow, Flexpa synchronizes the patient's health plan data to our FHIR server.

      After the data synchronization has completed, Flexpa Link will call the onSuccess callback passing in a public_token.

      On your server, you will exchange the public_token andsecret_key for an access_token.

      Use the access_token to make requests to Flexpa API to access the patient's health plan data.

      #Mobile applications

      Flexpa Link is normally installed in a browser application. It is possible to install Flexpa Link in a mobile application. For mobile applications, we recommend installing Flexpa Link inside of native application views which support tabs.

      #iOS

      SFSafariViewController is a way to launch mobile Safari inside of your application (similarly to, but different from, a web view). Using SFSafariViewController is the recommended approach to implementing Flexpa Link in iOS. This is because using SFSafariViewController has the following notable benefits:

      • Works out of the box, with a relatively small development effort required.
      • Behaves like a fully featured Safari browser, including a built-in navigation bar, toolbar, reader mode, and the ability to use Safari's cookies and settings.
      • Supports AutoFill, which may help users log in to their payer, improving login success rates.
      • Includes accessibility features, such as resizable fonts.
      • Provides security features. For example, the current page's domain is always visible to the user.

      However, please note that using SFSafariViewController has the following drawbacks:

      • Users are required to tap 'Done' at the end of the Flexpa Link authentication flow to close the in-app browser.
      • Generally speaking SFSafariViewController is not very customizable. For example, your application cannot inject JavaScript, handle navigation events, or modify the DOM.

      The following example code was generated for iOS 16.4.

      FlexpaLink in iOS

      import SwiftUI
      import SafariServices
      
      // 1. SafariView wrapper for SFSafariViewController
      struct SafariView: UIViewControllerRepresentable {
        let url: URL
      
        func makeUIViewController(
          context: Context
        ) -> SFSafariViewController {
          return SFSafariViewController(url: url)
        }
      
        func updateUIViewController(
          _ uiViewController: SFSafariViewController,
          context: Context
        ) {
            // Can be left empty for this use case
        }
      }
      
      // 2. Example View
      struct SafariViewOption: View {
        @State private var showSafari: Bool = false
        // Here, replace this URL with the web page that you are
        // loading Flexpa Link on. We've used the my.flexpa.com
        // demo app here to show it working end to end.
        let url: URL? = URL(string: "https://my.flexpa.com")
      
        var body: some View {
          VStack {
            Text("Open Flexpa Link").onTapGesture {
              showSafari.toggle()
            }
          }
          .padding()
          .sheet(isPresented: $showSafari, content: {
            if let validURL = url {
              SafariView(url: validURL)
            }
          })
        }
      }
      
      struct SafariViewOption_Previews: PreviewProvider {
        static var previews: some View {
          SafariViewOption()
        }
      }
      

      #Workflow Ideas

      Here are different techniques for embedding Flexpa Link into your application or service to ensure participation of new users and activate existing users:

      #Onboarding

      Incorporate Flexpa Link directly into your new user onboarding experience. New users have higher engagement as completion of enrollment is a compelling event to complete the Flexpa Link flow.

      As these users sign up and learn to navigate your application, prompt them to link their payer account through Flexpa. This could be presented as an initial setup step, or as a highlighted feature in a tutorial. Make sure to explain the benefits and reassure the user about the security of the process.

      #Integration

      Embed Flexpa Link as an activity or option within your existing patient interface. This could be as a button, a banner, or a new tab in a user's profile settings. Explain the value of linking their payer account and gently prompt users to do so.

      #Personalization

      On the user's profile or dashboard, you can include a personalized status or progress bar indicating the completion of their profile setup, including whether they've linked their payer account. This visual cue can motivate users to complete their setup for existing users, including linking their payer account via Flexpa Link.

      #Customization

      Customize the user's experience based on whether they have linked their payer account or not. For those who have not linked their account, display a banner or a dedicated space on their dashboard, encouraging them to link their payer account. For those who have linked their accounts, this space could be replaced with more advanced features or personalized content.

      #In-app notifications

      In-app notifications can be a powerful tool for existing users. Use pop-up messages or notifications in your application to remind users to link their payer accounts via Flexpa Link. These can be triggered based on certain user behaviors. For example, you could notify when a user logs in, when they navigate to certain sections of the app, or when they have been inactive for a while.

      Make sure these reminders are not too intrusive and are designed in a way that clearly communicates the value of the action.

      #Additional techniques

      Regardless of whether a user is new or existing, sometimes they need a little extra direction to complete the Flexpa Link flow. Here are some additional techniques to encourage users to link their payer account:

      #Campaigns

      In-app notifications may not be suited for all applications' populations. Send targeted marketing campaigns to encourage users to link their payer accounts through Flexpa. This can be done via:

      • Email: Craft an informative email explaining the benefits of linking a payer account and how to do it. Include a direct link to your application or web page you've built to launch Flexpa Link.
      • SMS: Send a short, compelling message with a direct link to your application where users can easily link their payer accounts. Ensure the message is concise yet informative.

      #Incentivization

      Consider offering small incentives or rewards for users who link their payer account. This could be in the form of discounts, access to premium features, or other value-added benefits. Incentives can be a powerful motivator for users to take action.

      #Best practices

      Below are some principles we typically recommend to optimize user conversion via Flexpa Link and ensure your users complete the authentication flow. Some recommendations may be less applicable to your workflow.

      #Explain the benefit

      Your UI should tell the user why they want to use Flexpa and the value they get from linking their payer. For example, linking their payer account might save them time inputting medication data manually or it might enable your app to present more relevant, tailored Medicare plan recommendations.

      #Set expectations

      Before launching the Flexpa flow, explain to the user that they'll be prompted to link a payer account. Explain that they'll need to input their username and password, but also that they can create an account with their payer if they do not have one. Explain what data your app collects from their account, and why it's needed.

      #Present as default

      Rather than presenting Flexpa and manual flows as equal alternatives, encourage your customers to use Flexpa through the size, positioning, and color of the Flexpa Link entry point. You can also use labels such as "Recommended" or "Preferred".

      #Security

      Let customers know that Flexpa Link is secure and uses 256-bit encryption - a lock icon can also be used to help convey that Flexpa uses encryption. Explain how patients can control their data and remove connectivity through Connections.

      #Polish your flow

      A Flexpa hosting flow that is aesthetically engaging, polished, and reflects your brand conveys the legitimacy and importance of linking an account. Illustrations and interactive elements can all be a part of your pre-Flexpa messaging.

      #Allow for multiple links

      Patients sometimes have multiple payer accounts, such as a primary and secondary insurance for dual eligibles or a current and prior insurance for members who have changed carriers. To capture all of this information, allow patients to link multiple accounts to your app, and make it clear that they can do so.

      #Technical Configurations

      #Django COOP Configuration

      To set up a Cross-Origin Opener Policy (COOP) in Django, you need to add HTTP headers to your responses. This can be done by configuring your settings.py file:

      # In settings.py
      
      MIDDLEWARE = [
          # ... other middleware
          'django.middleware.security.SecurityMiddleware',
          # ... other middleware
      ]
      
      # For 'unsafe-none' option
      SECURE_CROSS_ORIGIN_OPENER_POLICY = 'unsafe-none'
      
      # OR for 'same-origin-allow-popups' option
      # SECURE_CROSS_ORIGIN_OPENER_POLICY = 'same-origin-allow-popups'
      

      Django's SecurityMiddleware will handle sending these headers with your responses. You only need to set it to one of the options (either unsafe-none or same-origin-allow-popups).

      If you're using Django 4.0 or later, the SECURE_CROSS_ORIGIN_OPENER_POLICY setting is built-in. For earlier versions, you might need to create a custom middleware:

      # custom_middleware.py
      class COOPMiddleware:
          def __init__(self, get_response):
              self.get_response = get_response
      
          def __call__(self, request):
              response = self.get_response(request)
              response['Cross-Origin-Opener-Policy'] = 'unsafe-none'  # or 'same-origin-allow-popups'
              return response
      
      # Then add to MIDDLEWARE in settings.py
      MIDDLEWARE = [
          # ... other middleware
          'path.to.custom_middleware.COOPMiddleware',
          # ... other middleware
      ]
      

      #Next steps

      Quickstart

      Get started with a cloneable quickstart project

      Try it out →

      Flexpa API

      Use Flexpa API as a unified API to access Explanation of Benefits and more

      Build with Flexpa API →
      Status TwitterGitHub

      © 2025 Flexpa. All rights reserved.