Appearance
Endpoint Capabilities
Retrieve the full FHIR CapabilityStatement and SMART configuration for any endpoint.
Request
GET /api/v1/endpoints/:id/capabilitiesResponse
json
{
"success": true,
"data": {
"endpointId": "abc123",
"url": "https://fhir-ehr.cerner.com/r4/tenant-uuid",
"vendorName": "Oracle Health (Cerner)",
"lastProbed": "2026-04-13T00:00:00Z",
"probeStatus": "success",
"summary": {
"fhirVersion": "4.0.1",
"softwareName": "Oracle Health",
"softwareVersion": "22.1",
"supportedResourceCount": 51,
"supportedResources": ["Patient", "Observation", "Condition", "..."],
"smartSupported": true,
"smartCapabilities": ["launch-ehr", "launch-standalone", "..."],
"grantTypes": ["authorization_code", "client_credentials"]
},
"capabilityStatement": { "...full /metadata response..." },
"smartConfiguration": { "...full /.well-known/smart-configuration response..." }
}
}Fields
| Field | Description |
|---|---|
summary | Quick-access fields extracted from the raw responses |
capabilityStatement | The full FHIR CapabilityStatement resource as returned by the server's /metadata endpoint |
smartConfiguration | The full SMART App Launch configuration as returned by the server's /.well-known/smart-configuration endpoint |
Probe Status
| Status | Meaning |
|---|---|
success | Both /metadata and /.well-known/smart-configuration returned data |
partial | One of the two probes succeeded (e.g., /metadata works but SMART config returns 404) |
failed | Both probes failed (server unreachable, auth required, etc.) |
unchecked | Enrichment has not run yet for this endpoint |
Data Formats
The capabilityStatement and smartConfiguration fields contain the raw, unmodified JSON from the server. These follow the official FHIR and SMART specifications:
- CapabilityStatement: HL7 FHIR R4 CapabilityStatement — describes supported resources, search parameters, operations, and security
- SMART Configuration: SMART App Launch Framework — describes OAuth2 endpoints, supported scopes, capabilities, and grant types
You can parse these with any FHIR client library (e.g., fhir.js, fhirclient, HAPI FHIR).
Filtering by Capabilities
You can filter the endpoint list by server capabilities without fetching each endpoint's full data:
Filter by supported resources:
GET /api/v1/endpoints?hasResource=Patient,ObservationReturns only endpoints whose server supports all listed resource types (AND logic).
Filter by SMART support:
GET /api/v1/endpoints?smartSupported=trueReturns only endpoints on servers that have a SMART configuration.
These filters can be combined with all existing filters (vendor, state, fhirVersion, etc.).
Use Cases
1. Enable/disable features based on supported resources
Before querying a FHIR server, check which resources it supports. Not all servers support the same set — an EHR might support Patient and Observation but not CareTeam.
bash
curl "https://fhir-api.luxera.io/api/v1/endpoints/abc123/capabilities"typescript
const resp = await fetch(
`https://fhir-api.luxera.io/api/v1/endpoints/${endpointId}/capabilities`
);
const { data } = await resp.json();
const supported = new Set(data.summary.supportedResources);
// Enable or disable features based on what the server offers
const features = {
patientDemographics: supported.has('Patient'),
labResults: supported.has('Observation') && supported.has('DiagnosticReport'),
medications: supported.has('MedicationRequest'),
allergies: supported.has('AllergyIntolerance'),
careTeam: supported.has('CareTeam'),
scheduling: supported.has('Appointment') && supported.has('Schedule'),
};
// Render your UI conditionally
if (features.labResults) {
showLabResultsTab();
}
if (!features.careTeam) {
hideCareTeamSection();
showUnsupportedMessage('Care Team data is not available from this provider.');
}python
import requests
resp = requests.get(
f"https://fhir-api.luxera.io/api/v1/endpoints/{endpoint_id}/capabilities"
)
capabilities = resp.json()["data"]
supported = set(capabilities["summary"]["supportedResources"])
# Check before making FHIR calls
if "Observation" in supported:
observations = fhir_client.search("Observation", patient=patient_id)
else:
print("This server does not support Observation resources")
# Build a feature flags dict
features = {
"lab_results": "Observation" in supported and "DiagnosticReport" in supported,
"medications": "MedicationRequest" in supported,
"care_team": "CareTeam" in supported,
}csharp
using System.Net.Http.Json;
var response = await httpClient.GetFromJsonAsync<ApiResponse>(
$"https://fhir-api.luxera.io/api/v1/endpoints/{endpointId}/capabilities"
);
var supported = new HashSet<string>(response.Data.Summary.SupportedResources);
// Enable or disable features based on what the server offers
var hasLabResults = supported.Contains("Observation") && supported.Contains("DiagnosticReport");
var hasMedications = supported.Contains("MedicationRequest");
var hasCareTeam = supported.Contains("CareTeam");
if (hasCareTeam)
EnableCareTeamFeature();
else
ShowUnsupportedMessage("Care Team data is not available from this provider.");2. Configure SMART OAuth connections dynamically
Use the SMART configuration to set up OAuth2 flows without hardcoding endpoints per vendor. Each server publishes its own authorization and token URLs.
bash
# Get the SMART config to discover OAuth2 endpoints
curl "https://fhir-api.luxera.io/api/v1/endpoints/abc123/capabilities" \
| jq '.data.smartConfiguration'typescript
const resp = await fetch(
`https://fhir-api.luxera.io/api/v1/endpoints/${endpointId}/capabilities`
);
const { data } = await resp.json();
if (!data.summary.smartSupported) {
console.warn('SMART not supported for this endpoint');
return;
}
const smartConfig = data.smartConfiguration;
const capabilities = new Set(data.summary.smartCapabilities);
// Discover what the server supports
const supportsStandaloneLaunch = capabilities.has('launch-standalone');
const supportsEhrLaunch = capabilities.has('launch-ehr');
const supportsPublicClients = capabilities.has('client-public');
const supportsPkce = smartConfig.code_challenge_methods_supported?.includes('S256');
// Configure your OAuth2 client dynamically
if (supportsStandaloneLaunch && supportsPublicClients) {
initStandaloneLaunch({
authorizationUrl: smartConfig.authorization_endpoint,
tokenUrl: smartConfig.token_endpoint,
clientId: MY_CLIENT_ID,
redirectUri: MY_REDIRECT_URI,
usePkce: supportsPkce,
});
}python
import requests
resp = requests.get(
f"https://fhir-api.luxera.io/api/v1/endpoints/{endpoint_id}/capabilities"
)
caps = resp.json()["data"]
smart = caps.get("smartConfiguration")
if not caps["summary"]["smartSupported"]:
raise Exception("SMART not supported for this endpoint")
# Build OAuth2 config from the server's published configuration
auth_url = smart["authorization_endpoint"]
token_url = smart["token_endpoint"]
grant_types = smart.get("grant_types_supported", [])
if "client_credentials" in grant_types:
# Backend service auth — no user interaction needed
token = request_client_credentials_token(token_url, client_id, client_secret)
elif "authorization_code" in grant_types:
# User-facing auth — redirect to authorization URL
redirect_to_auth(auth_url, scopes=["patient/*.read", "openid"])csharp
using System.Net.Http.Json;
var response = await httpClient.GetFromJsonAsync<ApiResponse>(
$"https://fhir-api.luxera.io/api/v1/endpoints/{endpointId}/capabilities"
);
var smart = response.Data.SmartConfiguration;
var summary = response.Data.Summary;
if (!summary.SmartSupported)
throw new InvalidOperationException("SMART not supported for this endpoint");
// Configure OAuth2 dynamically from the server's SMART config
var oauthOptions = new OAuthOptions
{
AuthorizationEndpoint = smart.AuthorizationEndpoint,
TokenEndpoint = smart.TokenEndpoint,
ClientId = Environment.GetEnvironmentVariable("SMART_CLIENT_ID"),
RedirectUri = "https://myapp.com/callback",
};
var capabilities = new HashSet<string>(summary.SmartCapabilities);
if (capabilities.Contains("launch-standalone") && capabilities.Contains("client-public"))
{
// Public standalone launch supported
await LaunchStandaloneAsync(oauthOptions);
}
else if (smart.GrantTypesSupported.Contains("client_credentials"))
{
// Backend service auth
var token = await GetClientCredentialsTokenAsync(oauthOptions);
}3. Request scopes dynamically
Different servers support different OAuth scopes. Use the SMART configuration to request only scopes the server actually supports.
bash
# See what scopes the server supports
curl "https://fhir-api.luxera.io/api/v1/endpoints/abc123/capabilities" \
| jq '.data.smartConfiguration.scopes_supported'typescript
const resp = await fetch(
`https://fhir-api.luxera.io/api/v1/endpoints/${endpointId}/capabilities`
);
const { data } = await resp.json();
const serverScopes = new Set(data.smartConfiguration?.scopes_supported ?? []);
// Your app wants these scopes — but only request what the server supports
const desiredScopes = [
'openid',
'profile',
'patient/Patient.read',
'patient/Observation.read',
'patient/MedicationRequest.read',
'patient/AllergyIntolerance.read',
'launch/patient',
'offline_access',
];
const requestedScopes = desiredScopes.filter(scope => {
if (scope === 'openid' || scope === 'profile') return true;
if (serverScopes.size === 0) return true; // Server didn't publish — request all
return serverScopes.has(scope);
});
console.log('Requesting scopes:', requestedScopes.join(' '));python
import requests
resp = requests.get(
f"https://fhir-api.luxera.io/api/v1/endpoints/{endpoint_id}/capabilities"
)
smart = resp.json()["data"].get("smartConfiguration", {})
server_scopes = set(smart.get("scopes_supported", []))
desired_scopes = [
"openid", "profile",
"patient/Patient.read",
"patient/Observation.read",
"patient/MedicationRequest.read",
"launch/patient",
"offline_access",
]
# Only request scopes the server actually supports
if server_scopes:
requested = [s for s in desired_scopes if s in server_scopes or s in ("openid", "profile")]
else:
requested = desired_scopes # Server didn't publish — try all
print(f"Requesting scopes: {' '.join(requested)}")csharp
using System.Net.Http.Json;
var response = await httpClient.GetFromJsonAsync<ApiResponse>(
$"https://fhir-api.luxera.io/api/v1/endpoints/{endpointId}/capabilities"
);
var serverScopes = new HashSet<string>(
response.Data.SmartConfiguration?.ScopesSupported ?? Array.Empty<string>()
);
var desiredScopes = new[]
{
"openid", "profile",
"patient/Patient.read",
"patient/Observation.read",
"patient/MedicationRequest.read",
"launch/patient",
"offline_access",
};
// Only request scopes the server supports
var requestedScopes = serverScopes.Count > 0
? desiredScopes.Where(s => serverScopes.Contains(s) || s is "openid" or "profile").ToList()
: desiredScopes.ToList();
Console.WriteLine($"Requesting scopes: {string.Join(" ", requestedScopes)}");4. Find endpoints that support specific workflows
Use the list filters to find endpoints that support your application's requirements.
bash
# Find endpoints that support Patient and Observation (for a lab results app)
curl "https://fhir-api.luxera.io/api/v1/endpoints?hasResource=Patient,Observation&limit=10"
# Find SMART-enabled endpoints in California
curl "https://fhir-api.luxera.io/api/v1/endpoints?smartSupported=true&state=CA&limit=10"
# Find Epic endpoints with Appointment support
curl "https://fhir-api.luxera.io/api/v1/endpoints?vendor=epic&hasResource=Appointment&limit=10"typescript
// Find lab-capable endpoints
const labEndpoints = await fetch(
'https://fhir-api.luxera.io/api/v1/endpoints?hasResource=Patient,Observation&limit=50'
).then(r => r.json());
console.log(`Found ${labEndpoints.meta.total} endpoints with Patient + Observation support`);
// Find SMART-enabled endpoints for a specific vendor
const smartEpic = await fetch(
'https://fhir-api.luxera.io/api/v1/endpoints?vendor=epic&smartSupported=true&limit=50'
).then(r => r.json());
console.log(`Found ${smartEpic.meta.total} SMART-enabled Epic endpoints`);python
import requests
# Find endpoints that support scheduling workflows
resp = requests.get("https://fhir-api.luxera.io/api/v1/endpoints", params={
"hasResource": "Appointment,Schedule,Patient",
"smartSupported": "true",
"limit": 50,
})
data = resp.json()
print(f"Found {data['meta']['total']} scheduling-capable SMART endpoints")
for ep in data["data"]:
print(f" {ep['organizationName']} ({ep['vendorName']})")csharp
using System.Net.Http.Json;
// Find SMART-enabled endpoints in New York
var url = "https://fhir-api.luxera.io/api/v1/endpoints"
+ "?smartSupported=true&state=NY&hasResource=Patient&limit=50";
var response = await httpClient.GetFromJsonAsync<EndpointListResponse>(url);
Console.WriteLine($"Found {response.Meta.Total} SMART-enabled endpoints in NY");
foreach (var ep in response.Data)
Console.WriteLine($" {ep.OrganizationName} ({ep.VendorName})");Further Reading
- FHIR R4 CapabilityStatement — full specification for the
/metadataresponse - SMART App Launch Framework — the SMART on FHIR authorization specification
- SMART Conformance — details on
/.well-known/smart-configuration - FHIR Resource Types — list of all FHIR resource types
- SMART Scopes — how scopes work in SMART on FHIR