{
  "openapi": "3.1.0",
  "info": {
    "title": "Forward Networks: Network Snapshots API",
    "description": "List or manage the network Snapshots collected from network devices",
    "contact": {
      "email": "support@forwardnetworks.com"
    },
    "license": {
      "name": "MIT",
      "url": "https://spdx.org/licenses/MIT"
    },
    "version": "${apiVersion}"
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [
    {
      "api_token": []
    }
  ],
  "tags": [
    {
      "name": "Network Snapshots",
      "description": "List or manage the network Snapshots collected from network devices"
    }
  ],
  "paths": {
    "/api/networks/{networkId}/snapshots": {
      "get": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Lists all Snapshots",
        "operationId": "listNetworkSnapshotsUsingGET",
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "List only Snapshots in this state.",
            "schema": {
              "$ref": "#/components/schemas/SnapshotState"
            }
          },
          {
            "name": "minSuccessfulDevices",
            "in": "query",
            "description": "List only Snapshots with at least this many successfully modeled devices.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "minSuccessfulDevicePct",
            "in": "query",
            "description": "List only Snapshots with at least this percentage of devices successfully modeled.",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "maxCollectionFailureDevices",
            "in": "query",
            "description": "List only Snapshots with no more than this many devices from which collection has failed.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "maxCollectionFailureDevicePct",
            "in": "query",
            "description": "List only Snapshots with no more than this percentage of devices from which collection has failed.",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "maxParsingFailureDevices",
            "in": "query",
            "description": "List only Snapshots with no more than this many devices for which parsing of collected data has failed.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "maxParsingFailureDevicePct",
            "in": "query",
            "description": "List only Snapshots with no more than this percentage of devices for which parsing of collected data has failed.",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of Snapshots desired",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "includeArchived",
            "in": "query",
            "description": "Also include archived snapshots. Defaults to false if not provided.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkSnapshots"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Imports a Snapshot",
        "description": "Imports a network Snapshot that was previously exported as a .zip file. If multiple Snapshot .zip files are uploaded in a single request, they will be merged. They must not have any devices in common.",
        "operationId": "createSnapshotUsingPOST",
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  },
                  "note": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotInfo"
                }
              }
            }
          }
        }
      }
    },
    "/api/networks/{networkId}/snapshots/latestProcessed": {
      "get": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Returns the latest processed Snapshot",
        "description": "Returns the latest processed Snapshot (the most recent one that's currently prepared for [path searches](#path-search) and [new checks](#checks)).\n\nTriggers processing of the latest Snapshot if it's not already underway and the network has no processed Snapshots.",
        "operationId": "getLatestProcessedSnapshotUsingGET",
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Processing is complete for the identified Snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotInfo"
                }
              }
            }
          },
          "404": {
            "description": "The network has no Snapshots.",
            "content": {}
          },
          "409": {
            "description": "None of the Snapshots in the network are processed. Processing of the latest Snapshot has begun.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorInfo"
                }
              }
            }
          }
        }
      }
    },
    "/api/snapshots/{snapshotId}": {
      "get": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Exports a Snapshot",
        "description": "Exports a network Snapshot as a .zip file.",
        "operationId": "zipSnapshotUsingGET",
        "parameters": [
          {
            "name": "snapshotId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "only",
            "in": "query",
            "description": "Use `?only=CONFIG` to include only device configuration files.",
            "schema": {
              "type": "string",
              "const": "CONFIG"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {}
          }
        }
      },
      "post": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Exports a Snapshot subset, optionally obfuscated",
        "description": "Exports a network Snapshot as a .zip file, optionally limiting which devices are included and optionally [obfuscating](/docs/administration/system/obfuscate-snapshot/) sensitive data.\n\nTo limit which devices are included, specify either `\"includeDevices\"` or `\"excludeDevices\"`. To obfuscate, specify an `\"obfuscationKey\"`.",
        "operationId": "customZipSnapshotUsingPOST",
        "parameters": [
          {
            "name": "snapshotId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SnapshotExportParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {}
          }
        }
      },
      "delete": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Deletes a Snapshot",
        "operationId": "deleteSnapshotUsingDELETE",
        "parameters": [
          {
            "name": "snapshotId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/snapshots/{snapshotId}/metrics": {
      "get": {
        "tags": [
          "Network Snapshots"
        ],
        "summary": "Returns the metrics of a Snapshot",
        "description": "Returns collection and processing health metrics of a Snapshot.",
        "operationId": "getSnapshotMetricsUsingGET",
        "parameters": [
          {
            "name": "snapshotId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved metrics for the Snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SnapshotMetrics"
                }
              }
            }
          },
          "404": {
            "description": "The Snapshot was not found or its metrics were not found; the health metrics will be recomputed if the Snapshot is reprocessed.",
            "content": {}
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ComputationStatus": {
        "type": "string",
        "enum": [
          "UNKNOWN",
          "FAILURE",
          "SUCCESS",
          "CANCELED"
        ]
      },
      "ErrorInfo": {
        "type": "object",
        "required": [
          "httpMethod",
          "apiUrl",
          "message"
        ],
        "properties": {
          "httpMethod": {
            "type": "string",
            "examples": [
              "GET"
            ],
            "enum": [
              "GET",
              "HEAD",
              "POST",
              "PUT",
              "PATCH",
              "DELETE"
            ]
          },
          "apiUrl": {
            "type": "string",
            "examples": [
              "/api/version"
            ]
          },
          "message": {
            "type": "string",
            "description": "A description of the error"
          },
          "reason": {
            "type": "string"
          }
        }
      },
      "Network": {
        "type": "object",
        "required": [
          "id",
          "name",
          "orgId"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "parentId": {
            "type": "string",
            "description": "The network from which this Workspace network was created. Absent if this network is not a Workspace."
          },
          "name": {
            "type": "string",
            "examples": [
              "My Network"
            ]
          },
          "orgId": {
            "type": "string"
          },
          "creator": {
            "type": "string",
            "description": "The username of the user who created the network, or null if the account was deleted",
            "examples": [
              "mary"
            ]
          },
          "creatorId": {
            "type": "string",
            "description": "The id of the user who created the network, or null if the account was deleted",
            "examples": [
              "123"
            ]
          },
          "createdAt": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1649277285118
            ]
          },
          "note": {
            "type": "string",
            "description": "An optional network description."
          },
          "retentionDays": {
            "type": "integer",
            "format": "int32",
            "minimum": 1,
            "maximum": 365,
            "description": "The number of days without any use of this network after which it will be automatically deleted. Absent for parent networks and permanent Workspace networks."
          },
          "secondsToExpiry": {
            "type": "integer",
            "format": "int64",
            "description": "Number of seconds without use before the network expires. Present for temporary Workspace networks only."
          }
        }
      },
      "NetworkSnapshots": {
        "allOf": [
          {
            "type": "object",
            "required": [
              "snapshots"
            ],
            "properties": {
              "snapshots": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SnapshotInfo"
                }
              }
            }
          },
          {
            "$ref": "#/components/schemas/Network"
          }
        ]
      },
      "SnapshotExportParams": {
        "type": "object",
        "properties": {
          "includeDevices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Must be absent if `\"excludeDevices\"` is specified.",
            "examples": [
              "- device-1\n- device-2\n- pa*"
            ]
          },
          "excludeDevices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Must be absent if `\"includeDevices\"` is specified.",
            "examples": [
              "- device-6\n- device-7\n- pa*"
            ]
          },
          "obfuscationKey": {
            "type": "string",
            "description": "If specified, sensitive data will be [obfuscated](/docs/administration/system/obfuscate-snapshot/).",
            "examples": [
              "a-sEcr3t-kEy-th4t-i$-h4rd-to-guE$$"
            ]
          },
          "obfuscateNames": {
            "type": "boolean",
            "description": "default: `false`. If specified, `\"obfuscationKey\"` must also be specified.",
            "examples": [
              false
            ]
          }
        }
      },
      "SnapshotInfo": {
        "type": "object",
        "properties": {
          "creationDateMillis": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1569001234567
            ]
          },
          "id": {
            "type": "string"
          },
          "isDraft": {
            "type": "boolean",
            "examples": [
              false
            ]
          },
          "note": {
            "type": "string"
          },
          "parentSnapshotId": {
            "type": "string"
          },
          "processedAtMillis": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1569003456789
            ]
          },
          "processingTrigger": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "COLLECTION",
              "IMPORT",
              "REPROCESS",
              "FORK"
            ]
          },
          "restoredAtMillis": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1569001234567
            ]
          },
          "state": {
            "$ref": "#/components/schemas/SnapshotState"
          },
          "favoritedBy": {
            "type": "string",
            "description": "The username of the user who most recently marked this Snapshot as a favorite if it's currently a favorite and the user account hasn’t been deleted.",
            "examples": [
              "mary"
            ]
          },
          "favoritedByUserId": {
            "type": "string",
            "description": "The id of the user who most recently marked this Snapshot as a favorite if it’s currently a favorite.",
            "examples": [
              "1234"
            ]
          },
          "favoritedAtMillis": {
            "type": "integer",
            "format": "int64",
            "description": "When this Snapshot was most recently marked as a favorite if it’s currently a favorite. A favorite Snapshot will never be automatically deleted, regardless of its network's snapshot retention policy.",
            "examples": [
              1569872939481
            ]
          }
        }
      },
      "SnapshotMetrics": {
        "type": "object",
        "properties": {
          "collectionConcurrency": {
            "type": "integer",
            "format": "int32",
            "examples": [
              16
            ]
          },
          "collectionDuration": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1234
            ]
          },
          "creationDateMillis": {
            "type": "integer",
            "format": "int64",
            "examples": [
              1649277285118
            ]
          },
          "deviceCollectionFailures": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Possible device error types during collection \n*UNKNOWN*: Unknown error\n*CONNECTION_TIMEOUT*: Connection to device timed out\n*CONNECTION_REFUSED*: Connection to device refused\n*AUTHENTICATION_FAILED*: Authentication failed\n*KEY_EXCHANGE_FAILED*: Key exchange failed\n*AUTHORIZATION_FAILED*: Authorization failed\n*AVI_SHELL_AUTH_FAILED*: Avi authentication failed\n*AVI_CONTROLLER_WITHOUT_HEALTHY_SERVICE_ENGINES*: No Avi Service Engines found\n*NETWORK_UNREACHABLE*: Network not reachable\n*IO_ERROR*: I/O error\n*SESSION_CLOSED*: Session closed unexpectedly\n*STATE_COLLECTION_FAILED*: State collection failed\n*JUMP_SERVER_CONNECTION_TIMEOUT*: Jump server timed out\n*JUMP_SERVER_PASSWORD_AUTH_FAILED*: Jump server auth failed\n*JUMP_SERVER_CONNECTION_FAILED*: Jump server connection refused\n*JUMP_SERVER_KEY_EXCHANGE_FAILED*: Jump server key exchange failed\n*PROXY_SERVER_PING_FAILED*: Proxy ping failed\n*PROXY_SERVER_PORT_REACHABILITY_FAILED*: Proxy port not reachable\n*PROXY_SERVER_CONNECTION_FAILED*: Proxy connection refused\n*PROXY_SERVER_AUTHENTICATION_FAILED*: Proxy authentication failed\n*PRIV_PASSWORD_ERROR*: Privileged password failed\n*UNSUPPORTED_VERSION*: Unsupported version\n*DEVICE_TYPE_UNDETECTED*: Undetected device type\n*WARN_TYPE_MISMATCH*: Device type mismatch\n*DEVICE_IS_CHILD_CONTEXT*: Parent context required\n*MANAGER_COLLECTOR_NOT_FOUND*: Collector manager error\n*INCOMPLETE_SETUP*: Incomplete setup\n*COLLECTION_NOT_FOUND*: Collection not found\n*INFINITE_LOOP_IN_COMMAND_OUTPUT*: Collection stuck in loop\n*MISSING_FILE*: File is missing\n*UNSUPPORTED_VENDOR*: Vendor not supported\n*COMMAND_DISABLED*: Required command is disabled\n*APIC_CONFIG_COLLECTION_FAILED*: APIC config collection failed\n*UNEXPECTED_KEY_EXCHANGE_MESSAGE*: Unexpected Key-Exchange message\n*UNDISCOVERED_ACI_FABRIC*: ACI fabric node was not discovered by APIC\n*SLOW_READ_RATE_DETECTED*: Read rate from the remote peer is too low\n*COLLECTION_TIMED_OUT*: Collection timed out\n*COLLECTION_CANCELED*: Collection canceled by user\n*OPERATION_TIMED_OUT*: Operation timed out\n*CERTIFICATE_CHECK_FAILED*: Certificate cannot be verified\n"
          },
          "deviceProcessingFailures": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Possible error types during processing \n*LICENSE_EXHAUSTED*: License limit exceeded\n*MISSING_SIGNATURE*: Missing signature\n*DUPLICATE*: Duplicate device\n*PARSER_EXCEPTION*: Couldn't be parsed\n*UNSUPPORTED_VENDOR*: Vendor not supported\n"
          },
          "endpointCollectionFailures": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Possible device error types during collection \n*UNKNOWN*: Unknown error\n*CONNECTION_TIMEOUT*: Connection to device timed out\n*CONNECTION_REFUSED*: Connection to device refused\n*AUTHENTICATION_FAILED*: Authentication failed\n*KEY_EXCHANGE_FAILED*: Key exchange failed\n*AUTHORIZATION_FAILED*: Authorization failed\n*AVI_SHELL_AUTH_FAILED*: Avi authentication failed\n*AVI_CONTROLLER_WITHOUT_HEALTHY_SERVICE_ENGINES*: No Avi Service Engines found\n*NETWORK_UNREACHABLE*: Network not reachable\n*IO_ERROR*: I/O error\n*SESSION_CLOSED*: Session closed unexpectedly\n*STATE_COLLECTION_FAILED*: State collection failed\n*JUMP_SERVER_CONNECTION_TIMEOUT*: Jump server timed out\n*JUMP_SERVER_PASSWORD_AUTH_FAILED*: Jump server auth failed\n*JUMP_SERVER_CONNECTION_FAILED*: Jump server connection refused\n*JUMP_SERVER_KEY_EXCHANGE_FAILED*: Jump server key exchange failed\n*PROXY_SERVER_PING_FAILED*: Proxy ping failed\n*PROXY_SERVER_PORT_REACHABILITY_FAILED*: Proxy port not reachable\n*PROXY_SERVER_CONNECTION_FAILED*: Proxy connection refused\n*PROXY_SERVER_AUTHENTICATION_FAILED*: Proxy authentication failed\n*PRIV_PASSWORD_ERROR*: Privileged password failed\n*UNSUPPORTED_VERSION*: Unsupported version\n*DEVICE_TYPE_UNDETECTED*: Undetected device type\n*WARN_TYPE_MISMATCH*: Device type mismatch\n*DEVICE_IS_CHILD_CONTEXT*: Parent context required\n*MANAGER_COLLECTOR_NOT_FOUND*: Collector manager error\n*INCOMPLETE_SETUP*: Incomplete setup\n*COLLECTION_NOT_FOUND*: Collection not found\n*INFINITE_LOOP_IN_COMMAND_OUTPUT*: Collection stuck in loop\n*MISSING_FILE*: File is missing\n*UNSUPPORTED_VENDOR*: Vendor not supported\n*COMMAND_DISABLED*: Required command is disabled\n*APIC_CONFIG_COLLECTION_FAILED*: APIC config collection failed\n*UNEXPECTED_KEY_EXCHANGE_MESSAGE*: Unexpected Key-Exchange message\n*UNDISCOVERED_ACI_FABRIC*: ACI fabric node was not discovered by APIC\n*SLOW_READ_RATE_DETECTED*: Read rate from the remote peer is too low\n*COLLECTION_TIMED_OUT*: Collection timed out\n*COLLECTION_CANCELED*: Collection canceled by user\n*OPERATION_TIMED_OUT*: Operation timed out\n*CERTIFICATE_CHECK_FAILED*: Certificate cannot be verified\n"
          },
          "endpointProcessingFailures": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Possible error types during processing \n*LICENSE_EXHAUSTED*: License limit exceeded\n*MISSING_SIGNATURE*: Missing signature\n*DUPLICATE*: Duplicate device\n*PARSER_EXCEPTION*: Couldn't be parsed\n*UNSUPPORTED_VENDOR*: Vendor not supported\n"
          },
          "hostComputationStatus": {
            "$ref": "#/components/schemas/ComputationStatus",
            "description": "Host computation status",
            "examples": [
              "SUCCESS"
            ]
          },
          "ipLocationIndexingStatus": {
            "$ref": "#/components/schemas/ComputationStatus",
            "description": "IP location indexing status",
            "examples": [
              "SUCCESS"
            ]
          },
          "jumpServerCollectionConcurrency": {
            "type": "integer",
            "format": "int32"
          },
          "l2IndexingStatus": {
            "$ref": "#/components/schemas/ComputationStatus",
            "description": "L2 elements (vlans, LAN segments etc.) indexing status",
            "examples": [
              "SUCCESS"
            ]
          },
          "numCollectionFailureDevices": {
            "type": "integer",
            "format": "int32"
          },
          "numCollectionFailureEndpoints": {
            "type": "integer",
            "format": "int32"
          },
          "numProcessingFailureDevices": {
            "type": "integer",
            "format": "int32"
          },
          "numProcessingFailureEndpoints": {
            "type": "integer",
            "format": "int32"
          },
          "numSuccessfulDevices": {
            "type": "integer",
            "format": "int32",
            "examples": [
              401
            ]
          },
          "numSuccessfulEndpoints": {
            "type": "integer",
            "format": "int32",
            "examples": [
              234
            ]
          },
          "pathSearchIndexingStatus": {
            "$ref": "#/components/schemas/ComputationStatus",
            "description": "End-to-end path indexing status",
            "examples": [
              "SUCCESS"
            ]
          },
          "processingDuration": {
            "type": "integer",
            "format": "int64",
            "examples": [
              5678
            ]
          },
          "searchIndexingStatus": {
            "$ref": "#/components/schemas/ComputationStatus",
            "description": "Object search indexing status",
            "examples": [
              "SUCCESS"
            ]
          },
          "snapshotId": {
            "type": "string"
          },
          "snapshotState": {
            "$ref": "#/components/schemas/SnapshotState",
            "description": "Current state of the Snapshot",
            "examples": [
              "PROCESSING"
            ]
          }
        }
      },
      "SnapshotState": {
        "type": "string",
        "enum": [
          "UNPACKING",
          "UNPROCESSED",
          "PROCESSING",
          "PROCESSED",
          "FAILED",
          "CANCELED",
          "TIMED_OUT",
          "ARCHIVED",
          "RESTORING",
          "RESTORE_FAILED"
        ]
      }
    },
    "securitySchemes": {
      "api_token": {
        "type": "http",
        "scheme": "basic"
      }
    }
  }
}