Vitals Vault
What We TestLabor DaySALEMulti-Cancer Signal ScreeningNEWHow it WorksPlatform FeaturesGifts
120+–160+ biomarkers·Partner lab testing·HSA/FSA eligible·Results in days
Unlock Your Plan →

Developers

Vitals Vault API Reference

Vitals Vault Educational API

Version 1.0.0 · OpenAPI 3.0

Developer portal · OpenAPI 3.0 JSON

Public API for accessing educational biomarker information, lab packages, and health insights.

Overview

This API provides comprehensive educational content about biomarkers, their optimal ranges, and related health information. It is designed for mobile applications and web platforms that need to display biomarker educational content.

Key Features

Comprehensive biomarker database with 100+ markers Optimal ranges by age and gender Nutrition and testing guidelines Lab package information User-generated content (stories and Q&A) Search and trending functionality

Authentication

Most endpoints are public and do not require authentication or an API key. Admin endpoints require an operator-issued bearer token restricted to the admin endpoints; not part of the public surface. Partner access to patient data goes through the separate FHIR R4 rail, which uses OAuth 2.0 authorization code + PKCE with per-resource scopes (`patient/Patient.rs`, `patient/Observation.rs`, `patient/DiagnosticReport.rs`); see the `PartnerOAuth2` security scheme and https://www.vitalsvault.com/developers. The FHIR rail is enabled per environment and may be disabled on production.

Rate Limiting

Public Educational API GET endpoints share one budget of 100 requests per 15 minutes by default per client (IP), enforced across all servers. Exceeding the limit returns HTTP 429 with a Retry-After header and X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

Response Format

All responses follow a consistent format with `success`, `data`, and optional `error` fields. Error responses also implement RFC 9457 `application/problem+json` (`type`, `title`, `status`, `detail`, `instance`) while keeping `success: false` and `error: { code, message }` for existing clients.

Versioning

The public surface is URL-versioned at `/api/v1`. Breaking changes ship as a new path prefix (`/api/v2`) with at least six months of notice. Deprecated routes send `Deprecation` and `Sunset` headers. Policy: https://www.vitalsvault.com/developers/versioning

Execution Model

All public Educational API operations are synchronous and return a final response in the same HTTP request. Follow the pagination parameters declared by each operation: the biomarker list supports cursor parameters in addition to `page` and `pageSize`, while category and lab-package lists declare `page` and `pageSize`. `POST /api/v1/biomarkers/batch` accepts at most 50 biomarker slugs. The public API does not expose asynchronous jobs, `202 Accepted` status URLs, or polling endpoints.

POST operations accept an optional `Idempotency-Key` header. The batch biomarker endpoint replays a stored response when the same key and body are sent again within 24 hours.

Servers

  • https://www.vitalsvault.comProduction

Authentication and scopes

Each operation lists its scheme as a short Auth line. Admin operations use BearerAuth; biomarker and lab-package operations are public (Auth: none). An omitted security list inherits the document-level requirement; an explicit empty list means the operation is public.

BearerAuth

Type: http

Used by: GET /api/v1/admin/performance, DELETE /api/v1/admin/performance

An operator-issued bearer token; not part of the public surface. Restricted to the admin endpoints.

PartnerOAuth2

Type: oauth2

No operations in this specification declare this scheme.

Partner OAuth 2.0 for the FHIR R4 rail. Authorization code with PKCE (S256). The partner's back channel initiates the handshake by pushing an authorization request to `/api/oauth/par` authenticated with the application's `vvfhir_` bearer credential (partner identity token and a PKCE S256 code challenge) and receives a `request_id`; this is a proprietary back-channel init, not RFC 9126 `request_uri`. The member is sent to `/oauth/authorize` with `client_id` and `request_id` and approves on the Vitals Vault consent screen. The code is redeemed at `/api/oauth/token` (authorization_code + PKCE `code_verifier`, or a signed JWT client assertion for the attested exchange); refresh uses `refresh_token`; revoke at `/api/oauth/revoke`. Every access token is scoped: the scopes granted are the intersection of the partner organisation licence, the registered application's allowed scopes, and what the patient consented to. Requesting a scope above that ceiling is rejected with `invalid_scope`. The handshake is documented for approved partners in the partner portal and is not a generic RFC 8414 / RFC 9126 server. Production availability is per partner agreement; the sandbox environment is available to approved partners.

ScopeDescription
patient/Patient.rsRead and search the consenting patient's FHIR Patient resource
patient/Observation.rsRead and search lab Observations for the consenting patient
patient/DiagnosticReport.rsRead and search DiagnosticReports for the consenting patient

