Bulk APIs
Cisco Catalyst SD-WAN Manager bulk APIs issue a single request to collect information about multiple WAN Edge devices and return it in batches. Bulk operations have two purposes: state operations return current status such as OMP and BFD session state, while statistics operations return measurements such as transmitted and received packet counts.
Statistics bulk APIs can retrieve millions of records from the internal SD-WAN Manager statistics database. Always estimate the result with /doccount, constrain the requested time range, and paginate through the response instead of attempting an unbounded export.
The 26.1 OpenAPI specification exposes those two purposes through three endpoint families:
| Family | Base path | Data type | Pagination |
|---|---|---|---|
| Device State | /data/device/state/{state_data_type} |
Current state snapshots | startId cursor |
| Device Statistics v1 | /data/device/statistics/{state_data_type} |
Time-series stats — generic, all types | scrollId + date range |
| Device Statistics v2 | /v2/data/device/statistics/{type} |
Time-series stats — typed schema per domain | scrollId + date range |
Device State APIs
Section titled “Device State APIs”Endpoint Overview
Section titled “Endpoint Overview”| Method | Path | Description |
|---|---|---|
GET |
/data/device/state/{state_data_type} |
Retrieve bulk device state records |
GET |
/data/device/state/{state_data_type}/fields |
List available fields for a state data type |
GET |
/data/device/state/{state_data_type}/query |
Retrieve state data with a query string filter |
Query Parameters — /data/device/state/{state_data_type}
Section titled “Query Parameters — /data/device/state/{state_data_type}”| Parameter | Type | Default | Description |
|---|---|---|---|
state_data_type |
string (path) | — | The state data type (e.g. CEdgeInterface) |
startId |
string (query) | — | Cursor for the next page — use the value returned in the previous response |
count |
integer | 1000 | Number of records to return per page |
Response Schema
Section titled “Response Schema”{ "data": [ { "@rid": 3413, "ifname": "GigabitEthernet1", "ip-address": "10.0.1.14", "if-admin-status": "if-state-up", "if-oper-status": "if-oper-state-ready", "vdevice-name": "172.16.255.14", "vdevice-host-name": "vm4", "vpn-id": "512", "mtu": "1500", "speed-mbps": "1000", "rx-octets": 22625972, "tx-octets": 12993252, "lastupdated": 1682322326889 } ]}Example — Fetch Interface State
Section titled “Example — Fetch Interface State”curl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/data/device/state/CEdgeInterface?count=500" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"Discover Available Fields
Section titled “Discover Available Fields”Before querying, you can discover what fields are available for any state data type:
curl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/data/device/state/CEdgeInterface/fields" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"Returns an array of field descriptors:
[ { "property": "ifname", "display": "Interface Name", "dataType": "string" }, { "property": "ip-address", "display": "IP Address", "dataType": "string" }, { "property": "if-oper-status", "display": "Oper Status", "dataType": "string" }]Device Statistics APIs
Section titled “Device Statistics APIs”Endpoint Overview
Section titled “Endpoint Overview”| Method | Path | Description |
|---|---|---|
GET |
/data/device/statistics |
List all available statistics types |
GET |
/data/device/statistics/{state_data_type} |
Retrieve bulk statistics records |
GET |
/data/device/statistics/{state_data_type}/doccount |
Get the total record count for a query |
GET |
/data/device/statistics/{state_data_type}/fields |
List available fields for a statistics type |
GET |
/data/device/statistics/alarm/active |
Retrieve active alarms |
Query Parameters — /data/device/statistics/{state_data_type}
Section titled “Query Parameters — /data/device/statistics/{state_data_type}”| Parameter | Type | Required | Description |
|---|---|---|---|
state_data_type |
string (path) | ✅ | Statistics type (e.g. approutestatsstatistics) |
startDate |
string (query) | — | Start of time window — format: 2023-10-31T14:30:00 |
endDate |
string (query) | — | End of time window — format: 2023-10-31T14:30:00 |
scrollId |
string (query) | — | Cursor for subsequent pages |
count |
integer (query) | — | Records per page |
timeZone |
string (query) | — | Time zone (e.g. UTC) |
Available Statistics Types
Section titled “Available Statistics Types”Retrieve the full list dynamically:
GET /dataservice/data/device/statisticsThe response lists all supported state_data_type values:
state_data_type |
Domain |
|---|---|
approutestatsstatistics |
App-Aware Routing (tunnel SLA) |
interfacestatistics |
Interface throughput & errors |
qosstatistics |
QoS queue statistics |
dpistatistics |
Deep Packet Inspection |
aggregatedappsdpistatistics |
Aggregated DPI / application stats |
devicesystemstatusstatistics |
Device CPU, memory, disk |
flowlogstatistics |
Flow log |
eioltestatistics |
Cellular / LTE statistics |
wlanclientinfostatistics |
WLAN client info |
bridgemacstatistics |
Bridge MAC table |
bridgeinterfacestatistics |
Bridge interface statistics |
artstatistics |
Application Response Time |
cloudxstatistics |
Cloud Express |
apphostingstatistics |
App hosting |
vnfstatistics |
VNF interface statistics |
trackerstatistics |
Endpoint tracker status |
urlf |
URL Filtering |
fwall |
Firewall statistics |
umbrella |
Umbrella DNS |
utddaqioxstatistics |
UTD/DAQ IOx statistics |
ipsalert |
IPS alerts |
sulstatistics |
Security Unified Logging |
alarm |
Alarm records |
auditlog |
Audit log |
deviceevents |
Device events |
deviceconfiguration |
Device configuration records |
nwpi |
Network-Wide Path Insights |
nwpiflowraw |
NWPI raw flow data |
sleofflinereport |
SLE offline report |
speedtest |
Speed test diagnostics |
Check Record Count Before Fetching
Section titled “Check Record Count Before Fetching”Before paginating through a large dataset, check how many records match your time window:
GET /dataservice/data/device/statistics/approutestatsstatistics/doccount ?startDate=2024-01-15T00:00:00 &endDate=2024-01-15T23:59:59 &timeZone=UTCExample — Fetch AppRoute Statistics
Section titled “Example — Fetch AppRoute Statistics”# First pagecurl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/data/device/statistics/approutestatsstatistics\?startDate=2024-01-15T00:00:00\&endDate=2024-01-15T23:59:59\&count=500\&timeZone=UTC" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"import requestsfrom urllib.parse import urlencode
BASE_URL = "https://<vmanage>:<port>/dataservice"HEADERS = { "X-XSRF-TOKEN": "<X-XSRF-TOKEN>", "Authorization": "Bearer {{apikey}}", "Content-Type": "application/json",}STAT_TYPE = "approutestatsstatistics"PAGE_SIZE = 500
params = { "startDate": "2024-01-15T00:00:00", "endDate": "2024-01-15T23:59:59", "timeZone": "UTC", "count": PAGE_SIZE,}
url = f"{BASE_URL}/data/device/statistics/{STAT_TYPE}"all_data = []scroll_id = None
while True: if scroll_id: params["scrollId"] = scroll_id
response = requests.get(url, params=params, headers=HEADERS, verify=False) response.raise_for_status()
records = response.json() # returns a list directly
if not records: break
all_data.extend(records) print(f"Fetched {len(all_data)} records so far...")
# If fewer records than requested, we've reached the last page if len(records) < PAGE_SIZE: break
# Extract scrollId from the last record to continue pagination scroll_id = records[-1].get("scrollId") if not scroll_id: break
print(f"Total records retrieved: {len(all_data)}")Active Alarms
Section titled “Active Alarms”A dedicated endpoint retrieves only currently active (uncleared) alarms:
GET /data/device/statistics/alarm/activeQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
scrollId |
string | Cursor for subsequent pages |
startDate |
string | Start date — format: 2023-10-31T14:30:00 |
endDate |
string | End date — format: 2023-10-31T14:30:00 |
count |
integer | Records per page |
timeZone |
string | Time zone (e.g. UTC) |
curl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/data/device/statistics/alarm/active?count=200" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"Discover Available Fields
Section titled “Discover Available Fields”For both state and statistics types, you can discover all queryable fields before building your application:
# State fieldsGET /dataservice/data/device/state/{state_data_type}/fields
# Statistics fieldsGET /dataservice/data/device/statistics/{state_data_type}/fieldsBoth return an array of field descriptors:
[ { "property": "entry_time", "display": "Entry Time", "dataType": "date" }, { "property": "vdevice-name", "display": "System IP", "dataType": "string" }, { "property": "loss_percentage", "display": "Loss %", "dataType": "number" }]Device Statistics v2 APIs
Section titled “Device Statistics v2 APIs”The /v2/ endpoints follow the same pattern as v1 but expose dedicated paths per statistics domain with fully typed response schemas. In the SD-WAN Manager 26.1 specification, interfacestatistics is the available v2 type.
Endpoint Overview
Section titled “Endpoint Overview”| Method | Path | Description |
|---|---|---|
GET |
/v2/data/device/statistics/interfacestatistics |
Fetch interface statistics (typed schema) |
GET |
/v2/data/device/statistics/interfacestatistics/doccount |
Get record count for a time window |
GET |
/v2/data/device/statistics/interfacestatistics/fields |
List available fields |
Query Parameters
Section titled “Query Parameters”Identical to v1 statistics:
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate |
string | — | Start of time window — format: 2023-1-1T00:00:00 |
endDate |
string | — | End of time window — format: 2023-1-1T00:00:00 |
scrollId |
string | — | Cursor for subsequent pages |
count |
integer | — | Records per page |
timeZone |
string | — | Time zone (e.g. UTC) |
v2 Response Schema: InterfaceStatisticsRes
Section titled “v2 Response Schema: InterfaceStatisticsRes”Unlike v1 which returns array<object>, v2 returns array<InterfaceStatisticsRes> with every field explicitly typed:
| Field | Type | Example | Description |
|---|---|---|---|
entry_time |
integer (epoch ms) | 1687177528488 |
Sample timestamp |
statcycletime |
integer (epoch ms) | 1687178400026 |
Stats collection cycle time |
vdevice_name |
string | 172.16.255.16 |
Device system IP |
host_name |
string | vm6 |
Device hostname |
vmanage_system_ip |
string | 172.16.255.16 |
vManage system IP |
interface |
string | GigabitEthernet1 |
Interface name |
interface_type |
string | physical |
Interface type |
af_type |
string | IPv4 |
Address family |
vpn_id |
number | 0 |
VPN / VRF ID |
admin_status |
string | Up |
Admin status |
oper_status |
string | Up |
Operational status |
rx_kbps |
number | 15 |
Receive throughput (kbps) |
tx_kbps |
number | 14 |
Transmit throughput (kbps) |
rx_pkts |
number | 3876 |
Received packets |
tx_pkts |
number | 3757 |
Transmitted packets |
rx_pps |
number | 0 |
Receive packets per second |
tx_pps |
number | 11 |
Transmit packets per second |
rx_octets |
number | 679091 |
Received bytes |
tx_octets |
number | 769358 |
Transmitted bytes |
rx_errors |
number | 0 |
Receive errors |
tx_errors |
number | 0 |
Transmit errors |
rx_drops |
number | 0 |
Receive drops |
tx_drops |
number | 0 |
Transmit drops |
bw_up |
number | 1000000 |
Configured upstream bandwidth (kbps) |
bw_down |
number | 1000000 |
Configured downstream bandwidth (kbps) |
up_capacity_percentage |
number | 0.0014 |
Upstream utilization % |
down_capacity_percentage |
number | 0.0015 |
Downstream utilization % |
total_mbps |
number | 0 |
Total throughput (Mbps) |
device_model |
string | vedge-C8000V |
Device model |
tenant |
string | default |
Tenant name |
id |
string | ZmOr04gBUJf8VowqUaIl |
Record ID |
doccount Response
Section titled “doccount Response”The v2 /doccount endpoint returns a properly typed object (unlike v1 which returns an untyped object):
{ "count": 35174 }Example
Section titled “Example”# Get record count firstcurl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/v2/data/device/statistics/interfacestatistics/doccount\?startDate=2024-01-15T00:00:00\&endDate=2024-01-15T01:00:00\&timeZone=UTC" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"# → { "count": 35174 }
# Fetch first pagecurl -s -k -X GET \ "https://<vmanage>:<port>/dataservice/v2/data/device/statistics/interfacestatistics\?startDate=2024-01-15T00:00:00\&endDate=2024-01-15T01:00:00\&count=500\&timeZone=UTC" \ -H "X-XSRF-TOKEN: <X-XSRF-TOKEN>" \ -H "Authorization: Bearer {{apikey}}" \ -H "Content-Type: application/json"Compare Bulk Endpoint Families
Section titled “Compare Bulk Endpoint Families”| Device State | Statistics v1 | Statistics v2 | |
|---|---|---|---|
| Path | /data/device/state/{type} |
/data/device/statistics/{type} |
/v2/data/device/statistics/{type} |
| Data | Current snapshot | Historical time-series | Historical time-series |
| Types available | Multiple (generic) | Multiple (discover dynamically) | interfacestatistics (26.1) |
| Response schema | Generic object | Untyped array | Fully typed per domain |
| Time filter | ❌ | ✅ startDate / endDate |
✅ startDate / endDate |
| Pagination | startId |
scrollId |
scrollId |
| doccount endpoint | ❌ | ✅ (returns untyped object) | ✅ (returns { "count": N }) |
| fields endpoint | ✅ | ✅ | ✅ |
| RBAC | Device Monitoring-read | Device Monitoring-read | Device Monitoring-read |
Practice with Bruno
Section titled “Practice with Bruno”After completing authentication, run these requests from the Monitoring APIs folder:
05 - Bulk Interface Statecollects current interface state across multiple WAN Edge devices.06 - Bulk Interface Statisticscollects the last hour of interface statistics in batches. Its pre-request script calculatesmonitoringStartDateandmonitoringEndDateautomatically.
Try It with Python
Section titled “Try It with Python”uv run -m monitoring.run_cases --insecure bfd-state --count 500This demonstrates a bounded bulk-state request. The Python examples do not yet implement cursor-driven statistics bulk export; follow the pagination guidance on this page when adding one.
Next Steps
Section titled “Next Steps”Review Monitoring API Best Practices before increasing export frequency, concurrency, or time-window size.