openapi: 3.0.3
info:
title: Garner Health Facilities Providers API
version: v1.11.0
license:
name: Commercial
url: https://getgarner.com
description: "Garner's APIs power its core provider recommendation experience. These recommendations are based on over 60 billion\nanonymized health insurance claims that paint a clear picture of a patient's journey through the healthcare system. \n\nUsing these data, Garner evaluates whether physicians practice evidence-based medicine as defined by major,\nrespected healthcare journals. Garner has designed over 550 clinical and financial metrics that look closely\nat every decision a physician makes rather than relying on standard industry episode groupers. This results in\nrankings that are much more transparent and trustworthy and enable better-informed decisions for patients,\nphysicians, and payers.\n\n# Authentication: \n \n## OAuth2.0\n\n*If you were provided a JWT at account setup rather than an API client id and client secret, please refer to instructions for [legacy token authentication.](#section/Authentication:/Legacy-token)*\n\nGarner APIs authenticate with OAuth 2.0 access tokens. You will be provided an API client ID and API client secret during account setup. \nThe client ID and client secret can be exchanged for an access token which in turn authenticates your app when making calls to Garner's APIs. \n\nTo obtain an access token, make a request to the `POST oauth2/token/` endpoint. In the request body, include the `client_id`, `client_secret`, \nand `grant_type=client_credentials`. This response will contain an `access_token`, the `token_type` which will always be \"Bearer\", \nand `expires_in` which is the lifetime in seconds of the token. \n\nThe access token can be used to authenticate with Garner's APIs. When making a request, provide the access token as a \nbearer token in the `Authorization` header. \n\nFor example, \n\n**JavaScript**\n```js\n/* Get the token */\nconst { access_token, token_type, expires_in } = await fetch('https://api.getgarner.com/oauth2/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: '<YOUR_API_CLIENT_ID_HERE>',\n client_secret: '<YOUR_API_CLIENT_SECRET_HERE>',\n }),\n}).then(r => r.json());\n\n\n/* Use the token */\nconst { providers } = fetch(\n 'https://api.getgarner.com/providers',\n {\n method: 'GET',\n headers: {'Authorization': `Bearer ${<YOUR_ACCESS_TOKEN_HERE>}`},\n query: ...\n },\n).then(response => response.json());\n\n``` \n**cURL**\n```sh\n# Get the token\ncurl --location 'https://api.garner.health/oauth2/token' \\\n--header 'Content-Type: application/x-www-form-urlencoded' \\\n--data-urlencode 'grant_type=client_credentials' \\\n--data-urlencode 'client_id=<YOUR_API_CLIENT_ID_HERE' \\\n--data-urlencode 'client_secret=<YOUR_API_CLIENT_SECRET_HERE>'\n\n# Use the token\ncurl -G https://api.getgarner.com/providers -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN_HERE>'\n```\n\n\n### Managing the access token\nThe access token will only be valid for 15 minutes. We recommend caching the token in your application so that it can be reused up to its expiration. This can be managed by the app programmatically by implementing a `GarnerTokenClient` class like the following:\n```typescript\nclass GarnerTokenClient {\n /** Cached access token */\n private currentToken: string | undefined;\n /** Time at which the cached token expires */\n private expirationTime: number | undefined;\n\n /** \n * Fetches a new access token from the `POST /oauth2/token` endpoint,\n * then caches the token and its expiration time.\n * Returns a promise that resolves to the newly fetched access token\n */\n private async fetchNewToken(): Promise<string> {\n const currentTime = Date.now();\n const { access_token: accessToken, expires_in: expiresIn } = await fetch('https://api.getgarner.com/oauth2/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: '<YOUR_API_CLIENT_ID_HERE>',\n client_secret: '<YOUR_API_CLIENT_SECRET_HERE>',\n }),\n }).then(r => r.json());\n // Cache the access token\n this.currentToken = accessToken;\n // Set the expiration time as the current time plus the number of ms until the token expires. Subtract a 15 second buffer to account for lag.\n this.expirationTime = (currentTime + expiresIn * 1000) - 15000; \n return accessToken;\n }\n\n /** \n * Returns the cached access token if it is valid. \n * Otherwise, fetches a new token.\n */\n async getToken(): Promise<string> {\n if (this.currentToken && this.expirationTime && Date.now() < this.expirationTime) {\n return this.currentToken;\n }\n return await this.fetchNewToken();\n }\n}\n```\n\nThen when making a request to Garner's APIs you can use the response of `getToken()` from an instance of the `GarnerTokenClient` class as your token.\n\nFor example, \n\n```typescript\nconst garnerTokenClient = new GarnerTokenClient();\n\nfetch('https://api.getgarner.com/providers',\n {\n method: 'GET',\n headers: {'Authorization': `Bearer ${await garnerTokenClient.getToken()}`},\n query: ...\n },\n);\n\n```\n## Legacy token\n\n*If you were provided an API client id and client secret at account setup rather than a token, please refer to instructions for [OAuth2.0 authentication.](#section/Authentication:/OAuth2.0)*\n\nAuthenticating is done with an JSON Web Token (JWT) provided as a `Bearer` token to the `Authorization` header.\nYou will have received a token during account setup.\n\nFor example, \n```sh\ncurl -G https://api.getgarner.com -H 'Authorization: Bearer <YOUR_API_TOKEN_HERE>'\n```\n"
servers:
- url: https://api.getgarner.com
security:
- ApiToken: []
tags:
- name: Providers
paths:
/providers:
parameters:
- $ref: '#/components/parameters/acceptVersion'
- name: Request-ID
in: header
schema:
type: string
required: false
description: Correlation ID to be provided on responses
get:
operationId: GetRankedProviders
summary: Get a list of providers near a position
x-codeSamples:
- lang: curl
source: "curl -i -X GET \\\n 'https://api.getgarner.com/providers?gender=male&language=fas&lat=40.8144984&limit=30&lng=-74.259863&networkId=string&plan=core&specialty=adult_general_gastroenterologist' \\\n -H 'Accept-Version: 1' \\\n -H 'Authorization: Bearer <YOUR_API_TOKEN_HERE>' \\\n -H 'Request-ID: string'\n"
- lang: JavaScript
source: "const query = new URLSearchParams({\n gender: 'male',\n language: 'fas',\n lat: '40.8144984',\n lng: '-74.259863',\n limit: '30',\n networkId: 'string',\n plan: 'core',\n specialty: 'adult_general_gastroenterologist'\n}).toString();\n\nconst resp = await fetch(\n `https://api.getgarner.com/providers?${query}`,\n {\n method: 'GET',\n headers: {\n 'Accept-Version': '1',\n 'Request-ID': 'string',\n Authorization: 'Bearer <YOUR_API_TOKEN_HERE>'\n }\n }\n);\n\nconst data = await resp.text();\nconsole.log(data);\n"
description: "This endpoint supports two modes of querying. Depending on the query parameter you provide, a different result\nwill be returned.\n\n| Query Parameter | Search Mode | Query Type | Result Type |\n| -- | -- | -- | -- |\n| `specialty` | Ranked Search | `RankedProviderQuery` | `RankedProviderList` |\n| `name` | Directory Search | `DirectorySearchQuery` | `DirectorySearchResultList` |\n| `npi` | Directory Search | `DirectorySearchQuery` | `DirectorySearchResultList` |\n\n\n### Ranked Search (Primary)\n\nPerforms a ranked query for a specialty near a specific `Position`. This will return \nresults in rank-order, where the first `Provider` in the list is the most highly recommended based on distance, \nquality, cost, and patient reviews.\n\n### Directory Search (Secondary)\n\nPerforms a lookup for a professional by name or NPI near a specific Position; facilities are not currently \nsupported. **This will return results by relevance to the query. Providers returned are not necessarily\nrecommended by Garner.**\n"
parameters:
- name: QueryModeParams
in: query
explode: true
schema:
oneOf:
- $ref: '#/components/schemas/RankedProviderQuery'
- $ref: '#/components/schemas/DirectorySearchQuery'
responses:
'200':
description: Providers resolved successfully
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/RankedProviderList'
- $ref: '#/components/schemas/DirectorySearchResultList'
'422':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/ServiceError'
tags:
- Providers
components:
schemas:
Position:
description: Global coordinates
type: object
properties:
lat:
type: number
description: Latitude
lng:
type: number
description: Longitude
required:
- lat
- lng
additionalProperties: false
Location:
description: The office location of a provider
type: object
properties:
id:
type: string
description: The unique identifier for this location
name:
type: string
description: Name of the office or facility for the associated location and provider. Only returned if provider is a professional rather than a facility
providerCorporationName:
type: string
description: The primary provider corporation (e.g. health system) affiliated with this location. When both `providerCorporationName` and `allProviderCorporations` are present, the value here is also included in `allProviderCorporations`. Only returned when the provider is a professional and the corporation is known.
example: NYU Langone Health
allProviderCorporations:
type: array
items:
type: string
description: All provider corporations (e.g. health systems) the professional is affiliated with at this location. When `providerCorporationName` is also returned, it is the primary entry in this list. Only returned when the provider is a professional and at least one affiliation is known.
example:
- NYU Langone Health
- Mount Sinai Health System
lines:
type: array
items:
type: string
description: The lines of an address, in order
city:
type: string
description: The city of the address
state:
type: string
description: The state of the address
position:
$ref: '#/components/schemas/Position'
required:
- lines
- city
- state
- zipCode
- position
additionalProperties: false
WorkingHours:
description: The days and times of day the provider's office is open
type: object
properties:
day:
$ref: '#/components/schemas/DayOfWeek'
open:
type: number
description: The time of day the office opens. Represented as minutes after midnight
close:
type: number
description: The time of day the office closes. Represented as minutes after midnight
BaseQuery:
type: object
properties:
lat:
type: number
description: Latitude of the origin of the query. Must be combined with `lng`. Must not be combined with `zipCode`
example: 40.8144984
lng:
type: number
description: Longitude of the origin of the query. Must be combined with `lat`. Must not be combined with `zipCode`
example: -74.259863
zipCode:
format: '[0-9]{5}'
type: string
description: The center of this ZIP-5 code to use as the origin of the query. Must not be combined with `lat` or `lng`
example: '10451'
plan:
type: string
description: The data subscription plan associated with your account. Contact your account manager for the correct value to this parameter.
example: core
limit:
type: number
description: The maximum number of providers to include in the response. Defaults to 15.
example: 15
maximum: 30
default: 15
required:
- plan
DayOfWeek:
type: number
enum:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
description: ISO day of week (e.g. 1 is Monday)
ServiceError:
type: object
properties:
requestId:
type: number
message:
type: string
data:
type: object
additionalProperties: true
required:
- message
additionalProperties: false
DirectorySearchResultList:
type: object
properties:
providers:
type: array
items:
$ref: '#/components/schemas/ProviderDirectoryEntry'
description: The result list of professionals for the request.
required:
- providers
RankedProviderList:
type: object
properties:
providers:
type: array
items:
$ref: '#/components/schemas/RankedProvider'
description: The result list of providers (professionals or facilities) for the request. The providers are in rank order.
required:
- providers
DirectorySearchQuery:
allOf:
- type: object
properties:
name:
type: string
description: Name or partial name of the provider. Must not be combined with `npi`
example: Mark Smith
npi:
format: '[0-9]{9}'
type: string
description: The unique identifier for the provider. Must not be combined with `name`
example: 123456789
networkId:
type: string
description: "When included, the `networkStatus` attribute of the result will indicate whether the physician is \nin-network with the given network.\n"
gender:
type: string
enum:
- male
- female
description: Filters results to a given gender. If omitted, no gender filter will be applied.
language:
type: string
description: Filters results to require a given language to be spoken by the provider. If omitted, no language filter will be applied. Must be provided as a [ISO639-3](https://iso639-3.sil.org/code_tables/639/data) code.
example: fas
required:
- networkId
- $ref: '#/components/schemas/BaseQuery'
RankedProvider:
type: object
properties:
id:
type: string
description: Unique identifier for the provider
npi:
type: string
description: National Provider Identifier
firstName:
type: string
description: First name of the provider. Only returned if provider is a professional rather than a facility
lastName:
type: string
description: Last name of the provider. Only returned if provider is a professional rather than a facility
credentials:
type: string
description: Degrees and certifications held by the provider. Only returned if provider is a professional rather than a facility
example: MD
gender:
$ref: '#/components/schemas/Gender'
specialty:
type: string
description: The specialty identifier for the provider
example: adult_general_gastroenterologist
organizationName:
type: string
description: Name of the facility. Only returned if provider is a facility rather than a professional
example: Mount Sinai
languages:
type: array
items:
type: string
format: '[a-z]{3}'
description: List of languages spoken by the provider. Languages are [ISO639-3](https://iso639-3.sil.org/code_tables/639/data) codes. Only returned if provider is a professional rather than a facility,
metrics:
description: Relevant metrics for the query. Will be repeated for each provider ranked for ease of comparison.
type: array
items:
type: object
properties:
id:
type: string
description: Metric descriptor
example: id="Patient Outcomes"
value:
type: string
enum:
- good
- very_good
- excellent
description: Performance on the metric. Providers will only be recommended by the API if they have at least a score of `good` on each metric
overallScore:
description: Score for the provider taking into account overall quality and cost
type: integer
minimum: 0
maximum: 100
reviewStars:
description: Star-rating synthesizing the patient reviews for the provider
type: number
minimum: 1
maximum: 5
location:
$ref: '#/components/schemas/Location'
hours:
type: array
items:
$ref: '#/components/schemas/WorkingHours'
phoneNumber:
type: string
format: '[0-9]{10}'
description: 10-digit phone number
example: 5555555555
faxNumber:
type: string
format: '[0-9]{10}'
description: 10-digit fax number
example: 5555555555
distanceMi:
type: number
description: The driving distance to the location in miles
required:
- costScore
- distanceMi
- id
- location
- phoneNumber
- specialty
additionalProperties: false
description: A ranked provider
example:
id: p.f3ac4f1a01275ca68e6c932ad4722491
npi: 1231766309
firstName: Sepideh
lastName: Baghian
credentials: MD
gender: female
specialty: adult_general_gastroenterologist
languages:
- eng
- fas
metrics:
- id: accurately_diagnoses_gi_issues
value: very_good
- id: performs_safe_colonoscopies
value: excellent
- id: great_patient_outcomes
value: good
overallScore: 92
reviewStars: 4.5
location:
id: fc8b2f21-506c-5c7c-a96f-a4580bd9ba87
name: Mount Sinai Morningside Cardiovascular Institute
providerCorporationName: Mount Sinai Health System
allProviderCorporations:
- Mount Sinai Health System
- NYC Health + Hospitals
city: New York
lines:
- 440 W 114th St 2nd Fl Ste 220
position:
lat: 40.8053
lng: -73.9618
state: NY
zipCode: '10025'
hours:
- day: 1
open: 480
close: 1020
- day: 2
open: 480
close: 1020
- day: 3
open: 480
close: 1020
- day: 4
open: 480
close: 1020
- day: 5
open: 480
close: 1020
phoneNumber: '2124271540'
faxNumber: '2124107196'
distanceMi: 3.50453352288
ProviderDirectoryEntry:
type: object
properties:
id:
type: string
description: Unique identifier for the provider
npi:
type: string
description: National Provider Identifier
firstName:
type: string
description: First name of the provider.
lastName:
type: string
description: Last name of the provider.
credentials:
type: string
description: Degrees and certifications held by the provider. Only returned if provider is a professional rather than a facility
example: MD
gender:
$ref: '#/components/schemas/Gender'
specialty:
type: string
description: The specialty identifier for the provider
example: adult_general_gastroenterologist
networkStatus:
type: boolean
description: Whether the doctor is in-network with the network specified in the query parameters
languages:
type: array
items:
type: string
format: '[a-z]{3}'
description: List of languages spoken by the provider. Languages are [ISO639-3](https://iso639-3.sil.org/code_tables/639/data) codes. Only returned if provider is a professional rather than a facility
location:
$ref: '#/components/schemas/Location'
hours:
type: array
items:
$ref: '#/components/schemas/WorkingHours'
phoneNumber:
type: string
format: '[0-9]{10}'
description: 10-digit phone number
example: 5555555555
faxNumber:
type: string
format: '[0-9]{10}'
description: 10-digit phone number
example: 5555555555
distanceMi:
type: number
description: The driving distance to the location in miles
required:
- distanceMi
- id
- location
- phoneNumber
- specialty
additionalProperties: false
description: A ranked provider
example:
id: p.f3ac4f1a01275ca68e6c932ad4722491
npi: 1231766309
firstName: Sepideh
lastName: Baghian
credentials: MD
gender: female
specialty: adult_general_gastroenterologist
languages:
- eng
- fas
location:
id: fc8b2f21-506c-5c7c-a96f-a4580bd9ba87
name: Mount Sinai Morningside Cardiovascular Institute
providerCorporationName: Mount Sinai Health System
allProviderCorporations:
- Mount Sinai Health System
- NYC Health + Hospitals
city: New York
lines:
- 440 W 114th St 2nd Fl Ste 220
position:
lat: 40.8053
lng: -73.9618
state: NY
zipCode: '10025'
hours:
- day: 1
open: 480
close: 1020
- day: 2
open: 480
close: 1020
- day: 3
open: 480
close: 1020
- day: 4
open: 480
close: 1020
- day: 5
open: 480
close: 1020
phoneNumber: '2124271540'
faxNumber: '2124107196'
distanceMi: 3.50453352288
networkStatus: true
Gender:
type: string
enum:
- male
- female
description: Gender. Only returned if provider is a professional rather than a facility
RankedProviderQuery:
allOf:
- type: object
properties:
specialty:
type: string
description: Specialty code to query.
example: adult_general_gastroenterologist
networkId:
type: string
description: Filters results to a given carrier network when included.
gender:
type: string
enum:
- male
- female
description: Filters results to a given gender. If omitted, no gender filter will be applied.
language:
type: string
description: Filters results to require a given language to be spoken by the provider. If omitted, no language filter will be applied. Must be provided as a [ISO639-3](https://iso639-3.sil.org/code_tables/639/data) code.
example: fas
required:
- networkId
- $ref: '#/components/schemas/BaseQuery'
parameters:
acceptVersion:
name: Accept-Version
in: header
required: true
schema:
type: integer
enum:
- 1
description: The API major version.
securitySchemes:
ApiToken:
type: http
scheme: bearer
bearerFormat: API_TOKEN