API reference
#Introduction
Flexpa's API uses REST. Our API functions as an opinionated request proxy layer for FHIR: every resource available in the API conforms to one available in FHIR.
To start using Flexpa API, your users must connect their health plan with Flexpa Link.
You can use the Flexpa API in test mode, which doesn't use real patient data. The API key you use to authenticate the request determines whether the request is made in live mode or test mode.
Base URL
https://api.flexpa.com
#Authentication
The Flexpa API uses API keys and Access Tokens to authenticate requests. You obtain an Access Token as the last step of the Flexpa Link auth flow.
Authentication to the per-patient FHIR Resources is performed via bearer auth.
Submit an Authorization
header with a value of Bearer ${PAT}
where ${PAT}
is a currently valid Access Token.
#Access Tokens
Patient Access Tokens are obtained by exchanging a Flexpa Link public_token
for an API access_token
. Flexpa Link returns a public_token
in the onSuccess
callback after a user has successfully connected their health plan.
Patient Access Tokens are string-encoded JSON Web Tokens (JWTs).
JSON Web Tokens can be decoded to inspect their contents. You can decode a JWT in two ways:
The Flexpa API does not support client side requests. Read more about making server side requests here.
#State
Patient access tokens have a state
associated with them that indicates where the token is in the authorization flow. The states are enumerated below.
In Progress
tokens have the following values:
CREATED
Flexpa Link has just been opened
AUTHORIZING
The patient has been redirected to the payer's authorization screen
Successful
tokens have the following values:
AUTHORIZED
The patient has successfully completed an authorization, but the Link exchange step has not yet been completed
EXCHANGED
The Link exchange step has been completed and the PAT is expected to be fully usable
REFRESHED
The PAT has been refreshed and is no longer usable
REVOKED
The patient has chosen to revoke access to the PAT and it is no longer usable
Unsuccessful
tokens have the following values:
BOUNCED
The patient has exited Link without interacting with the interface
ABANDONED
Authorization did not end in an error but was not completed
ERRORED
Authorization was not successful and resulted in an error
#Request ID
Each API request has an associated request identifier.
You can find this value in the response headers, under X-Request-Id
.
If you need help debugging a request, please include the Request Id when contacting support.
#Sync Job States
Sync jobs, essential for updating patient data in the cache, progress through various states reflecting their current status in the synchronization process.
These states are enumerated below, providing visibility into each phase of a sync job's lifecycle.
CREATED
The sync job has been created. This is its initial state
WAITING
The sync job is queued for processing
ACTIVE
The sync job is currently being processed
FAILED
The sync job was not successful and resulted in an error
COMPLETED
The sync job completed successfully and the patient's data is available through the FHIR API
#Link API
In order to link and manage patient authorizations in your application, you will first need to interact with the Flexpa Link API.
Link API routes begin with the /link/
subpath of the URL.
The Flexpa Link component must be configured as a prerequisite before using the Link API.
POSThttps://api.flexpa.com/link/exchange
It's important to only call this endpoint from your server, as to not expose your secret_key
Request fields
- public_tokenstringRequired
Received from the Flexpa Link onSuccess
callback
- secret_keystringRequired
Your Flexpa API secret key
Response fields
- access_tokenstring
The access_token
to be used to make FHIR Requests on behalf of this user.
- expires_innumber
expires_in
is the time (in seconds) for which the access_token
is valid.
Defaults to 86400 seconds (24 hours).
For ONE_TIME
usage patient authorizations, once this time has elapsed, data that was synced is deleted from Flexpa's data cache.
- usageenum
usage
is the resolution of intended data usage and the
capabilities of the selected endpoint. If the usage
indicated
in FlexpaLink.create()
was MULTIPLE
but the endpoint does not support refreshable authorization then we will return ONE_TIME
here as an indication.
- MULTIPLEstring
Returned when both the intended usage
was MULTIPLE
and the selected endpoint
is refreshable
- ONE_TIMEstring
Returned when the intended usage
is ONE_TIME
or the endpoint
is not refreshable
- refresh_tokenstring
Only provided for MULTIPLE
usage patient authorizations.
The refresh_token
to be used to obtain a new access_token
once the current one expires using the token refresh route.
- refresh_expires_innumber
refresh_expires_in
is the time (in seconds) for which the access_token
is refreshable.
Once this time has elapsed, the user is required to re-authorize.
A null
suggests that this value is either unknown or not applicable.
A 0
indicates an indefinite expiration.
For MULTIPLE
usage patient authorizations, the refresh_token
is valid for 7776000 seconds (90 days) by default.
Once this time has elapsed, data that was synced is deleted from Flexpa's data cache.
- patientstring
The Patient ID connected to the authorization (formatted as a FHIR Resource Path Patient/<patient_id>
).
- userobject
Information about the end user you can specify during the create step of Flexpa Link. Echoed back to you in this response.
- externalIdstring
A unique identifier of the user as that is owned by the host application.
- endpointobject
The endpoint
to be used to make FHIR Requests on behalf of this user.
- syncobject
An object containing information about the sync job of the patient authorization.
- resourceTypesobject
A summary of the resource types that Flexpa successfully synced for the patient authorization.
Synced data is available for querying via the FHIR API.
The keys are the resource types and the values are the number of resources synced of that type.
Flexpa's supported resource types will always appear in this object, even if no resources of that type were synced; the count will equal 0 in this case.
All other FHIR resource types will only appear in this object if resources of that type were synced.
- lastSyncedAtobject
The last time this patient's data was successfully synced in Unix time (in seconds).
This property specifically refers to the timestamp of the last COMPLETED
sync job.
- stateobject
The state of the current sync job associated with this patient authorization.
See the sync job states section for more information.
curl -X POST https://api.flexpa.com/link/exchange \
-H 'Content-Type: application/json' \
-d '{
"public_token": "public_token_950fae5f-...",
"secret_key": "<your-secret-key>"
}'
Response
{
"access_token": "eyJhbGciOiJFUzI1NiJ9.eyJqdGkiOiI5NmQ5Njgw...",
"expires_in": 86400,
"usage": "ONE_TIME",
"refresh_expires_in": 86400,
"patient": "Patient/33512af4-5ab2-4be2-90f5-3945cff01c1a",
"user": {
"externalId": "1234567890"
},
"endpoint": {
"id": "d39433b7-0fbd-4bc2-bdae-fb276799979f",
"label": ["Humana"],
"name": "humana-sandbox",
"refreshable": true,
}
}
GEThttps://api.flexpa.com/link/introspect
When using the introspect endpoint, we will return an additional endpoint
field containing information about the health plan used to create the access token.
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Response fields
- jtistring
A random nonce value that uniquely identifies the access token.
- iatnumber
When the access token was issued in Unix time (in seconds).
- expnumber
When the access token expires in Unix time (in seconds).
- activeboolean
A boolean that states whether the access token can be used.
- issnumber
The issuer of the access token. Always https://api.flexpa.com
.
- audnumber
The audience of the access token. Always https://api.flexpa.com
.
- substring
A unique identifier for the patient authorization backing this access token.
- patientstring
The Patient ID connected to the authorization (formatted as a FHIR Resource Path Patient/<patient_id>
).
- client_idstring
The ID of the application that created this patient authorization.
- userobject
Information about the end user you can specify during the create step of Flexpa Link. Echoed back to you in this response.
- externalIdstring
A unique identifier of the user as that is owned by the host application.
- stateenum
The state indicates where the token is in the authorization flow. See the state section for more information.
- usageenum
usage
is the resolution of intended data usage and the
capabilities of the selected endpoint. If the usage
indicated
in FlexpaLink.create()
was MULTIPLE
but the endpoint does not support refreshable authorization then we will return ONE_TIME
here as an indication.
- MULTIPLEstring
Returned when both the intended usage
was MULTIPLE
and the selected endpoint
is refreshable
- ONE_TIMEstring
Returned when the indented usage
is ONE_TIME
or the endpoint
is not refreshable
- endpointobject
The Endpoint to which the patient authorized access to, can be used to determine which health plan the patient connected.
- syncobject
An object containing information about the sync job of the patient authorization.
- resourceTypesobject
A summary of the resource types accessible via Flexpa for the patient authorization.
Synced data is available for querying via the FHIR API.
The keys are the resource types and the values are the number of resources synced of that type.
Flexpa's supported resource types will always appear in this object, even if no resources of that type were synced; the count will equal 0 in this case.
All other FHIR resource types will only appear in this object if resources of that type were synced.
- lastSyncedAtobject
The last time this patient's data was successfully synced in Unix time (in seconds).
This property specifically refers to the timestamp of the last COMPLETED
sync job.
- stateobject
The state of the current sync job associated with this patient authorization.
See the sync job states section for more information.
ACCESS_TOKEN=flexpa-link-access-token
curl https://api.flexpa.com/link/introspect \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"jti": "4e99f5ae-eb40-4161-9506-23b119e7136f",
"iat": 1671116375,
"exp": 1671202775,
"active": true,
"iss": "https://api.flexpa.com",
"aud": "https://api.flexpa.com",
"sub": "329034ef-5fa8-4a08-99d5-c389e22a2533",
"patient": "Patient/33512af4-5ab2-4be2-90f5-3945cff01c1a",
"client_id": "46db2b53-1291-4e44-9d75-e4a26ceb1fa7",
"user": {
"externalId": "1234567890"
},
"state": "EXCHANGED",
"usage": "MULTIPLE",
"endpoint": {
"id": "d39433b7-0fbd-4bc2-bdae-fb276799979f",
"label": ["Humana"],
"name": "humana-sandbox",
"refreshable": true,
},
"sync": {
"resourceTypes": {
"AllergyIntolerance": 3,
"CarePlan": 21,
"CareTeam": 10,
"Condition": 9,
"Coverage": 18,
"Device": 0,
"DiagnosticReport": 0,
"DocumentReference": 1,
"Encounter": 0,
"ExplanationOfBenefit": 11,
"Goal": 16,
"Immunization": 0,
"MedicationDispense": 0,
"MedicationRequest": 3,
"Observation": 7,
"Patient": 1,
"Procedure": 62,
"Provenance": 0,
"Location": 0,
"Medication": 0,
"Organization": 0,
"Practitioner": 3,
"PractitionerRole": 0
},
"state": "COMPLETED",
"lastSyncedAt": 1712163905
},
}
POSThttps://api.flexpa.com/link/token
Flexpa attempts to obtain a long-lived authorization for every MULTIPLE
usage patient authorization.
When a long-lived authorization is obtained, expired access tokens can be refreshed for a new, valid one using the refresh token provided in the exchange step.
Request headers
- AuthorizationstringRequired
To authenticate, include an Authorization: Basic
header with your Flexpa API keys obtained from Flexpa Portal.
Concatenate your publishable key and secret key with a colon (:
), then encode this string in base64 format.
The header format should look like this:
Authorization: Basic base64_encoded_credentials
.
Request body
- grant_typestringRequired
The type of grant used to obtain the access_token
.
Always refresh_token
.
- refresh_tokenstringRequired
The refresh_token
obtained from the exchange endpoint.
Once you have used this token to refresh the access_token
, it is no longer valid.
A new refresh_token
will be issued upon successful token refresh.
Response fields
- access_tokenstring
The access_token
to be used to make Flexpa API requests on behalf of this user
- expires_innumber
expires_in
is the time (in seconds) for which the access_token
is valid.
Once this time has elapsed, data that was synced is deleted from Flexpa's data cache.
Additionally, your application will be required to refresh the access_token
once more to trigger a new sync.
Defaults to 86400 seconds (24 hours).
- refresh_tokenstring
The new refresh_token
to be used to refresh the access_token
.
- refresh_expires_innumber
refresh_expires_in
is the time period for which the refresh_token
is valid.
You must call this route to refresh the access_token
before this time period elapses otherwise, the user will need to re-authorize.
Defaults to 7776000 seconds (90 days).
- syncobject
An object containing information about the sync job of the patient authorization.
- resourceTypesobject
A summary of the resource types that Flexpa successfully synced for the patient authorization.
Synced data is available for querying via the FHIR API.
The keys are the resource types and the values are the number of resources synced of that type.
Flexpa's supported resource types will always appear in this object, even if no resources of that type were synced; the count will equal 0 in this case.
All other FHIR resource types will only appear in this object if resources of that type were synced.
- lastSyncedAtobject
The last time this patient's data was successfully synced in Unix time (in seconds).
This property specifically refers to the timestamp of the last COMPLETED
sync job.
- stateobject
The state of the current sync job associated with this patient authorization.
See the sync job states section for more information.
Errors
- invalid_client
The client credentials are invalid.
Ensure your API keys are correctly base64 encoded and passed in the Authorization header.
- invalid_grant
The refresh token provided was invalid or expired.
Verify that the refresh token is correct and hasn't been used previously.
- server_error
An unexpected error occurred.
Please try again later.
If the problem persists, contact support.
PUBLIC_KEY=sk_test...
SECRET_KEY=pk_test...
REFRESH_TOKEN=flexpa-link-refresh-token
# Base64 encode the credentials
CREDENTIALS=$(echo -n "${PUBLIC_KEY}:${SECRET_KEY}" | base64)
curl -X POST https://api.flexpa.com/link/token \
-H "Authorization: Basic ${CREDENTIALS}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}"
Response
{
"access_token": "eyJhbGciOiJFUzI1NiJ9.eyJqdGkiOiI5NmQ5Njgw...",
"expires_in": 86400,
"refresh_token": "b3500e631567d140ff6b5efa241c8359548e81d2...",
"refresh_expires_in": 7776000,
"sync": {
"resourceTypes": {
"AllergyIntolerance": 3,
"CarePlan": 21,
"CareTeam": 10,
"Condition": 9,
"Coverage": 18,
"Device": 0,
"DiagnosticReport": 0,
"DocumentReference": 1,
"Encounter": 0,
"ExplanationOfBenefit": 11,
"Goal": 16,
"Immunization": 0,
"MedicationDispense": 0,
"MedicationRequest": 3,
"Observation": 7,
"Patient": 1,
"Procedure": 62,
"Provenance": 0,
"Location": 0,
"Medication": 0,
"Organization": 0,
"Practitioner": 3,
"PractitionerRole": 0
},
"state": "COMPLETED",
"lastSyncedAt": 1712163905
}
}
POSThttps://api.flexpa.com/link/revoke
If a patient has linked multiple times to the same endpoint from the same application, /link/revoke
only needs to be called once to revoke all authorizations.
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Request fields
- secret_keystringRequired
Your Flexpa API secret key
Response fields
- countnumber
The number of access tokens revoked
ACCESS_TOKEN=flexpa-link-access-token
curl -X POST https://api.flexpa.com/link/revoke \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"secret_key": "sk_test..."
}'
Response
{
"count": 1
}
#FHIR API
You can make FHIR resource requests with the Flexpa FHIR API after acquiring an access_token
from POST /link/exchange.
The Flexpa FHIR API currently supports Read and Search requests.
Identify the FHIR Resource you want to Read or Search after the /fhir/
subpath of the URL.
Historically, FHIR API requests were proxied directly to the payer's endpoint
, which yielded undesirable behaviours:
- Inconsistent uptime. If an
endpoint
was unavailable at the time of the request, the request would fail.
- Inconsistent FHIR operations. For example, the Patient $everything operation was not universally supported.
- Inconsistent support for search features. For example, the
patient
search parameter was not universally supported. Similarly, the _include
parameter could be used for all fields customers expect.
Flexpa's API architecture addresses the issues mentioned above. Flexpa dynamically adapts to the unique implementations of each payer's FHIR API and synchronizes data, providing a consistent and reliable experience for developers.
For more detail about some of the specific things we do and tools we offer to make the experience better for our developers check out:
Request
ACCESS_TOKEN=flexpa-link-access-token
curl https://api.flexpa.com/fhir/ExplanationOfBenefit \
-H "Authorization: Bearer $ACCESS_TOKEN"
= ```
```js
const ACCESS_TOKEN="flexpa-link-access-token"
const response = await fetch("https://api.flexpa.com/fhir/ExplanationOfBenefit", {
headers: {
"content-type": "application/json",
"authorization": `Bearer ${ACCESS_TOKEN}`,
},
});
const cachedResponse = await response.json();
Response
{
"resourceType": "Bundle",
"id": "22f61d0877b54b2a8a2feb57bfe2c462",
"entry": [{
"resource": {
"resourceType":"ExplanationOfBenefit",
...
}
}]
}
GEThttps://api.flexpa.com/fhir/[Resource]/:id
A read is the most basic operation in FHIR. It allows you to retrieve the current version of a single resource by its ID.
For a full list of available Resources, please refer to the FHIR Resources documentation.
Many resources returned by the API will contain references to other resources.
For more information on how to handle references, see the Referenced Resources section.
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Request parameters
- identifierstring
The identifier of the resource to be retrieved - used in the last part of the URL path segment
Response fields
- resourceTypestring
Reads return an individual resource, so the resource type is expected to correspond to the resource you are reading
Error codes
- transient429 status code
The API is expected to return a 429 status code until the data is ready to be retrieved.
This error is returned by the API while in the initial sync period, which typically lasts less than 1 minute.
You will need to implement retry logic to handle this error.
Refer to the Quickstart guide for an example fetchWithRetry
implementation.
- processing422 status code
- The API is expected to return a 422 when Flexpa fails to synchronize any resources from the payer for the requested Patient. Please re-authorize or reach out to support.
ACCESS_TOKEN=flexpa-link-access-token
curl https://api.flexpa.com/fhir/Coverage/123 \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"resourceType": "Coverage",
"id": "123"
}
GEThttps://api.flexpa.com/fhir/[Resource]
Searches on Flexpa API follow the RESTful style of the FHIR specification by submitting a GET HTTP request to the base URL of the resource with parameters to define the exact search criteria to filter the response.
Many resources returned by the API will contain references to other resources.
For more information on how to handle references, see the Referenced Resources section.
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Request parameters
- _includestring
The referenced resources to include in the search response.
Only applies to relative references.
The value of the searchInclude
parameter has the format [Resource]:[field]
, for example Patient:general-practitioner
.
For more information on available searchInclude
parameters, please refer to the CapabilityStatement.
- _revincludestring
Like _include
but intstead of including the resources referenced within the searched-for resource, include resources that may reference the searched resource.
The value of the searchRevInclude
parameter has the format [Resource]:[field]
, for example Provenance:target
.
- [searchParam]string
To filter the search results server-side, you can use any of the available search parameters for the resource type you are searching for.
For more information on available searchParam
parameters, please refer to the CapabilityStatement.
Search results can also be modified by certain search result parameters.
For more information on available search result parameters, see the Search Result Parameters section.
Response fields
- resourceTypestring
Searches return a Bundle
resource type
- entryarray
An array of FHIR resources expected to match the resource type of the search
Error codes
- transient429 status code
The API is expected to return a 429 status code until the data is ready to be retrieved.
This error is returned by the API while in the initial sync period, which typically lasts less than 1 minute.
You will need to implement retry logic to handle this error.
Refer to the Quickstart guide for an example fetchWithRetry
implementation.
- processing422 status code
- The API is expected to return a 422 when Flexpa fails to synchronize any resources from the payer for the requested Patient. Please refresh again or reach out to support.
Request
const ACCESS_TOKEN="flexpa-link-access-token"
const searchUrl = "https://api.flexpa.com/fhir/ExplanationOfBenefit";
const response = await fetch(searchUrl, {
headers: {
"authorization": `Bearer ${ACCESS_TOKEN}`,
},
});
const searchBundle = await response.json();
Response
{
"resourceType": "Bundle",
"id": "22f61d0877b54b2a8a2feb57bfe2c462",
"entry": [
{
"resource": {
"resourceType": "ExplanationOfBenefit",
"id": "123"
}
},
{
"resource": {
"resourceType": "ExplanationOfBenefit",
"id": "456"
}
}
]
}
GEThttps://api.flexpa.com/fhir/Patient/$PATIENT_ID/$everything
Unique to the Patient resource, the Patient $everything
FHIR operation retrieves all resources that reference the Patient resource in a single API request.
This operation frees the client from needing to determine what it could or should ask for.
Executing this operation will return a non-paginated Bundle. The client should be prepared to handle a potentially large single response.
Please be aware that Patient $everything
will never include the following resource types in its response.
If you need the following resources, you will need to make additional read requests for them:
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Response fields
- ResponseBundle
Patient $everything returns a Bundle that contains all resources that reference the Patient resource.
GET
/fhir/Patient/$PATIENT_ID/$everythingACCESS_TOKEN=flexpa-link-access-token
curl 'https://api.flexpa.com/fhir/Patient/$PATIENT_ID/$everything' \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"resourceType": "Bundle",
"entry": [
{ "resource": {"resourceType": "Patient", ...} },
{ "resource": {"resourceType": "Coverage", ...} },
{ "resource": {"resourceType": "ExplanationOfBenefit", ...} },
]
}
POSThttps://api.flexpa.com/fhir/Patient/:patientId/$expunge
The $expunge
operation deletes all resources in a specific Patient resource compartment.
This operation performs a "hard" delete, meaning all data, including resource history, is permanently removed from the server.
Once the data is deleted, any subsequent FHIR requests to retrieve the data will return a 404 status code.
Request headers
- AuthorizationstringRequired
An Authorization: Bearer
header value must presented with the
access_token
obtained from the link exchange endpoint
Request parameters
- patientIdstring
The ID of the patient whose data you want to delete.
This ID must match the patient ID of the access token and can be retrieved with a search request for the Patient resource.
There is an option to use the patient wildcard parameter to automatically match the patient ID in the access token.
Response fields
- ResponseBundle
The Patient $expunge operation returns an OperationOutcome resource, indicating the success or failure of the expunge request.
Error codes
- transient429 status code
The API is expected to return a 429 status code until the data is ready to be retrieved.
The API returns this error during the initial sync period, which typically lasts less than 1 minute.
Data cannot be expunged until the initial sync period has passed.
POST
/fhir/Patient/$PATIENT_ID/$expungeACCESS_TOKEN=flexpa-link-access-token
curl 'https://api.flexpa.com/fhir/Patient/$PATIENT_ID/$expunge' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "X-Flexpa-Raw: 0" \
-X POST
Response
{
"resourceType": "OperationOutcome",
"id": "accepted",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"text": "Accepted"
},
"diagnostics": "http://medplum.flexpa.com/fhir/R4/job/15c72fcc-267e-4372-a85e-26fa20b01634/status"
}
],
"extension": [
{
"url": "https://medplum.com/fhir/StructureDefinition/tracing",
"extension": [
{
"url": "requestId",
"valueUuid": "175885a0-d396-4d1d-9c9d-a618f06cfdc8"
},
{
"url": "traceId",
"valueUuid": "5e18c528-a74a-4dac-9cec-b35a2ce33c3e"
}
]
}
]
}
GEThttps://api.flexpa.com/fhir/metadata
CapabilityStatement is a conformance FHIR Resource that is used to understand the exact capabilities that a FHIR server makes available.
The CapabilityStatement resource is used to describe the features and capabilities of a FHIR server in a machine-readable way.
CapabilityStatement is a base FHIR resource.
Flexpa's CapabilityStatement is available at the /fhir/metadata
route.
View it here.
#Helpful capabilities
We've highlighted the following capabilities to provide extra convenience to developers when querying data.
The following examples are defined per-resource.
interaction
is an array of objects that describe the valid operations that can be performed on the resource.
searchInclude
is an array of strings that describe the valid values that can be used with the _include
search param.
searchParam
is an array of objects that describe the valid params that the server accepts in a URL query string.
curl https://api.flexpa.com/fhir/metadata
Response
{
"resourceType": "CapabilityStatement",
"url": "https://api.flexpa.com/fhir/metadata",
"title": "Flexpa Capability Statement",
"date": "2023-11-01",
"publisher": "Flexpa",
"rest": [
{
"mode": "server",
"resource": [
{ "type": "Patient", ... },
{ "type": "Coverage", ... },
{ "type": "ExplanationOfBenefit", ... },
...
]
}
]
}
#Interaction
All the FHIR resources that Flexpa supports have both a read
and search-type
operation, which means that they can be both read and searched.
You can find the interaction
array in the CapabilityStatement resource.
Interaction
{
"resourceType": "CapabilityStatement",
"url": "https://api.flexpa.com/fhir/metadata",
"rest": [
{
"mode": "server",
"resource": [
{
"type": "Practitioner",
"interaction": [
{
"code": "read",
},
{
"code": "search-type",
}
]
}
]
}
]
}
#Search Include
The searchInclude
array describes the valid values that can be used with the _include
search param.
Each value is a string with the format [Resource]:[field]
, where [Resource]
is the resource type and [field]
is the field name.
For example, to include the care-team
field of an ExplanationOfBenefit resource in the search response, you would use the value ExplanationOfBenefit:care-team
.
For the search to successfully return a CareTeam resource, the following conditions must be met:
- A
care-team
field must be present in the ExplanationOfBenefit resource.
- The
care-team
field must contain a relative reference to a CareTeam resource.
To use the _include
search param, refer to the Search section.
Search Include
{
"resourceType": "CapabilityStatement",
"url": "https://api.flexpa.com/fhir/metadata",
"rest": [
{
"mode": "server",
"resource": [
{
"type": "ExplanationOfBenefit",
"searchInclude": [
"ExplanationOfBenefit:care-team",
]
}
]
}
]
}
#Search Param
The searchParam
array describes the valid params that the server accepts in a URL query string.
These params can be used to filter the search results.
The name of the param can be accessed in the name
property of each searchParam
object in the CapabilityStatement resource.
To filter search results with a searchParam
, refer to the Search section.
Search Param
{
"resourceType": "CapabilityStatement",
"url": "https://api.flexpa.com/fhir/metadata",
"rest": [
{
"mode": "server",
"resource": [
{
"type": "Condition",
"searchParam": [
{
"name": "onset-age",
"definition": "http://hl7.org/fhir/SearchParameter/Condition-onset-age",
"type": "quantity"
}
]
}
]
}
]
}
#Wildcard Parameters
Flexpa API supports wildcard parameters that can be used in URL query parameters in FHIR API requests.
Wildcards are used as tokens directly in the URL of the API request you make to Flexpa.
They are replaced with real values by the API using context provided by the required Patient Access Token.
We currently support one parameter $PATIENT_ID
, which references the patient_id
belonging to the access_token
.
Flexpa will replace this token with the correct patient_id
when you make an API request to Flexpa.
Wildcard in Patient Read
ACCESS_TOKEN=flexpa-link-access-token
curl 'https://api.flexpa.com/fhir/Patient/$PATIENT_ID' \
-H "Authorization: Bearer $ACCESS_TOKEN"
#Search Result Parameters
Flexpa supports search result parameters as a way to modify search results. The following search result query parameters can be used in your search request:
_totalstringThe _total
query parameter will include in the bundle the number of resources that match the search parameters. It is not always visible on the bundle. The possible values for the _total
search result paramter are:
none
: Flexpa will not include the total in the response
accurate
: Flexpa will provide the exact total of matching resources, if available. Note that this may be more server intensive.
estimate
: Flexpa will provide a rough estimate of the number of matching resources, if available.
_sortstringThe _sort
parameter is used to sort results in priority order based on a comma-separated list of search parameters, for example status,-date,category
.
If the _sort
value starts with -
, then the results are returned in decreasing order, otherwise they are returned in increasing order.
_summarystringThe _summary
parameter returns a portion of a resource's elements in order to help optimize queries for only the essential information.
Supported values for _summary
are true
, which returns only elements that are marked summary
in the resource's definition, and count
which will return only the count of matching resources, but no other resource details.
_elementsstringThe _elements
parameter returns a specified subset of a resource's elements. Specified elements are given as a list of comma separated values, for example _elements=identifier,active,link
.
However, more than only requested elements may be returned, including mandatory elements or modifier elements that have values.
_countstringThe _count
parameter limits the number of results per page. See Pagination for more information.
Request
GET
/fhir/[Resource]?_total=[none|accurate|estimate]const ACCESS_TOKEN="flexpa-link-access-token";
const searchUrl = "https://api.flexpa.com/fhir/ExplanationOfBenefit?patient=$PATIENT_ID&_total=accurate";
const response = await fetch(searchUrl, {
headers: {
"authorization": `Bearer ${ACCESS_TOKEN}`,
},
});
const searchBundle = await response.json();
Response
{
"resourceType": "Bundle",
"type": "searchset",
"entry": [...],
"total": 11,
"link": [...]
}
Flexpa supports pagination on the results of a FHIR search request.
Pagination can reduce the load on both the client and server.
You can leverage pagination using the following query parameters in your search request:
_count
to control the page size
_offset
to control the page number
In the Flexpa API, the default page size is 20, and the maximum allowed page size is 1000.
Alternatively, if a search result is paginated, the Bundle includes a link
array that references other pages in relation to the current page:
self
is the URL of the current page. Always present in link
.
first
is the URL of the first page. Always present in link
.
next
is the URL of the next page. Only present in link
if there is a next page.
previous
is the URL of the previous page. Only present in link
if there is a previous page.
For example, to access the next page of resources, make a GET request to the URL indicated by "relation": "next"
.
GET
/fhir/Condition?_count=3ACCESS_TOKEN=flexpa-link-access-token
curl https://api.flexpa.com/fhir/Condition?_count=3 \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"resourceType": "Bundle",
"type": "searchset",
"entry": [ ... ],
"link": [
{
"relation": "self",
"url": "https://api.flexpa.com/fhir/Condition?_count=3&_offset=6&_tag=..."
},
{
"relation": "first",
"url": "https://api.flexpa.com/fhir/Condition?_count=3&_offset=0&_tag=..."
},
{
"relation": "next",
"url": "https://api.flexpa.com/fhir/Condition?_count=3&_offset=9&_tag=..."
},
{
"relation": "previous",
"url": "https://api.flexpa.com/fhir/Condition?_count=3&_offset=3&_tag=..."
},
]
}
In order to support the ease with which our implementers can rely on our data we do some simple transformations on the data coming from the payer's endpoints.
#Flexpa Tagging
The first thing we do is that we add some Flexpa specific data to each resource. Namely, we add some identifiers to the tag
array in the Meta
section of each resource. This is meant to help link data back to Flexpa specific entities such as PatientAccessToken, Endpoint and Application (your application).
#FHIR logical ID
Flexpa will replace the FHIR Logical ID on every resource to ensure uniqueness and avoid ID collision. However, we want to make sure that you have access to the original ID. So, we add the ID from the payer to both the meta.source
and the identifier
array on the resource.
#Required fields
Flexpa ensures that any field required by the FHIR spec will exist even if it isn't provided by the source payer. We will return those fields with a value similar to "Undefined by source".
Resource
{
"resourceType": "ExplanationOfBenefit",
"id": "<Flexpa generated id>",
"identifier": [
{
"value": "<id from payer>",
"system": "https://https://apif1.aetna.com/fhir/v2/patientaccess/ExplanationOfBenefit/SourceResourceId",
}
],
"meta": {
"source": "<id from payer>",
"tag": [
{
"system": "https://fhir.flexpa.com/identifiers/PatientAccessTokenId",
"code": "66eed280-324d-4c4e-b8ca-d71c481075c5"
},
{
"system": "https://fhir.flexpa.com/identifiers/EndpointId",
"code": "663f104c-216f-4d50-83f8-cf061a0e6e68"
},
{
"system": "https://fhir.flexpa.com/identifiers/ApplicationId",
"code": "16678ba4-5282-4fd5-9131-f4f11e3901ee"
},
{
"system": "https://fhir.flexpa.com/identifiers/PatientAuthorizationMode",
"code": "LIVE"
}
]
},
"provider": { "display": "Undefined by source" }
...
}
#Referenced Resources
Many resources returned by the API will contain references to other resources.
A reference is a string that points to the location where the referenced resource can be retrieved.
For instance, a Patient may contain a reference to an Organization or a Practitioner.
References can be categorized into one of three types, each of which require a different approach to resolve:
#Relative references
Relative references are relative to the base resource.
They can be identified by the structure [resourceType]/[id]
.
You can resolve a relative reference by appending the value of the reference
string to the base URL in a subsequent GET request.
Alternatively, you can conveniently resolve relative references in a single API request by using the _include
parameter on a Search operation.
For more information on available searchInclude
parameters, please refer to the CapabilityStatement.
#Internal references
Internal references point to a "contained" resource that is directly embedded within the base resource.
They can be identified by a #
prefix.
You can access the contained resource in the contained
field by filtering for the matching id
.
Contained resources in FHIR do not need to be complete resources.
For example, a contained resource may only contain a name
field and this is considered valid FHIR.
#Absolute references
Absolute references are standalone URLs.
They can be identified by any valid URI prefix, but are typically prefixed by either http
, https
or urn
.
You may be able request more data using the URL in its entirety.
Note that this request will be to a FHIR API separate from Flexpa's.
Following URLs to external servers is always risky.
Please consider the security implications of doing so and take the appropriate steps to mitigate unintended access to malicious servers, such as an allowlist of trusted servers for example.
Alternatively, the most conservative approach is to avoid following absolute references altogether.
For more information on references in FHIR, please refer to the FHIR References documentation.
Resolving References
const patient = {
"resourceType" : "Patient",
"generalPractitioner" : {
"reference" : "Practitioner/123"
}
};
const ACCESS_TOKEN="flexpa-link-access-token";
const response = await fetch("https://api.flexpa.com/fhir/Practitioner/123", {
headers: {
"authorization": `Bearer ${ACCESS_TOKEN}`,
},
});
const practitioner = await response.json();
Resolved Resource
{
"resourceType" : "Practitioner",
"id" : "123",
"name" : "Dr. Adam Smith"
}
#Errors
When a request is unsuccessful, Flexpa API attempts to return an OperationOutcome
FHIR R4 Resource.
If the Endpoint connected by the patient during authorization returns an OperationOutcome
Flexpa API returns it directly.
If the endpoint does not return an OperationOutcome
, Flexpa API substitutes the actual response with a Flexpa-generated OperationOutcome
to represent the error.
Your application code should be prepared to handle the following issue.code
values:
Error codes
- processing422 status code
- Processing issues. This is expected to be final (e.g., there is no point resubmitting the same content unchanged).
- transient429 status code
- The API is expected to return a 429 status code until the data is ready to be retrieved. The API returns this error during the
- initial sync period
- , which typically lasts less than 1 minute. Data cannot be expunged until the initial sync period has passed.
- not-supported404 status code
- The interaction, operation, resource or profile is not supported.
- forbidden403 status code
- The user does not have the rights to perform this action.
- exception500+ status code
- An unexpected internal error has occurred.
Error response
{
"resourceType": "OperationOutcome",
"issue": [{
"severity": "error",
"code": "not-supported"
}],
};
#REST API
Flexpa makes available some APIs to your application without authentication. These APIs are largely informational and intended to supplement equivalently accessible information found in our documentation.
GEThttps://api.flexpa.com/organizations
An organization is a payer, provider, or vendor entity that operates an Endpoint.
This API returns data also available in our payer network documentation.
Response fields
- namestring
The name
of the organization
- idstring
The id
that Flexpa uses to identify this organization
- notestring
The note
is used to detail whether the organization supports just CMS plans or all plans (including commercial lives)
- typestring
The type
details whether the organization is a payer, a provider, a vendor, or another type of entity.
curl https://api.flexpa.com/organizations \
-H 'Content-Type: application/json'
Response
[
{
"name": "SCAN Health Plan",
"id": "a4212073-f832-483c-8fd0-706f97fe3d8e",
"note": "CMS plans",
"type": "PAYER"
},
{
"name": "Blue Cross and Blue Shield of North Carolina",
"id": "12db2e9e-26f5-4ee6-b705-29ee9349f653",
"note": "CMS plans",
"type": "PAYER"
},
...
]
GEThttps://api.flexpa.com/endpoints
Endpoints are individual FHIR REST API servers in Flexpa's network created and maintained by payers. They are used to access patient data.
This API returns data also available our endpoint network documentation.
Response fields
- namestring
The name
attribute is a human-readable unique identifier for the endpoint. This attribute is subject to change, so we recommend using the id
attribute as a static identifier.
- idstring
The id
that Flexpa uses to identify this endpoint
- modestring
The mode
is used to detail whether the endpoint is for test or live mode
- labelarray
The label
is a human-readable name for the endpoint. This is often equivalent to the payer name, but may be a brand level name if the payer has multiple brands.
- refreshableboolean
The refreshable
is boolean that indicates whether the endpoint supports refreshing an authorization without the original user present. If you attempt to use MULTIPLE
as your intended usage
for a non-refreshable endpoint we will still complete the authorization but only one time. That authorization cannot be refresh without further user interaction.
- refreshValidFornumber
The refreshValidFor
represents the maximum time (in seconds) for which an access_token
can be refreshed against the endpoint.
After this period elapses, the user is required to re-authorize.
A 0
indicates that the endpoint is refreshable indefinitely.
If the endpoint is refreshable, a null
suggests that this value is unknown to Flexpa.
- maxAuthPeriodnumber
The maxAuthPeriod
represents the maximum time (in seconds) for which an endpoint will allow a user to keep an application authorized to it. After this period elapses, the user is required to re-authorize. A 0
indicates that the endpoint can be authorized indefinitely. If the endpoint is refreshable, a null
suggests that this value is unknown to Flexpa.
- statusenum
The status
is an enumerated list of values:
The endpoint is available for use, but has not yet been validated via our user testing program.
The endpoint is live and has been validated by a user.
The endpoint is live and has been validated based on related tests.
The endpoint is not currently live due to an issue identified during user testing.
- resourcesarray
resources
is an array of FHIR resources supported by the endpoint
- organizationobject
The organization
is a JSON object that shows the ID and name of the payer associated with the endpoint.
curl https://api.flexpa.com/endpoints \
-H 'Content-Type: application/json'
Response
[
{
"name": "san-francisco-health-plan-test",
"id": "46062592-1111-4a06-8974-da9589119238",
"mode": "TEST",
"label": ["San Francisco Health Plan"],
"refreshable": false,
"status": "LIVE",
"resources": [
"Account",
"ActivityDefinition",
"AdverseEvent",
"AllergyIntolerance",
"Appointment",
...
],
"organization": {
"id": "de83b67b-b176-49ef-b83d-8f8edcd45761",
"name": "San Francisco Health Plan (SFHP)"
}
},
{
"name": "village-care-max-test",
"id": "5c34e5d2-bb46-42d3-a1ce-9b9d2d1fec26",
"mode": "TEST",
"label": ["VillageCareMAX"],
"status": "USER_VALIDATED",
"refreshable": false,
"refreshValidFor": 86400,
"maxAuthPeriod": 31536000,
"resources": [
"AccessPolicy",
"Account",
"ActivityDefinition",
"AdverseEvent",
"AidboxConfig",
...
],
"organization": {
"id": "603889da-dc1e-4f67-b0cf-04d76edc2dcf",
"name": "Horizon Blue Cross Blue Shield of New Jersey"
}
}
...
]
POSThttps://api.flexpa.com/apply
At Flexpa, our API is core to everything we do. If you're excited to work with us, applying by API is the best way to get our attention.
Find out more about how we work in the Flexpa OS.
Parameters
- namestringRequired
Your name
- emailstringRequired
Your email address
- whystringRequired
Why do you want to work at Flexpa?
- locationstringRequired
Your location
- resumestringRequired
A link to your resume
- phonestring
A phone number where we can reach you
- githubstring
A link to your GitHub profile
- linkedinstring
A link to your LinkedIn profile
- websitestring
A link to your personal website
- twitterstring
A link to your Twitter profile
curl -X POST https://api.flexpa.com/apply \
-H 'Content-Type: application/json' \
-d '{
"name": "Fizz Buzz",
"email": "fizz@example.com",
"why": "I want to work at Flexpa because...",
"location": "Foobar, USA",
"resume": "https://www.dropbox.com/s/123456789/resume.pdf",
"phone": "555-555-5555",
"github": "@fizzbuzz",
"linkedin": "https://www.linkedin.com/in/fizz-buzz-123456789/",
"website": "https://www.example.com/",
"twitter": "@fizzbuzz"
}'
#FAQ
#Which FHIR version does the API support?
The API supports FHIR R4.
#Does the API support CORS?
No, the API does not support CORS.
The Quickstart repository contains a simple example of a server making requests - replicating that behavior for both the Link operations but also subsequent FHIR requests is important for security.
#Next steps