Hierarchy (Write)
Create Network
POST /api/v1/networks
Request body:
{
"name": "Production",
"description": "Production network"
}
Validation: name is required.
Response: 201 Created (created network object with generated ID and timestamps)
Error responses:
400 Bad Request — Missing name
409 Conflict — Duplicate name (PostgreSQL unique constraint violation)
Update Network
PUT /api/v1/networks/{networkID}
Request body: Same as create (all fields optional). Beyond name/description, the endpoint accepts the per-network settings fields shown in the network object (only the fields present in the body are patched): poller_paused, SNMP settings (snmp_credential_profile_id, snmp_fallback_credential_profile_id, snmp_timeout_seconds 1–30, snmp_retries 0–10, snmp_auto_disable_threshold 1–100), discovery/counters (discovery_enabled, discovery_interval_hours >= 1, counters_enabled, counters_interval_minutes >= 1, counters_poll_interval_seconds 10–3600), L2 (l2_enrichment_enabled, l2_enrichment_interval_hours, l2_crawl_enabled, l2_crawl_interval_hours, l2_crawl_max_depth, l2_crawl_include_routers, l2_stale_hours, l2_credential_profile_id, l2_fallback_credential_profile_id), and mpls_discovery — the MPLS discovery switch (TE tunnels, L3VPN VRFs, pseudowires), on (walk only capability-probed MPLS devices) or off (never walk; the default). The legacy auto is accepted and normalized to on. Set from the Enrichment panel's MPLS Discovery card.
Response: 200 OK (updated network object)
Error responses:
400 Bad Request — Validation failure (e.g. mpls_discovery not on/off)
404 Not Found — Network does not exist
409 Conflict — Attempt to set l2_enrichment_enabled=false on a network that has an EIGRP recorder. EIGRP has no LSDB, so the LLDP/CDP adjacencies L2 enrichment records are its only topology source; the recorder would keep polling but resolve no neighbours. Remove the EIGRP recorder first. (The poller also force-enables enrichment for such networks at runtime; this guard surfaces the constraint instead of letting it fail silently.)
Delete Network
DELETE /api/v1/networks/{networkID}?delete_history=true
Disables all collectors under this network (sets enabled=false, status='stopped') before cascade delete. Cascade deletes all child resources (AS, routing domains, protocol instances, areas, devices, links).
Query Parameters:
delete_history (optional, boolean): When true, deletes all topology_event and topology_snapshot rows for areas under this network before cascade delete. Default: false (history is preserved).
Response: 204 No Content
Error: 404 Not Found (or 500 Internal Server Error on database constraint violations)
Create Autonomous System
POST /api/v1/networks/{networkID}/autonomous-systems
Request body:
{
"asn": 65000,
"name": "AS65000",
"description": "Primary AS"
}
Validation: asn is required.
Response: 201 Created
Error: 400 Bad Request — Missing asn
Update Autonomous System
PUT /api/v1/networks/{networkID}/autonomous-systems/{asID}
Request body: Same as create (all fields optional).
ASN renumber cascade: When asn differs from the current value, the handler:
- Updates the AS row and rewrites
collector_config JSONB hierarchy.asn fields (as a JSON number) within a single transaction, bumping config_version to trigger collector-manager restarts.
- Publishes
osprey.config.bmp_target.updated for each BMP target under this AS (engine cache invalidation).
- Publishes
osprey.config.as.updated (BMP server closes affected TCP sessions so routers reconnect with the new ASN).
Response: 200 OK
Delete Autonomous System
DELETE /api/v1/networks/{networkID}/autonomous-systems/{asID}
Cascade deletes all child resources.
Response: 204 No Content
Create Routing Domain
POST /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains
Request body:
{
"name": "Global",
"description": "Global routing table",
"type": "global",
"rd": null
}
Validation: name is required. type defaults to "global" if omitted; valid values are "global", "vrf", "l3vpn" — anything else is a 400 (create and update).
Response: 201 Created
Error: 400 Bad Request — Missing name or invalid type
Update Routing Domain
PUT /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}
Request body: Same as create (all fields optional).
Response: 200 OK
Delete Routing Domain
DELETE /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}?delete_history=true
Disables all collectors under this routing domain before cascade delete. Cascade deletes all child resources.
Query Parameters:
delete_history (optional, boolean): When true, deletes all topology_event and topology_snapshot rows for areas under this routing domain before cascade delete. Default: false (history is preserved).
Response: 204 No Content
Create Protocol Instance
POST /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances
Request body:
{
"protocol": "ospfv3",
"process_id": "1",
"address_family": "ipv6",
"description": "Primary OSPFv3 instance"
}
Validation:
protocol and process_id are required.
address_family is optional. Defaults: "ipv4" for OSPFv2, "ipv6" for OSPFv3, "multi" for BGP.
- OSPFv2 only supports
address_family: "ipv4".
- OSPFv3 supports
"ipv4" (RFC 5838 AF extensions) or "ipv6".
- BGP:
process_id must be a valid ASN (1–4294967295). address_family is auto-set to "multi". BGP PIs have no areas — BMP targets are linked via bmp_target.protocol_instance_id instead.
Response: 201 Created
Error: 400 Bad Request — Missing protocol or process_id, invalid address_family, invalid BGP ASN
Error: 409 Conflict — A BGP protocol instance already exists for this routing domain
Update Protocol Instance
PUT /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances/{piID}
Request body: Same as create (all fields optional).
Response: 200 OK
Delete Protocol Instance
DELETE /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances/{piID}?delete_history=true
Disables all collectors under this protocol instance before cascade delete. Cascade deletes all child resources.
Query Parameters:
delete_history (optional, boolean): When true, deletes all topology_event and topology_snapshot rows for areas under this protocol instance before cascade delete. Default: false (history is preserved).
Response: 204 No Content
Create Area
POST /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances/{piID}/areas
Request body:
{
"area_id": "0.0.0.0",
"area_type": "normal",
"name": "Area 0",
"description": "Backbone area"
}
Validation: area_id is required. area_type defaults to "normal" if omitted. Valid values: normal, stub, totally_stub, nssa, totally_nssa, level-1, level-2 (DB CHECK constraint — backbone is not valid; sending it currently yields a 500).
Response: 201 Created
Error: 400 Bad Request — Missing area_id
Update Area
PUT /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances/{piID}/areas/{areaID}
Request body: Same as create (all fields optional).
Response: 200 OK
Delete Area
DELETE /api/v1/networks/{networkID}/autonomous-systems/{asID}/routing-domains/{rdID}/protocol-instances/{piID}/areas/{areaID}?delete_history=true
Disables all collectors for this area before cascade delete. Cascade deletes all child resources (devices, links, stub networks).
Query Parameters:
delete_history (optional, boolean): When true, deletes all topology_event and topology_snapshot rows for this area before cascade delete. Default: false (history is preserved).
Response: 204 No Content