---
updatedAt: 2026-09-08T17:12:52.000Z
agentTools:
  projectIndex: https://docs.zushealth.com/llms.txt
---

# GraphQL API

The Zus FHIR GraphQL API allows users to interactively retrieve structured health data for use in web and API applications.

<Callout icon="📘" theme="info">
  ### API Reference

  This page provides a high-level introduction to the Zus FHIR GraphQL API. For additional information on the types of queries that the API supports, please visit our [API reference](https://fqs-docs.zusapi.com/).
</Callout>

<Callout icon="🚧" theme="warn">
  ### Beta

  This service is in a stage of development that may be subject to change or deprecation and may not yet be feature complete or perform consistently.
</Callout>

# Getting started with GraphQL

[GraphQL](https://graphql.org/) is a flexible data query language that allows you to request exactly the data you need, allowing for more efficient data retrieval. If you are new to the technology, here are some great educational resources:

* [Introduction to GraphQL](https://graphql.org/learn/)
* [How to GraphQL](https://www.howtographql.com/)
* [Guides and Best Practices](https://www.graphql.com/guides/)

## Endpoint

FHIR REST APIs have numerous endpoints. The GraphQL API has a single endpoint that remains constant no matter what query you perform. The endpoint has the prefix FQS, which stands for FHIR Query Service.

> POST <https://fqs.zusapi.com/query>

## Authentication

All requests to the GraphQL API require authentication. The GraphQL API supports the same HTTP Authorization token used throughout Zus APIs. Queries are made using a POST request and a bearer token. See [Authenticating for API Access ](https://docs.zushealth.com/docs/user-authentication#/authenticating-for-api-access) for instructions on obtaining a bearer token.

```
POST fqs.zusapi.com/query
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Content-Type: application/json
```

## Data you are authorized to see

You are permitted to view data in the Zus platform that was either created directly by your organization, or is part of the or a patient that your organization has a treatment relationship with.

The GraphQL API supports queries scoped to one human — FHIR resources associated with one Universal Patient Identifier — on resource types in the [Designated Record Set](https://docs.zushealth.com/docs/patient-level-access#designated-record-set). For simplicity, the patient will be referred to as one UPID and these queries as UPID-scoped searches.

The GraphQL API also supports queries scoped to one Builder for the Patient, Practitioner, and Organization resource types.

<Callout icon="👍" theme="okay">
  ### To view data in the Common Patient Record, perform UPID-scoped searches. To view data that was created by your organization, perform builder-scoped searches.
</Callout>

# Forming a query

The Zus FHIR GraphQL Service is read-only and thus only allows the query operation, the equivalent of making a GET request in REST. GraphQL queries return only the data you specify. To form a query, you must specify fields within fields until you return only scalars.

## Examples

### Get a single Patient by FHIR ID

If you know the FHIR ID of a Patient resource, the following query in Example 1 returns the id, given names, and family name of the Patient. Example 2 shows a query that returns more detailed information in the Patient resource, including the address and contact information.

```json Example 1 - Name and ID
query {
  Patient (id: $id) {
    id
    name { 
      family 
      given
    }
  }
}
```
```Text Example 2
query {
	Patient(id: $id) {
    address {
    	city
    	country
    	district
    	line
    	period {
        	start
        	end
    	}
    	postalCode
    	state
    	text
    	type
    	use
    }
    birthDate
    contact {
    	relationship {
        coding {
        code
       }
    }
    telecom {
        system
        use
        value
    }
    }
    deceasedBoolean
    deceasedDateTime
    gender
    id
    identifier {
    	system
    	value
    }
    maritalStatus {
    	coding {
        code
    	}
    	text
    	}
    managingOrganization {
    	reference
    	display
    	}
    name {
    	family
    	given
    	period {
        start
        end
    	}
    	prefix
    	suffix
    	text
    	use
    }
	}
}
```

### Search for Patients with a UPID

The List query type allows you to retrieve the first n results. The first 10 results are returned by default.

```json
query {
  ConditionList (upid: $upid) {
    id
    meta { lastUpdated }
  }
}
```

#### Paginating through results

If you need to paginate through a large number of results, use the Connection query type.

```json
query {
  ConditionConnection (
    upid: $upid,
    first: 100,
    after: "",
    filter: { clinicalStatus: { anymatch: "active" } }
) {
    pageInfo {
      hasNextPage
    }
    edges {
      node {
        id
        meta { lastUpdated }
      }
      cursor
    }
  }
}

```

The response includes a value for the cursor. To get the next page of results, provide the after parameter using the last cursor in the last page.

```json
query MedicationRequest {
  MedicationRequestConnection(
    upid: "4ed64962-9c8f-4712-9484-db6f85174817"
    after: "f789c7f7-f706-4119-98ff-c23c578c10f1"
  ) {
    edges {
      node {
        id
        meta {
          tag {
            system
            code
          }
        }
      }
      cursor
    }
    pageInfo {
      hasNextPage
    }
  }
}

```

We currently have a partial implementation of the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). Forward pagination (with first and after) is supported, but reverse pagination (with last and before) has not been implemented.

# Syntax Overview

The POST body is passed as a JSON string:

```
{  
    "query": "<queryContent>",  
    "variables": {  
        "variable1": "value1"  
    }  
}
```

`<queryContent>` is a GraphQL query string:

```
query <queryName> {
    <queryType> (<parameters>) {
        <fields>
    }
}

```

* `<queryName>` is optional and allows you to identify your query.
* `<queryType>` is one of the types below.
* `<parameters>` varies by query type. There is always a required scope parameter (id or upid), and Connection query types support optional pagination, filter, and sort parameters.
* `<fields>` varies by query type. See the documentation below for where to request specific FHIR fields.

## Single resource

```
query [<name>] {
  <resourceType> (id: $id) {
    // FHIR fields
  }
}

```

* `<resourceType>` is the FHIR resource type
* $id (required) is the FHIR resource ID

## Single resource history

History queries return all versions of a single resource. Versions are sorted in ascending order.

```
query [<name>] {
  <resourceType>History (id: $id) {
    // FHIR fields
  }
}

```

* `<resourceType>` is the FHIR resource type
* $id (required) is the FHIR resource ID

## UPID-scoped queries

### List queries

```
query [<name>] {
  <resourceType>List (upid: $upid) {
    // FHIR fields
  }
}

```

* `<resourceType>` is the FHIR resource type
* $upid (required) is the patient UPID

### Connection queries

```
query [<name>] {
  <resourceType>Connection (upid: $upid, [<pagination>], [<sort>], [<filter>]) {
    pageInfo {
      hasNextPage
    }
    edges {
      node {
        // FHIR fields
      }
      cursor
    }
  }
}

```

* `<resourceType>` is the FHIR resource type
* $upid (required) is the patient UPID
* `<pagination>` (optional) can be any/all of the pagination parameters. See below for pagination parameter documentation.
* `<sort>` (optional) is a field to sort by. See details below.
* `<filter>` (optional) is an object of fields to filter by. See details below.

## Builder-scoped queries

Supported for Patient, Organization, and Practitioner

### List queries

```
query [<name>] {
  <resourceType>List (builderID: $builderID) {
    // FHIR fields
  }
}
```

* "resourceType" is the FHIR resource type
* $builderID is the builderID you would like to filter by. If you do not pass a builderID it will default to the builder in your JWT.

### Connection queries

```
query [<name>] {
  <resourceType>Connection (builderID: $builderID, [<pagination>], [<sort>], [<filter>]) {
    pageInfo {
      hasNextPage
    }
    edges {
      node {
        // FHIR fields
      }
      cursor
    }
  }
}
```

* `<resourceType>` is the FHIR resource type
* $builderID is the builderID you would like to filter by. If you do not pass a builderID it will default to the builder in your JWT
* `<pagination>` (optional) can be any/all of the pagination parameters. See below for pagination parameter documentation.
* `<sort>` (optional) is a field to sort by. See details below.
* `<filter>` (optional) is an object of fields to filter by. See details below.

## Filtering

Connection queries support a filter argument to filter returned results. The filter argument has the following form:

```
{
    <searchTerm>: { <predicate>: <value> }
}

```

Valid values for `<searchTerm>` depend on the resource type. All resource types support a `<searchTerm>` of tag and ids. To look up what filter parameters are supported by each resource type, look for `<resourceType>`FilterParams under the list of types.

### Predicates

Valid values for `<predicate>` and `<value>` depends on the search term type.

All types

| Predicate | Values          | Description                                         |
| :-------- | :-------------- | :-------------------------------------------------- |
| missing   | true<br />false | Match resources that have or are missing this field |

## Including referenced resources

Rather than have to conduct a separate query to retrieve a referenced resource of a different resource type, you can include a referenced resource in a result set through the `resource` element by leveraging [fragments](https://graphql.org/learn/queries/#fragments). For example, to include the id and name of the Organization resource referenced by a Patient resource through its managing organization:

```json
query {  
  PatientList(upid: "6a97a8ff-07fc-41b7-9284-487f29671146" {  
		id
    meta {
        lastUpdated
        versionId
        tag {
            system
            code
        }
    }
    extension {
        url
        valueString
    }
    managingOrganization {
      resource {
        ... on Organization {
            id
            name
        }
      }
    }
  }
}
```

# Constraints and Best Practices

At this time,

* The GraphQL API follows the rate limits as defined in the [Zus FAQs](https://docs.zushealth.com/docs/faqs#is-the-zus-api-rate-limited).
* Superclusters (UPIDs with more than 1000 resources for a single resource type) have poor query performance.
* The GraphQL API does not guarantee immediate read-your-write consistency. There may be a delay between when data is written and when it becomes available for subsequent read operations, which can result in inconsistencies.

For best practices,

* Don't request more fields than needed. Response latency is correlated with response size, and requesting too many fields increases the size of the response.
* If you're trying to compute statistics or export data in bulk, you should use [Data Marts](https://docs.zushealth.com/docs/data-marts).