API reference

Backhauls

Backhaul links: endpoints, capacity, usage and cross-link pings

List backhauls

GET /v1/backhauls Try it

Your backhaul links: the router and radio at each end, the capacity Swift Fox uses for the link and where it comes from (fixed by hand, bandwidth tests or the radios), the latest traffic, the latest ping across the link, and alert_state: ok, recovering (alerted recently but back to good), or the severity of the worst open issue. Filter by site or region (matching any end) or search names with q. While ping monitoring is on, backhauls are pinged router to router almost continuously, so get_backhaul_history (series pings) has detailed history. Directions are named for the link's ends: ap_to_su is toward the SU end (down) and su_to_ap is from the SU end (up). The ap_router/ap_radio and su_router/su_radio objects say which devices those ends are.

Parameters

  • isp string query

    ISP code from GET /isps. Optional when the key reaches exactly one ISP.

  • site integer or string query

    Restrict to backhauls with any end at this site: site_id or site code

  • region integer query

    Restrict to backhauls with any end in this region: region_id from list_regions

  • q string query

    Substring match on backhaul name

  • limit integer query

    Max rows (default 100, max 300)

  • cursor string query

    next_cursor from the previous page

Response

Also available as CSV: add format=csv. Columns follow the field order below, with nested fields as dotted columns (ap.name).

