1. FHIR R4 / R4B / R5 / R6 Terminology Operations
The FHIR Terminology Service is served athttps://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 FHIRParameters.
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 isapps/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’sRemoteTerminologyServiceValidationSupport 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_IDon 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 referencehapi.fhir.validation.remote_terminology_service_urls, which is a different property path that the JPA Starter silently ignores
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 unknowntroubleshooting path
EHRbase (openEHR)
EHRbase delegates template-terminology validation to an external FHIR R4 server via Spring’sRemoteTerminologyServiceValidationSupport. 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.urltohttps://fhir.omophub.com/fhir/r4/ - Auth: OAuth2
client_credentials-spring.security.oauth2.client.registration.omophub.client-idset to your OMOPHub API key,client-secretto 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:nextwithapplication.ymloverlay - 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 fulltemplate upload → composition commit → $validate-code → rejectloop 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 (FHIRParameters 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 withnpx -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.