Appearance
Error Handling
All error responses use the same envelope format.
Error response format
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "page: Number must be greater than or equal to 1"
}
}Error codes
| HTTP Status | Code | When |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid parameters (unknown param, out of range, wrong type) |
| 404 | ENDPOINT_NOT_FOUND | Endpoint ID does not exist |
| 404 | NOT_FOUND | Route does not exist |
| 429 | TOO_MANY_REQUESTS | Rate limit exceeded — see Retry-After and RateLimit-* response headers |
| 500 | INTERNAL_ERROR | Unexpected server error |
Handling validation errors
The API uses strict parameter validation. Unknown parameters are rejected:
bash
# This returns 400 — "ehr" is not a valid parameter
curl "https://fhir-api.luxera.io/api/v1/endpoints?ehr=epic"
# Use "vendor" instead
curl "https://fhir-api.luxera.io/api/v1/endpoints?vendor=epic"python
import requests
# This returns 400 — "ehr" is not a valid parameter
response = requests.get(
"https://fhir-api.luxera.io/api/v1/endpoints",
params={"ehr": "epic"}
)
print(response.status_code) # 400
# Use "vendor" instead
response = requests.get(
"https://fhir-api.luxera.io/api/v1/endpoints",
params={"vendor": "epic"}
)
data = response.json()typescript
// This returns 400 — "ehr" is not a valid parameter
const bad = await fetch(
"https://fhir-api.luxera.io/api/v1/endpoints?ehr=epic"
);
console.log(bad.status); // 400
// Use "vendor" instead
const good = await fetch(
"https://fhir-api.luxera.io/api/v1/endpoints?vendor=epic"
);
const data = await good.json();csharp
using var client = new HttpClient();
// This returns 400 — "ehr" is not a valid parameter
var bad = await client.GetAsync(
"https://fhir-api.luxera.io/api/v1/endpoints?ehr=epic"
);
Console.WriteLine(bad.StatusCode); // BadRequest
// Use "vendor" instead
var good = await client.GetAsync(
"https://fhir-api.luxera.io/api/v1/endpoints?vendor=epic"
);
var data = await good.Content.ReadAsStringAsync();Rate limiting
When rate limited, the response includes headers:
RateLimit-Limit: 30
RateLimit-Remaining: 0
RateLimit-Reset: 1712361660
Retry-After: 45Wait for the Retry-After seconds before retrying.
Best practices
- Check
successfield — always checkresponse.successbefore accessingresponse.data - Handle 429 — implement exponential backoff or respect
Retry-After - Don't retry 400s — validation errors won't resolve with retries; fix the request
- Retry 500s — server errors are transient; retry with backoff