Paged: pass next_cursor back as cursor for the next page.

  • count integer
  • next_cursor string nullable

    Pass as cursor to get the next page; null on the last page

  • backhauls array of objects
    Each item: 13 fields
    • bhid integer
    • name string
    • link_type string

      e.g. wireless, wired

    • ap_router object nullable

      The router at the AP end

      3 fields
      • infid integer
      • name string
      • site object nullable

        The site

        3 fields
        • site_id integer
        • code string

          The ISP's short site code

        • name string
    • su_router object nullable

      The router at the SU end

      3 fields
      • infid integer
      • name string
      • site object nullable

        The site

        3 fields
        • site_id integer
        • code string

          The ISP's short site code

        • name string
    • ap_radio object nullable

      The radio at the AP end

      3 fields
      • infid integer
      • name string
      • site object nullable

        The site

        3 fields
        • site_id integer
        • code string

          The ISP's short site code

        • name string
    • su_radio object nullable

      The radio at the SU end

      3 fields
      • infid integer
      • name string
      • site object nullable

        The site

        3 fields
        • site_id integer
        • code string

          The ISP's short site code

        • name string
    • capacity object
      3 fields
      • source string

        Where the capacity figure comes from: fixed (set by hand), tcptest (bandwidth tests) or wireless (the radios' link rate)

      • current_mbps object nullable

        The capacity Swift Fox uses now: the fixed figure, or the latest measurement

        2 fields
        • ap_to_su number nullable
        • su_to_ap number nullable
      • measured_at date-time nullable

        When current_mbps was measured; null when it's fixed

    • traffic_mbps object nullable

      Latest traffic across the link (Mbps)

      2 fields
      • ap_to_su number nullable
      • su_to_ap number nullable
    • speedtest_enabled boolean
    • ping_enabled boolean
    • ping object nullable

      Latest cross-link ping; null when ping monitoring is off or has no data

      2 fields
      • latency_ms number
      • loss_pct number
    • alert_state one of: "ok", "recovering", "info", "warning", "outage", "critical"

      ok (no issues), recovering (alerted recently, back to good), or the worst open issue's severity

Example

curl -H "Authorization: Bearer $SWIFTFOX_KEY" \
  "https://api.swiftfox.net/v1/backhauls?isp=yourisp"

Response (example data):

{
  "count": 1,
  "next_cursor": null,
  "backhauls": [
    {
      "bhid": 12,
      "name": "RB-HT",
      "link_type": "wireless",
      "ap_router": {
        "infid": 101,
        "name": "Core Router",
        "site": {
          "site_id": 3,
          "code": "RB-CORE",
          "name": "Riverbend Data Centre"
        }
      },
      "su_router": {
        "infid": 214,
        "name": "Hilltop Router",
        "site": {
          "site_id": 7,
          "code": "HT",
          "name": "Hilltop Tower"
        }
      },
      "ap_radio": {
        "infid": 215,
        "name": "RB-HT AP",
        "site": {
          "site_id": 3,
          "code": "RB-CORE",
          "name": "Riverbend Data Centre"
        }
      },
      "su_radio": {
        "infid": 216,
        "name": "RB-HT SU",
        "site": {
          "site_id": 7,
          "code": "HT",
          "name": "Hilltop Tower"
        }
      },
      "capacity": {
        "source": "tcptest",
        "current_mbps": {
          "ap_to_su": 612.4,
          "su_to_ap": 598.1
        },
        "measured_at": "2026-10-08T22:06:26Z"
      },
      "traffic_mbps": {
        "ap_to_su": 534.2,
        "su_to_ap": 38.2
      },
      "speedtest_enabled": true,
      "ping_enabled": true,
      "ping": {
        "latency_ms": 1.12,
        "loss_pct": 0
      },
      "alert_state": "warning"
    }
  ]
}

Get a backhaul

GET /v1/backhauls/{bhid} Try it

Everything about one backhaul: the router and radio at each end, how its capacity is set and each source's latest reading (the bandwidth test's, with the traffic during the test, and the radios'), the latest traffic, ping across the link, and open issues. A router end's speedtest_ip is the address bandwidth tests and link pings use on that end, not a management address; each end's ip is the device's own address. History: get_backhaul_history with series pings, traffic or capacity. Directions are named for the link's ends: ap_to_su is toward the SU end (down) and su_to_ap is from the SU end (up). The ap_router/ap_radio and su_router/su_radio objects say which devices those ends are.

Parameters

  • bhid integer path required

    Backhaul id from list_backhauls

  • isp string query

    ISP code from GET /isps. Optional when the key reaches exactly one ISP.

Response

  • bhid integer
  • name string
  • link_type string
  • ap_router object nullable

    The router at the AP end

    8 fields
    • infid integer
    • name string
    • site object nullable

      The site

      3 fields
      • site_id integer
      • code string

        The ISP's short site code

      • name string
    • ip string nullable
    • hardware_type object nullable

      The kind of device, which decides how Swift Fox collects from it

      2 fields
      • id string

        e.g. mikrotik, ubiquiti, cambium, snmp (any standard-SNMP device), generic

      • name string

        As the app shows it

    • model string nullable
    • interface string nullable

      The backhaul's interface on this router

    • speedtest_ip string nullable

      The address bandwidth tests and link pings target on this end; not a management address

  • su_router object nullable

    The router at the SU end

    8 fields
    • infid integer
    • name string
    • site object nullable

      The site

      3 fields
      • site_id integer
      • code string

        The ISP's short site code

      • name string
    • ip string nullable
    • hardware_type object nullable

      The kind of device, which decides how Swift Fox collects from it

      2 fields
      • id string

        e.g. mikrotik, ubiquiti, cambium, snmp (any standard-SNMP device), generic

      • name string

        As the app shows it

    • model string nullable
    • interface string nullable

      The backhaul's interface on this router

    • speedtest_ip string nullable

      The address bandwidth tests and link pings target on this end; not a management address

  • ap_radio object nullable

    The radio at the AP end

    6 fields
    • infid integer
    • name string
    • site object nullable

      The site

      3 fields
      • site_id integer
      • code string

        The ISP's short site code

      • name string
    • ip string nullable
    • hardware_type object nullable

      The kind of device, which decides how Swift Fox collects from it

      2 fields
      • id string

        e.g. mikrotik, ubiquiti, cambium, snmp (any standard-SNMP device), generic

      • name string

        As the app shows it

    • model string nullable
  • su_radio object nullable

    The radio at the SU end

    6 fields
    • infid integer
    • name string
    • site object nullable

      The site

      3 fields
      • site_id integer
      • code string

        The ISP's short site code

      • name string
    • ip string nullable
    • hardware_type object nullable

      The kind of device, which decides how Swift Fox collects from it

      2 fields
      • id string

        e.g. mikrotik, ubiquiti, cambium, snmp (any standard-SNMP device), generic

      • name string

        As the app shows it

    • model string nullable
  • capacity object
    6 fields
    • source string

      Where the capacity figure comes from: fixed (set by hand), tcptest (bandwidth tests) or wireless (the radios' link rate)

    • current_mbps object nullable

      The capacity Swift Fox uses now: the fixed figure, or the latest measurement

      2 fields
      • ap_to_su number nullable
      • su_to_ap number nullable
    • measured_at date-time nullable

      When current_mbps was measured; null when it's fixed

    • fixed_mbps object nullable

      The figure set by hand (used when source is fixed)

      2 fields
      • ap_to_su number nullable
      • su_to_ap number nullable
    • tcptest object nullable

      The latest bandwidth test

      4 fields
      • ap_to_su_mbps number nullable
      • su_to_ap_mbps number nullable
      • used_during_test_mbps object nullable

        Traffic already on the link while the test ran

        2 fields
        • ap_to_su number nullable
        • su_to_ap number nullable
      • at date-time nullable
    • wireless object nullable

      The radios' latest link rate

      3 fields
      • ap_to_su_mbps number nullable
      • su_to_ap_mbps number nullable
      • as_of date-time nullable
  • traffic_mbps object nullable

    Latest traffic across the link (Mbps)

    3 fields
    • ap_to_su number nullable
    • su_to_ap number nullable
    • as_of date-time nullable
  • speedtest_enabled boolean
  • speedtest_streams integer nullable

    TCP streams per bandwidth test

  • ping object nullable
    3 fields
    • latency_ms number
    • loss_pct number nullable
    • recent_avg_latency_ms number
  • issues array of objects
    Each item: 7 fields
    • metric string
    • details string
    • severity one of: "ok", "info", "warning", "outage", "critical"

      ok while recovering, otherwise info, warning, outage or critical

    • since date-time nullable

      When the issue started

    • status one of: "active", "pending", "recovering"
    • recovered_at date-time nullable

      recovering only: when the metric went back to good

    • resolves_at date-time nullable

      recovering only: when the issue clears if it stays good

Example

curl -H "Authorization: Bearer $SWIFTFOX_KEY" \
  "https://api.swiftfox.net/v1/backhauls/42?isp=yourisp"

Response (example data):

{
  "bhid": 12,
  "name": "RB-HT",
  "link_type": "wireless",
  "ap_router": {
    "infid": 101,
    "name": "Core Router",
    "site": {
      "site_id": 3,
      "code": "RB-CORE",
      "name": "Riverbend Data Centre"
    },
    "ip": "10.10.0.1",
    "hardware_type": {
      "id": "mikrotik",
      "name": "Mikrotik"
    },
    "model": "CCR2116-12G-4S+",
    "interface": "sfp1-HT",
    "speedtest_ip": "10.10.250.1"
  },
  "su_router": {
    "infid": 214,
    "name": "Hilltop Router",
    "site": {
      "site_id": 7,
      "code": "HT",
      "name": "Hilltop Tower"
    },
    "ip": "10.10.7.1",
    "hardware_type": {
      "id": "mikrotik",
      "name": "Mikrotik"
    },
    "model": "CCR2004-16G-2S+",
    "interface": "sfp1-RB",
    "speedtest_ip": "10.10.250.2"
  },
  "ap_radio": {
    "infid": 215,
    "name": "RB-HT AP",
    "site": {
      "site_id": 3,
      "code": "RB-CORE",
      "name": "Riverbend Data Centre"
    },
    "ip": "10.10.250.10",
    "hardware_type": {
      "id": "ubiquiti",
      "name": "Ubiquiti"
    },
    "model": "airFiber 60 LR"
  },
  "su_radio": {
    "infid": 216,
    "name": "RB-HT SU",
    "site": {
      "site_id": 7,
      "code": "HT",
      "name": "Hilltop Tower"
    },
    "ip": "10.10.250.11",
    "hardware_type": {
      "id": "ubiquiti",
      "name": "Ubiquiti"
    },
    "model": "airFiber 60 LR"
  },
  "capacity": {
    "source": "tcptest",
    "current_mbps": {
      "ap_to_su": 612.4,
      "su_to_ap": 598.1
    },
    "measured_at": "2026-10-08T22:06:26Z",
    "fixed_mbps": null,
    "tcptest": {
      "ap_to_su_mbps": 612.4,
      "su_to_ap_mbps": 598.1,
      "used_during_test_mbps": {
        "ap_to_su": 498.3,
        "su_to_ap": 35.6
      },
      "at": "2026-10-08T22:06:25Z"
    },
    "wireless": {
      "ap_to_su_mbps": 1850,
      "su_to_ap_mbps": 1850,
      "as_of": "2026-10-08T22:09:40Z"
    }
  },
  "traffic_mbps": {
    "ap_to_su": 534.2,
    "su_to_ap": 38.2,
    "as_of": "2026-10-08T22:09:45Z"
  },
  "speedtest_enabled": true,
  "speedtest_streams": 3,
  "ping": {
    "latency_ms": 1.08,
    "loss_pct": 0,
    "recent_avg_latency_ms": 1.12
  },
  "issues": [
    {
      "metric": "Backhaul:Usage Percent Down",
      "details": "Warning - 87.2% down used - 534 / 612 mbit",
      "severity": "warning",
      "since": "2026-10-08T21:55:03Z",
      "status": "active",
      "recovered_at": null,
      "resolves_at": null
    }
  ]
}

Get a backhaul's health

GET /v1/backhauls/{bhid}/health Try it

The live monitored metrics for one device, backhaul or CPE: each metric's latest value and unit, its threshold state and severity, and any open issue. It's the same list as get_device's health, for backhauls and CPEs too. For devices, entries with has_history have history in get_device_history (series = the metric name). An issue's status is active (alerting now), pending (alerting, but still inside its grace period, so not alert-worthy yet) or recovering (back to good, but held open a while in case it comes back: recovered_at is when it went good, and resolves_at is when it clears if it stays good).

Parameters

  • bhid integer path required

    infid / bhid / cpeid

  • isp string query

    ISP code from GET /isps. Optional when the key reaches exactly one ISP.

Response

Also available as CSV: add format=csv. Columns follow the field order below, with nested fields as dotted columns (ap.name).

  • type string

    device, backhaul or cpe; more types may be added

  • id integer
  • metrics array of objects
    Each item: 10 fields
    • metric string
    • sub string optional

      Which value of a metric with several on one entity (a radio chain, a vulnerability)

    • description string optional
    • value number nullable

      Latest collected value

    • unit string optional
    • state string

      Threshold state name for the value, e.g. Good, Warning, Down; Inactive = the metric has no thresholds set

    • severity one of: "ok", "info", "warning", "outage", "critical" nullable

      ok, info, warning, outage or critical for the state's level; null when the metric has no thresholds

    • value_ttl_seconds integer nullable

      Seconds until the value is considered stale; -1 = no expiry set

    • issue object nullable
      6 fields
      • details string
      • severity one of: "ok", "info", "warning", "outage", "critical"

        ok while recovering, otherwise info, warning, outage or critical

      • since date-time nullable

        When the issue started

      • status one of: "active", "pending", "recovering"
      • recovered_at date-time nullable

        recovering only: when the metric went back to good

      • resolves_at date-time nullable

        recovering only: when the issue clears if it stays good

    • has_history boolean optional

      Devices: true when the metric's history is available (REST: /devices/{infid}/history/{metric})

Example

curl -H "Authorization: Bearer $SWIFTFOX_KEY" \
  "https://api.swiftfox.net/v1/backhauls/42/health?isp=yourisp"

Response (example data):

{
  "type": "backhaul",
  "id": 12,
  "metrics": [
    {
      "metric": "Backhaul:Ping Loss",
      "description": "The percentage packet loss from a high-res ping test between routers on each side of a backhaul",
      "value": 0,
      "unit": "%",
      "state": "Good",
      "severity": "ok",
      "value_ttl_seconds": 604798,
      "issue": null
    },
    {
      "metric": "Backhaul:Usage Percent Down",
      "description": "Percentage of the link's capacity in use toward the SU end",
      "value": 87.2,
      "unit": "%",
      "state": "Warning",
      "severity": "warning",
      "value_ttl_seconds": 604798,
      "issue": {
        "details": "Warning - 87.2% down used - 534 / 612 mbit",
        "severity": "warning",
        "since": "2026-10-08T21:55:03Z",
        "status": "active",
        "recovered_at": null,
        "resolves_at": null
      }
    }
  ]
}

Get a backhaul's history

GET /v1/backhauls/{bhid}/history/{series} Try it

History for one device, backhaul or CPE, rolled up into time buckets (up to 200, or max_points up to 500), so long ranges stay small. Series: devices have pings, quality, signal, traffic (with interface), or a health metric name from get_device whose has_history is true; backhauls have pings, quality, traffic or capacity; CPEs have pings, traffic, plan, quality or signal. Each point has its bucket's start time (at), the values for the series and how many readings went into it (samples). pings: loss_avg_pct, loss_max_pct, latency_avg_ms, latency_min_ms, latency_max_ms. traffic, capacity and plan: avg and max Mbps per direction (an interface's in/out, a backhaul's ap_to_su/su_to_ap, a CPE's down/up). quality: quality_avg, quality_min (0 down to 6 perfect). signal: one point per radio chain per bucket. Health metrics: value_avg, value_min, value_max in unit. A missing bucket means nothing was recorded then.

Parameters

  • bhid integer path required

    The infid, bhid or cpeid

  • series string path required

    Which history; see the operation's description

  • isp string query

    ISP code from GET /isps. Optional when the key reaches exactly one ISP.

  • source one of: "tcptest", "wireless" query

    Backhaul capacity only: which measurement (default: the backhaul's own capacity source)

  • period one of: "1hour", "4hours", "day", "week", "month", "year" query

    Lookback from now (default day). Use from/to instead for a past window

  • from integer or string query

    Range start: unix seconds or 'YYYY-MM-DD HH:MM:SS' UTC

  • to integer or string query

    Range end (default: now)

  • max_points integer query

    Point budget (default 200, max 500); buckets are sized to stay under it

Response

Also available as CSV: add format=csv. Columns follow the field order below, with nested fields as dotted columns (ap.name).

  • type string

    device, backhaul or cpe; more types may be added

  • id integer
  • series string
  • interface string optional

    Device traffic: the interface

  • source string optional

    Backhaul capacity: the measurement shown

  • unit string nullable

    Health metrics: the value's unit. Other series carry the unit in their field names

  • from date-time
  • to date-time
  • bucket_seconds integer
  • point_count integer
  • points array of objects
    Each item: 2 fields
    • at date-time

      Bucket start

    • chain string optional

      signal only: the radio chain

Example

curl -H "Authorization: Bearer $SWIFTFOX_KEY" \
  "https://api.swiftfox.net/v1/backhauls/42/history/series?isp=yourisp"

Response (example data):

{
  "type": "backhaul",
  "id": 12,
  "series": "pings",
  "unit": null,
  "from": "2026-10-08T21:00:00Z",
  "to": "2026-10-08T22:00:00Z",
  "bucket_seconds": 1800,
  "point_count": 2,
  "points": [
    {
      "at": "2026-10-08T21:00:00Z",
      "loss_avg_pct": 0,
      "loss_max_pct": 0,
      "latency_avg_ms": 1.11,
      "latency_min_ms": 0.93,
      "latency_max_ms": 14.2,
      "samples": 180
    },
    {
      "at": "2026-10-08T21:30:00Z",
      "loss_avg_pct": 0.4,
      "loss_max_pct": 5,
      "latency_avg_ms": 2.48,
      "latency_min_ms": 0.94,
      "latency_max_ms": 79.6,
      "samples": 180
    }
  ]
}