Skip to main content
This page documents what OMOPHub supports, what has been tested against real clients, and where the boundaries are. Use it to evaluate compatibility before writing integration code.

1. FHIR R4 / R4B / R5 / R6 Terminology Operations

The FHIR Terminology Service is served at https://fhir.omophub.com/fhir/{r4,r4b,r5,r6}/. R4 is the default when no version prefix is provided.

Not supported

2. OMOPHub Concept Resolver

Purpose-built REST endpoints for FHIR-to-OMOP ETL pipelines. Returns OMOPHub’s native JSON envelope rather than FHIR Parameters. See the FHIR Integration guide for request / response shapes and the FHIR → OMOP Standardization guide for the end-to-end pipeline pattern.

3. Supported FHIR Code System URIs

OMOPHub maps 19 canonical FHIR system URIs + 1 OMOP omnibus URL (total: 20 CodeSystems served via the Terminology Service). Source of truth is apps/api/src/config/fhir-vocabularies.ts - use GET /fhir/r4/metadata?mode=terminology to get the current list from the live service.
If your FHIR data uses a system URI not in this list, the Resolver returns a 400 error with an unknown_system code and a suggested match from the levenshtein-closest URI. You can bypass URI resolution by passing vocabulary_id directly instead of system.

4. Tested Client Scenarios

The following integration patterns have been validated against real clients.

HAPI FHIR Server

HAPI FHIR’s RemoteTerminologyServiceValidationSupport can delegate validation to OMOPHub. Two deployment shapes work, depending on whether you’re using the stock JPA Starter or building a custom Spring Boot HAPI app: HAPI JPA Starter (hapiproject/hapi:* Docker image) - the stock image’s YAML schema does not expose a Bearer-token field for remote terminology services (AppProperties.RemoteSystem in the starter only binds system and url; TerminologyConfig never calls addClientInterceptor). Use a reverse-proxy pattern:
  • Stand up nginx / Caddy / cloud gateway in front of OMOPHub
  • Configure the proxy to inject Authorization: Bearer $OMOPHUB_CLIENT_ID on every upstream request
  • Point HAPI’s remote terminology URL at the proxy
  • Config key: hapi.fhir.remote_terminology_service.<name>.{system,url} - note that older blog posts reference hapi.fhir.validation.remote_terminology_service_urls, which is a different property path that the JPA Starter silently ignores
Custom Spring Boot HAPI app - use the HAPI FHIR library directly and attach a BearerTokenAuthInterceptor programmatically:
  • Verified operations: $lookup, $validate-code, CodeSystem search-type (discovery call), GET /metadata
  • Verified against: HAPI FHIR 8.8.0
  • See: HAPI FHIR Integration for full config, verification checklist, and the CodeSystem is unknown troubleshooting path

EHRbase (openEHR)

EHRbase delegates template-terminology validation to an external FHIR R4 server via Spring’s RemoteTerminologyServiceValidationSupport. Unlike HAPI JPA Starter, EHRbase supports OAuth2 client_credentials natively via spring.security.oauth2.client.* config blocks - and OMOPHub exposes a compatible token endpoint at POST /oauth2/token.
  • Connection: Configure validation.external-terminology.provider.omophub.url to https://fhir.omophub.com/fhir/r4/
  • Auth: OAuth2 client_credentials - spring.security.oauth2.client.registration.omophub.client-id set to your OMOPHub API key, client-secret to any non-empty placeholder (OMOPHub’s shim doesn’t validate it)
  • Verified operations: ValueSet search-type (discovery), $expand, $validate-code, OAuth2 token exchange
  • Verified against: ehrbase/ehrbase:next with application.yml overlay
  • End-to-end test result: invalid SNOMED code submitted via composition → EHRbase returns HTTP 422 with "does not match any option from value set ..." - the full template upload → composition commit → $validate-code → reject loop is live
  • See: EHRbase / openEHR Integration for the complete docker-compose and template-binding walkthrough

Direct REST / curl

All FHIR operations support both GET (query parameters) and POST (FHIR Parameters body):

Python SDK

R SDK

R6 object-oriented style via $-dereferencing:

MCP Server (AI agents)

The OMOPHub MCP Server exposes 11 tools to Claude, Cursor, VS Code, and any MCP-compatible AI client. Install with npx -y @omophub/omophub-mcp. See AI Onboarding and the MCP Tools Reference for the full tool list.

5. Authentication

The OAuth2 shim is specifically designed to satisfy Spring Security OAuth2 clients (HAPI FHIR custom builds, EHRbase, any Java/Kotlin Spring Boot stack). The returned access_token is your API key wrapped in an RFC 6749 envelope - the token exchange is nominal but lets Spring-based clients treat OMOPHub like any other OAuth2-protected resource.

6. Content Negotiation

JSON wins on ties. Content negotiation follows RFC 7231 §5.3.2 q-value semantics; HAPI FHIR’s default client sends both JSON and XML at q=1.0, so the tie-break selects JSON. See the Content Type section of the FHIR Terminology Service overview for the full XML support matrix.

7. Rate Limits

FHIR endpoints share the same rate-limit and metering pool as the REST API. Each FHIR operation counts as one API call. Batch and bulk endpoints (POST /v1/fhir/resolve/batch, POST /fhir/r4/ batch Bundles, /v1/concepts/batch, /v1/search/bulk, and so on) meter per item inside the batch - a 100-item batch counts as 100 calls against your monthly quota. See Rate Limits for the headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset, ratelimit-window, retry-after) and the contact path for requesting higher limits.

8. Vocabulary Coverage

OMOPHub serves the full OHDSI ATHENA vocabulary set except licensed vocabularies. See Known Limitations for the full boundary discussion, and Vocabulary Releases for the current release cadence.