Skip to content
REST API

Supplier Status Endpoint

Current per-supplier availability and recent outage history.

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:

StatusCriteria
operationalsuccess_rate_15m >= 0.9 OR sample_size_15m < 5 (low traffic)
degraded0.5 <= success_rate_15m < 0.9
unavailablesuccess_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"
    }
  ]
}
  • since is 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.
  • confidence says how much weight to give the row's status:
    • 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), so operational may just mean low traffic.
    • stale -- the row's updated_at is 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:

FieldMeaning
as_ofWhen this response was generated (server clock).
snapshot_updated_atTimestamp of the most recent valid classification across all listed suppliers, or null when none exists yet.
snapshot_age_secondsSeconds between snapshot_updated_at and now, or null when no snapshot exists.
is_staletrue 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
    }
  ]
}
  • days clamps to [1, 90]; invalid values fall back to 14.
  • Incidents are ordered by opened_at descending.
  • Open incidents have closed_at = null and duration_ms = null.
  • Incidents open when a supplier flips to unavailable and close after 5 minutes of sustained operational.

/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:

StatusMeaning
successSupplier returned results (count > 0)
success_empty_resultSupplier reachable but returned zero matches
error_service_unavailableSupplier API returned 5xx, timed out, or connection failed
error_rate_limitedThe 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.
errorDriver-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.

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.