Supplier Status Endpoint
Elexess aggregates results from participating supplier APIs. When a supplier is degraded or unreachable, callers can use two public endpoints to show partial availability or decide when to check again:
GET https://api.elexess.com/functions/v1/supplier-status
GET https://api.elexess.com/functions/v1/supplier-incidents?days=14
Authentication
- No authentication required.
- Responses are cacheable:
Cache-Control: public, max-age=30, s-maxage=60. - Safe to poll from client applications or server jobs.
Status semantics
Each supplier is classified every 2 minutes from the preceding 15-minute window of driver logs:
| Status | Criteria |
|---|---|
operational | success_rate_15m >= 0.9 OR sample_size_15m < 5 (low traffic) |
degraded | 0.5 <= success_rate_15m < 0.9 |
unavailable | success_rate_15m < 0.5 AND sample_size_15m >= 5 |
success_rate_15m = success / (success + error_service_unavailable) over the
15-minute window. Empty responses (success_empty_result) are excluded from
both numerator and denominator -- an empty response is a successful API call
that happened to have no hits for a given query. Rate-limited requests
(error_rate_limited) are excluded as well: the request quota for that
supplier was used up, so the supplier was not contacted and the request says
nothing about its availability.
GET /supplier-status
{
"as_of": "2026-04-21T12:34:00Z",
"snapshot_updated_at": "2026-04-21T12:34:00Z",
"snapshot_age_seconds": 42,
"is_stale": false,
"suppliers": [
{
"supplier": "Anglia",
"confidence": "recent",
"status": "unavailable",
"since": "2026-04-21T11:58:00Z",
"success_rate_15m": 0.12,
"sample_size_15m": 18,
"updated_at": "2026-04-21T12:34:00Z"
},
{
"supplier": "Mouser",
"confidence": "recent",
"status": "operational",
"since": "2026-04-21T08:00:00Z",
"success_rate_15m": 0.98,
"sample_size_15m": 42,
"updated_at": "2026-04-21T12:34:00Z"
}
]
}
sinceis the timestamp at which the current classification began. It is preserved when the classification is unchanged, so callers can display "down since HH:MM".- Only suppliers with a driver_key are included (sub-stores like Verical are represented by their parent driver, e.g. Arrow USA).
- The list is sorted alphabetically.
confidencesays how much weight to give the row'sstatus:recent-- classified within the last 5 minutes from at least 5 samples.insufficient-- classified within the last 5 minutes, but from fewer than 5 samples (sample_size_15m < 5), sooperationalmay just mean low traffic.stale-- the row'supdated_atis older than 5 minutes or invalid; the classification may be out of date.
Snapshot freshness
The status classifications are recomputed on a schedule, not on every request. The top-level fields let a caller reason about how current the data is, separately from the endpoint's own response time:
| Field | Meaning |
|---|---|
as_of | When this response was generated (server clock). |
snapshot_updated_at | Timestamp of the most recent valid classification across all listed suppliers, or null when none exists yet. |
snapshot_age_seconds | Seconds between snapshot_updated_at and now, or null when no snapshot exists. |
is_stale | true when the newest classification is older than 5 minutes or missing, or when any listed supplier's classification is older than 5 minutes or has no valid timestamp. A healthy pipeline refreshes every supplier well within that window. |
Treat is_stale = true as "the availability data may be out of date" rather
than "suppliers are down" -- it usually means the classification job has not
run recently. The /status page surfaces the same signal so viewers know when
they are looking at aged data.
GET /supplier-incidents?days=14
{
"as_of": "2026-04-21T12:34:00Z",
"days": 14,
"count": 3,
"incidents": [
{
"id": 42,
"supplier": "Anglia",
"opened_at": "2026-04-21T11:58:00Z",
"closed_at": null,
"duration_ms": null,
"peak_status": "unavailable",
"is_open": true
},
{
"id": 41,
"supplier": "TME",
"opened_at": "2026-04-19T03:12:00Z",
"closed_at": "2026-04-19T03:44:00Z",
"duration_ms": 1920000,
"peak_status": "unavailable",
"is_open": false
}
]
}
daysclamps to[1, 90]; invalid values fall back to14.- Incidents are ordered by
opened_atdescending. - Open incidents have
closed_at = nullandduration_ms = null. - Incidents open when a supplier flips to
unavailableand close after 5 minutes of sustainedoperational.
/search response parity
When stream=false (default), the Search Endpoint
response includes a supplier_statuses array that mirrors the per-request
outcome of each driver:
{
"searchterm": "LM358",
"result_count": 42,
"results": [...],
"supplier_statuses": [
{ "supplier": "Farnell", "status": "success", "count": 12, "runtime_ms": 342 },
{ "supplier": "Anglia", "status": "error_service_unavailable", "count": 0, "runtime_ms": 20003 },
{ "supplier": "Digi-Key", "status": "error_rate_limited", "count": 0, "runtime_ms": 25,
"rate_limit_window": "hour", "retry_after_ms": 12000 },
{ "supplier": "Mouser", "status": "success_empty_result", "count": 0, "runtime_ms": 430 }
]
}
status values come straight from DriverResult.status in the edge function,
so consumers can distinguish empty-but-healthy from unavailable:
| Status | Meaning |
|---|---|
success | Supplier returned results (count > 0) |
success_empty_result | Supplier reachable but returned zero matches |
error_service_unavailable | Supplier API returned 5xx, timed out, or connection failed |
error_rate_limited | The request quota for this supplier is used up, so the supplier was not contacted. rate_limit_window identifies the second, hour, or day allowance; retry_after_ms is included when the limiter supplies retry timing. |
error | Driver-side programmer error (rare) |
Consumers such as Beluga / ERPNext can render a per-supplier "Unavailable --
check webshop" marker when they see error_service_unavailable, and a neutral
"no results" marker otherwise. This is the same signal the SSE
supplier_result / supplier_empty events already carry in data.status.
Consumer examples
curl
curl https://api.elexess.com/functions/v1/supplier-status | jq '.suppliers[] | select(.status != "operational")'
JavaScript (Beluga / web client)
const res = await fetch("https://api.elexess.com/functions/v1/supplier-status");
const { suppliers } = await res.json();
const down = suppliers.filter((s) => s.status === "unavailable");
if (down.length > 0) {
console.warn(`Suppliers down: ${down.map((s) => s.supplier).join(", ")}`);
}
Frappe / ERPNext Dashboard Chart (Custom)
Point a Frappe Custom Dashboard Chart or HTML Block at
/functions/v1/supplier-status, poll every 60 seconds, and render a
colored-dot list. No server-side code required.
Related Endpoints
Observation confidence
Each supplier row includes confidence: recent, insufficient or stale.
An operational status with fewer than five observations in the last 15 minutes
is insufficient evidence of health. A snapshot older than five minutes is stale.
The page shows these operational rows as unverified, rather than a green health
claim. is_stale also accounts for individually delayed supplier rows.
Only enabled suppliers configured for public status are exposed. Successful
dispatch, a public ping or a lack of error reports does not establish health.