PartnerClientSecret

Type: http

No operations in this specification declare this scheme.

Partner application credential (`vvfhir_` secret issued per registered application) used on the back channel only: pushed authorization requests (`/api/oauth/par`), the token endpoint (`/api/oauth/token` — the legacy arm authenticates with the same `vvfhir_` bearer), and token revocation (`/api/oauth/revoke`). Each credential is bound to one application and one environment (sandbox or production) and inherits that application's allowed scopes.

Contents

  • Biomarker Categories
    • GET /api/v1/biomarkers/categoriesList biomarker categories
    • GET /api/v1/biomarkers/categories/{slug}Get category details
  • Biomarkers
    • GET /api/v1/biomarkersList biomarkers
    • POST /api/v1/biomarkers/batchBatch biomarker lookup
    • GET /api/v1/biomarkers/searchSearch biomarkers
    • GET /api/v1/biomarkers/trendingGet trending biomarkers
    • GET /api/v1/biomarkers/{slug}Get biomarker details
  • Lab Packages
    • GET /api/v1/lab-packagesList lab packages
    • GET /api/v1/lab-packages/{slug}Get lab package details
  • User Content
    • GET /api/v1/biomarkers/{slug}/storiesGet user stories for a biomarker
    • GET /api/v1/biomarkers/{slug}/questionsGet Q&A for a biomarker
  • Admin
    • GET /api/v1/admin/performanceGet performance statistics
    • DELETE /api/v1/admin/performanceClear cache

Biomarker Categories

Operations related to biomarker categories

GET/api/v1/biomarkers/categories

Auth: none (public)

List biomarker categories

Get a paginated list of all biomarker categories

Parameters

NameInRequiredTypeConstraintsDescription
pagequerynointeger
  • default: 1
  • min: 1
Page number for pagination
pageSizequerynointeger
  • default: 20
  • min: 1
  • max: 100
Number of items per page
sortByquerynostring—Field to sort by
sortOrderquerynostring
  • one of: asc, desc
  • default: asc
Sort order

Responses

StatusDescription
200Successfully retrieved categories
400Bad request
500Internal server error

GET/api/v1/biomarkers/categories/{slug}

Auth: none (public)

Get category details

Get detailed information about a specific biomarker category

Parameters

NameInRequiredTypeConstraintsDescription
slugpathyesstring—Category slug

Responses

StatusDescription
200Successfully retrieved category
404Resource not found
500Internal server error

Biomarkers

Operations related to individual biomarkers

GET/api/v1/biomarkers

Auth: none (public)

List biomarkers

Get a paginated list of biomarkers with optional filtering

Parameters

NameInRequiredTypeConstraintsDescription
pagequerynointeger
  • default: 1
  • min: 1
Page number for pagination
pageSizequerynointeger
  • default: 20
  • min: 1
  • max: 100
Number of items per page
limitquerynointeger
  • min: 1
  • max: 100
Alias for pageSize (cursor-friendly clients)
cursorquerynostring—Opaque cursor from a previous next_cursor; takes precedence over page
sortByquerynostring—Field to sort by
sortOrderquerynostring
  • one of: asc, desc
  • default: asc
Sort order
searchquerynostring—Search query
fieldsquerynostring—Comma-separated list of fields to return, or 'minimal'/'card' for predefined sets
categoryquerynostring—Filter by category slug
genderquerynostring
  • one of: male, female
Filter by applicable gender
hasJunctionMappingquerynoboolean—Filter biomarkers with Junction Health integration
inPackagesquerynostring—Comma-separated list of package slugs

Responses

StatusDescription
200Successfully retrieved biomarkers
400Bad request
429Rate limit exceeded
500Internal server error

POST/api/v1/biomarkers/batch

Auth: none (public)

Batch biomarker lookup

Fetch up to 50 biomarkers by slug in one request. Optional Idempotency-Key replays the original response for 24 hours.

Parameters

NameInRequiredTypeConstraintsDescription
Idempotency-Keyheadernostring
  • minLength: 1
  • maxLength: 256
Optional replay key for POST operations. The same key and body return the original response for 24 hours.

Request body

Required. Content types: application/json.

object { slugs }
PropertyTypeConstraintsDescription
slugs *array of string
  • items: string

Responses

StatusDescription
200Batch lookup result. Missing slugs are returned as null in the same order.
400Bad request
429Rate limit exceeded
500Internal server error

GET/api/v1/biomarkers/search

Auth: none (public)

Search biomarkers

Full-text search across biomarker names, summaries, and significance

Parameters

NameInRequiredTypeConstraintsDescription
qqueryyesstring
  • minLength: 2
