Skip to content

Endpoint Capabilities

Retrieve the full FHIR CapabilityStatement and SMART configuration for any endpoint.

Request

GET /api/v1/endpoints/:id/capabilities

Response

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

FieldDescription
summaryQuick-access fields extracted from the raw responses
capabilityStatementThe full FHIR CapabilityStatement resource as returned by the server's /metadata endpoint
smartConfigurationThe full SMART App Launch configuration as returned by the server's /.well-known/smart-configuration endpoint

Probe Status

StatusMeaning
successBoth /metadata and /.well-known/smart-configuration returned data
partialOne of the two probes succeeded (e.g., /metadata works but SMART config returns 404)
failedBoth probes failed (server unreachable, auth required, etc.)
uncheckedEnrichment 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:

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,Observation

Returns only endpoints whose server supports all listed resource types (AND logic).

Filter by SMART support:

GET /api/v1/endpoints?smartSupported=true

Returns 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

Built by Luxera Software