Search query
categoryquerynostring—Filter by category slug
genderquerynostring
  • one of: male, female
Filter by applicable gender
limitquerynointeger
  • default: 10
  • min: 1
  • max: 50
Maximum number of results

Responses

StatusDescription
200Successfully searched biomarkers
400Bad request
500Internal server error

GET/api/v1/biomarkers/trending

Auth: none (public)

Get trending biomarkers

Get biomarkers with highest trending scores based on views and searches

Parameters

NameInRequiredTypeConstraintsDescription
limitquerynointeger
  • default: 10
  • min: 1
  • max: 20
Number of trending biomarkers to return
timeframequerynostring
  • one of: day, week, month
  • default: week
Timeframe for trending calculation

Responses

StatusDescription
200Successfully retrieved trending biomarkers
500Internal server error

GET/api/v1/biomarkers/{slug}

Auth: none (public)

Get biomarker details

Get comprehensive information about a specific biomarker

Parameters

NameInRequiredTypeConstraintsDescription
slugpathyesstring—Biomarker slug
includequerynostring—Comma-separated list of related data to include

Responses

StatusDescription
200Successfully retrieved biomarker
404Resource not found
500Internal server error

Lab Packages

Lab test packages and bundles

GET/api/v1/lab-packages

Auth: none (public)

List lab packages

Get a paginated list of available lab test packages

Parameters

NameInRequiredTypeConstraintsDescription
pagequerynointeger
  • default: 1
  • min: 1
Page number for pagination
pageSizequerynointeger
  • default: 20
  • min: 1
  • max: 100
Number of items per page
sortByquerynostring—Field to sort by
sortOrderquerynostring
  • one of: asc, desc
  • default: asc
Sort order
searchquerynostring—Search query
categoryquerynostring—Filter by category focus
conditionquerynostring—Filter by target condition
minPricequerynonumber
  • format: float
  • min: 0
Minimum price filter
maxPricequerynonumber
  • format: float
Maximum price filter
sampleTypequerynostring
  • one of: blood, urine, saliva, stool
Filter by sample type
isActivequerynoboolean—Filter by active status

Responses

StatusDescription
200Successfully retrieved lab packages
400Bad request
500Internal server error

GET/api/v1/lab-packages/{slug}

Auth: none (public)

Get lab package details

Get detailed information about a specific lab package including biomarkers

Parameters

NameInRequiredTypeConstraintsDescription
slugpathyesstring—Lab package slug
includeBiomarkersquerynoboolean
  • default: true
Include full biomarker details

Responses

StatusDescription
200Successfully retrieved lab package
404Resource not found
500Internal server error

User Content

User-generated content like stories and Q&A

GET/api/v1/biomarkers/{slug}/stories

Auth: none (public)

Get user stories for a biomarker

Get approved user stories and experiences related to a biomarker

Parameters

NameInRequiredTypeConstraintsDescription
slugpathyesstring—Biomarker slug
pagequerynointeger
  • default: 1
  • min: 1
Page number for pagination
pageSizequerynointeger
  • default: 20
  • min: 1
  • max: 100
Number of items per page
sortByquerynostring
  • one of: recent, helpful
  • default: recent
Sort order for stories

Responses

StatusDescription
200Successfully retrieved stories
404Resource not found
500Internal server error

GET/api/v1/biomarkers/{slug}/questions

Auth: none (public)

Get Q&A for a biomarker

Get approved questions and answers about a biomarker

Parameters

NameInRequiredTypeConstraintsDescription
slugpathyesstring—Biomarker slug
pagequerynointeger
  • default: 1
  • min: 1
Page number for pagination
pageSizequerynointeger
  • default: 20
  • min: 1
  • max: 100
Number of items per page
categoryquerynostring
  • one of: general, testing, interpretation, improvement, medical
Filter by question category
featuredquerynoboolean—Show only featured questions

Responses

StatusDescription
200Successfully retrieved questions
404Resource not found
500Internal server error

Admin

Administrative operations

GET/api/v1/admin/performance

Auth: BearerAuth

Get performance statistics

Retrieve detailed performance metrics including database queries, cache stats, and memory usage

Responses

StatusDescription
200Successfully retrieved performance statistics
401Unauthorized
500Internal server error

DELETE/api/v1/admin/performance

Auth: BearerAuth

Clear cache

Clear various cache layers

Parameters

NameInRequiredTypeConstraintsDescription
targetquerynostring
  • one of: cache, all
  • default: all
Cache target to clear

Responses

StatusDescription
200Successfully cleared cache
401Unauthorized
500Internal server error