{
  "openapi": "3.2.0",
  "info": {
    "title": "Forward: Data Connectors API",
    "summary": "Collect data for NQE from HTTP(S) services outside the network",
    "description": "A _data connector_ brings data from an HTTP(S) service outside the network into a network Snapshot, where\n[NQE](https://docs.fwd.app/latest/api/nqe/) queries can read it. Use one for data that lives behind an API and\nchanges over time, such as IPAM records, CMDB entries, or asset inventories.\n\nA connector names a `baseUrl` and one or more `endpoints` beneath it. Every collection re-fetches every endpoint, so\na Snapshot holds whatever the service returned at the time it was collected. Responses in JSON, CSV, and plain text\nare supported; the `content-type` response header selects the format. An endpoint whose dataset arrives in pages\ndeclares a `paginationModel` saying how to derive each subsequent request.\n\nA connector can reference an HTTP [credential](https://docs.fwd.app/latest/api/credentials/) ID to authenticate with\nand a proxy server ID if one is needed to reach the service.\n\nCollected data appears in the NQE data model under `network.dataConnectors`. See\n[Data Connectors](https://docs.fwd.app/latest/application/sources/configure-collection/data-connectors/) for the\nshape of that data, worked pagination examples, and when to prefer a data file over a connector.",
    "contact": {
      "email": "support@forwardnetworks.com"
    },
    "license": {
      "name": "MIT",
      "url": "https://spdx.org/licenses/MIT"
    },
    "version": "26.8"
  },
  "servers": [
    {
      "url": "/api"
    }
  ],
  "security": [
    {
      "api_token": []
    }
  ],
  "tags": [
    {
      "name": "Collection Sources",
      "description": "Specify the devices, endpoints, and other sources to collect from"
    },
    {
      "name": "Data Connectors",
      "description": "Collect data for NQE from HTTP(S) services outside the network",
      "parent": "Collection Sources"
    }
  ],
  "paths": {
    "/networks/{networkId}/data-connectors": {
      "get": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Get a network’s data connectors",
        "operationId": "getDataConnectors",
        "x-position": 1,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "with",
            "in": "query",
            "description": "Optional properties to include in each connector. Use a comma (as in `?with=status,testResult`) or repeat\nthis parameter to request more than one. Omit this parameter to include neither.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "status",
                  "testResult"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataConnectors"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Add a data connector",
        "description": "Adds an HTTP(S) data connector to the network. Nothing is fetched from the service until the next collection;\nuse [Test a data connector](https://docs.fwd.app/latest/api/data-connectors/test-data-connector/) to confirm\nthe connector works before then.",
        "operationId": "addDataConnector",
        "x-position": 2,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewHttpDataConnector"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataConnector"
                }
              }
            }
          }
        }
      }
    },
    "/networks/{networkId}/data-connectors/{name}": {
      "get": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Get a data connector",
        "operationId": "getDataConnector",
        "x-position": 3,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "with",
            "in": "query",
            "description": "Optional properties to include in the connector. Use a comma (as in `?with=status,testResult`) or repeat\nthis parameter to request more than one. Omit this parameter to include neither.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "status",
                  "testResult"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataConnector"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Update a data connector",
        "description": "All JSON properties in the request body are optional. Include only the properties you wish to change. Replacing\n`endpoints` replaces the whole list, so include every endpoint you want to keep.",
        "operationId": "updateDataConnector",
        "x-position": 4,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HttpDataConnectorPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataConnector"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Delete a data connector",
        "description": "Removes the connector, so later collections no longer fetch from its service. Data already collected stays in\nthe Snapshots that hold it.",
        "operationId": "deleteDataConnector",
        "x-position": 6,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content",
            "content": {}
          }
        }
      }
    },
    "/networks/{networkId}/data-connectors/{name}?action=test": {
      "post": {
        "tags": [
          "Data Connectors"
        ],
        "summary": "Test a data connector",
        "description": "Has a Collector request every one of the connector’s endpoints right now, without collecting a Snapshot, and\nwaits for the outcome. The result is stored on the connector, so it is also available afterward from\n[Get a data connector](https://docs.fwd.app/latest/api/data-connectors/get-data-connector/) with\n`?with=testResult`.\n\nA failed test is reported in the `error` and `errorDesc` of a 200 response, not as an error status.",
        "operationId": "testDataConnector",
        "x-position": 5,
        "parameters": [
          {
            "name": "networkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataConnectorTestResult"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DataConnector": {
        "allOf": [
          {
            "type": "object",
            "required": [
              "name",
              "baseUrl",
              "endpoints"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "A name that’s unique (ignoring case) among all of the network’s collection source names. It identifies\nthis connector in the NQE data model. May consist of letters, digits, dots, hyphens, and underscores.",
                "examples": [
                  "ipam"
                ]
              },
              "baseUrl": {
                "type": "string",
                "description": "The scheme, host, and optional port of the service to fetch from, with no trailing slash. Each endpoint’s\n`path` is appended to it.",
                "examples": [
                  "https://ipam.example.com"
                ]
              },
              "disableSslValidation": {
                "type": "boolean",
                "description": "Whether to skip TLS validation. Absent unless `baseUrl` uses the https scheme and validation is\ndisabled.",
                "examples": [
                  false
                ]
              },
              "credentialId": {
                "type": "string",
                "description": "The `id` of an HttpCredential to authenticate with. Absent if the service accepts unauthenticated\nrequests.",
                "examples": [
                  "H-5"
                ]
              },
              "proxyServerId": {
                "type": "string",
                "description": "The `id` of a proxy server to route requests through. Absent if the Collector reaches the service\ndirectly.",
                "examples": [
                  "P-1"
                ]
              },
              "extraHeaders": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "HTTP headers sent with every request to this service. Absent if no extra headers are\nconfigured.",
                "examples": [
                  {
                    "accept": "application/json"
                  }
                ]
              },
              "endpoints": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/HttpEndpoint"
                },
                "description": "The HTTP GET requests issued on every collection, each one relative to `baseUrl`. Never empty. Each\nendpoint’s response is stored under its own name in the Snapshot. An endpoint whose dataset arrives in pages\nhas a `paginationModel`.",
                "examples": [
                  [
                    {
                      "name": "subnets",
                      "path": "/api/v2/subnets"
                    },
                    {
                      "name": "addresses",
                      "path": "/api/v2/addresses"
                    }
                  ]
                ]
              },
              "collect": {
                "type": "boolean",
                "description": "Whether to collect from this data connector. Absent if it has never been set, which means true.",
                "examples": [
                  true
                ],
                "default": "true"
              },
              "collectorId": {
                "type": "string",
                "description": "The `id` of the Collector that collects from this data connector. Absent if Forward picks an online Collector\nthat supports it.",
                "examples": [
                  "C3"
                ]
              },
              "testResult": {
                "$ref": "#/components/schemas/DataConnectorTestResult",
                "description": "The outcome of the most recent connectivity test of this connector. Absent if it has never been tested, or if\nthe connector changed in a way that invalidated the result. When listing or getting connectors, also absent\nunless `?with=testResult` is used."
              },
              "status": {
                "type": "object",
                "properties": {
                  "error": {
                    "$ref": "#/components/schemas/DeviceCollectionError",
                    "description": "What went wrong collecting from this connector. Absent if collection succeeded. \"NONE\" never\noccurs."
                  }
                },
                "description": "How the most recent collection from this connector went. Absent unless `?with=status` is used, and absent then\ntoo if the network has no processed Snapshot or that Snapshot didn’t collect this connector."
              }
            }
          },
          {
            "$ref": "#/components/schemas/Attribution"
          }
        ]
      },
      "DataConnectorTestResult": {
        "type": "object",
        "required": [
          "startedAt",
          "endedAt"
        ],
        "properties": {
          "startedAt": {
            "type": "string",
            "description": "When the Collector began the test.",
            "examples": [
              "2024-10-27T21:44:51.345Z"
            ]
          },
          "endedAt": {
            "type": "string",
            "description": "When Forward received the test result, or stopped waiting for one.",
            "examples": [
              "2024-10-27T21:44:53.892Z"
            ]
          },
          "error": {
            "$ref": "#/components/schemas/DeviceCollectionError",
            "description": "What went wrong during the test. Absent if every endpoint responded successfully. \"NONE\" never\noccurs."
          },
          "errorDesc": {
            "type": "string",
            "description": "A human-readable explanation of `error`. Absent if the test succeeded.",
            "examples": [
              "HTTP 401 Unauthorized from /api/v2/subnets"
            ]
          }
        }
      },
      "DataConnectors": {
        "type": "object",
        "required": [
          "connectors"
        ],
        "properties": {
          "connectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataConnector"
            }
          },
          "snapshotId": {
            "type": "string",
            "description": "The network’s latest processed Snapshot, which is the one every `status` describes. Absent unless `?with=status`\nis used, and absent then too if the network has no processed Snapshot.",
            "examples": [
              "631772"
            ]
          }
        }
      },
      "HttpDataConnectorPatch": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "A name that’s unique (ignoring case) among all of the network’s collection source names. It identifies this\nconnector in the NQE data model. May consist of letters, digits, dots, hyphens, and underscores. Omit to leave\nthis property alone.",
            "examples": [
              "ipam"
            ]
          },
          "baseUrl": {
            "type": "string",
            "description": "The scheme, host, and optional port of the service to fetch from, with no trailing slash. Each endpoint’s `path`\nis appended to it. Omit to leave this property alone.",
            "examples": [
              "https://ipam.example.com"
            ]
          },
          "disableSslValidation": {
            "type": "boolean",
            "description": "Whether to skip TLS validation. Can be useful for a service whose certificate isn’t trusted. Not recommended.\nIgnored unless `baseUrl` uses the https scheme. Omit to leave this property alone.",
            "examples": [
              false
            ]
          },
          "credentialId": {
            "type": "string",
            "description": "The `id` of an HttpCredential to authenticate with. Null if the service accepts unauthenticated requests. Omit to\nleave this property alone.",
            "examples": [
              "H-5"
            ]
          },
          "proxyServerId": {
            "type": "string",
            "description": "The `id` of a proxy server to route requests through. Null if the Collector reaches the service directly. Omit to\nleave this property alone.",
            "examples": [
              "P-1"
            ]
          },
          "extraHeaders": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "HTTP headers to send with every request to this service. These headers should not contain sensitive data; use\n`credentialId` to authenticate. Replaces every header previously configured. Omit to leave this property alone.",
            "examples": [
              {
                "accept": "application/json"
              }
            ]
          },
          "endpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HttpEndpoint"
            },
            "description": "The HTTP GET requests to issue on every collection, each one relative to `baseUrl`. Never empty. Replaces the\nwhole list, so include every endpoint you want to keep. Omit to leave this property alone.",
            "examples": [
              [
                {
                  "name": "subnets",
                  "path": "/api/v2/subnets"
                },
                {
                  "name": "addresses",
                  "path": "/api/v2/addresses"
                }
              ]
            ]
          },
          "collect": {
            "type": "boolean",
            "description": "Whether to collect from this data connector. Omit to leave this property alone.",
            "examples": [
              true
            ]
          },
          "collectorId": {
            "type": "string",
            "description": "The `id` of the Collector that should collect from this data connector. Null if Forward should pick an online\nCollector that supports it. Omit to leave this property alone.",
            "examples": [
              "C3"
            ]
          }
        }
      },
      "NewHttpDataConnector": {
        "type": "object",
        "required": [
          "name",
          "baseUrl",
          "endpoints"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "A name that’s unique (ignoring case) among all of the network’s collection source names. It identifies this\nconnector in the NQE data model. May consist of letters, digits, dots, hyphens, and underscores.",
            "examples": [
              "ipam"
            ]
          },
          "baseUrl": {
            "type": "string",
            "description": "The scheme, host, and optional port of the service to fetch from, with no trailing slash. Each endpoint’s `path`\nis appended to it.",
            "examples": [
              "https://ipam.example.com"
            ]
          },
          "disableSslValidation": {
            "type": "boolean",
            "description": "Whether to skip TLS validation. Can be useful for a service whose certificate isn’t trusted. Not recommended.\nIgnored unless `baseUrl` uses the https scheme. Defaults to false.",
            "examples": [
              false
            ],
            "default": "false"
          },
          "credentialId": {
            "type": "string",
            "description": "The `id` of an HttpCredential to authenticate with. Absent if the service accepts unauthenticated\nrequests.",
            "examples": [
              "H-5"
            ]
          },
          "proxyServerId": {
            "type": "string",
            "description": "The `id` of a proxy server to route requests through. Absent if the Collector reaches the service\ndirectly.",
            "examples": [
              "P-1"
            ]
          },
          "extraHeaders": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "HTTP headers to send with every request to this service. These headers should not contain sensitive data; use\n`credentialId` to authenticate.",
            "examples": [
              {
                "accept": "application/json"
              }
            ]
          },
          "endpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HttpEndpoint"
            },
            "description": "The HTTP GET requests to issue on every collection, each one relative to `baseUrl`. Never empty. Each endpoint’s\nresponse is stored under its own name in the Snapshot. Give an endpoint a `paginationModel` if its dataset arrives\nin pages.",
            "examples": [
              [
                {
                  "name": "subnets",
                  "path": "/api/v2/subnets"
                },
                {
                  "name": "addresses",
                  "path": "/api/v2/addresses"
                }
              ]
            ]
          },
          "collect": {
            "type": "boolean",
            "description": "Whether to collect from this data connector. Defaults to true.",
            "examples": [
              true
            ],
            "default": "true"
          },
          "collectorId": {
            "type": "string",
            "description": "The `id` of the Collector that should collect from this data connector. Absent if Forward should pick an online\nCollector that supports it.",
            "examples": [
              "C3"
            ]
          }
        }
      },
      "OffsetIncrementExpression": {
        "type": "object",
        "required": [
          "operator"
        ],
        "properties": {
          "operator": {
            "type": "string",
            "description": "\"IDENTITY\" means to add the number at `path` in the previous request’s response to the previous request’s\noffset value. \"LENGTH\" means to add the length of the array at `path` in the previous request’s response to\nthe previous request’s offset value. \"PLUS_ONE\" means to simply add one to the previous request’s offset\nvalue.",
            "examples": [
              "LENGTH"
            ],
            "enum": [
              "IDENTITY",
              "LENGTH",
              "PLUS_ONE"
            ]
          },
          "path": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\nvalue or array needed to calculate the next offset value. Required if `operator` is \"IDENTITY\" or \"LENGTH\";\nabsent otherwise.",
            "examples": [
              [
                "items"
              ]
            ]
          }
        }
      },
      "OffsetBasedPagination": {
        "type": "object",
        "required": [
          "type",
          "itemsArrayField",
          "parameterName",
          "offsetIncrementExpression"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "OFFSET"
          },
          "itemsArrayField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\npaginated data array.",
            "examples": [
              [
                "items"
              ]
            ]
          },
          "parameterName": {
            "type": "string",
            "description": "The name of the URL query parameter to populate with the offset value that increases with each\nrequest.",
            "examples": [
              "skip"
            ]
          },
          "offsetIncrementExpression": {
            "$ref": "#/components/schemas/OffsetIncrementExpression",
            "description": "What to add to the previous request’s offset value to get the next request’s offset value. The first\nrequest’s offset value is always zero.",
            "examples": [
              {
                "operator": "LENGTH",
                "path": [
                  "items"
                ]
              }
            ]
          },
          "maxPages": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of pages to collect. Defaults to 1000.",
            "examples": [
              100
            ]
          }
        }
      },
      "UrlCursorBasedPagination": {
        "type": "object",
        "required": [
          "type",
          "itemsArrayField",
          "urlField"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "URL_CURSOR"
          },
          "itemsArrayField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\npaginated data array.",
            "examples": [
              [
                "items"
              ]
            ]
          },
          "urlField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\nnext page’s URL.",
            "examples": [
              [
                "pagingInfo",
                "nextPageUrl"
              ]
            ]
          },
          "maxPages": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of pages to collect. Defaults to 1000.",
            "examples": [
              100
            ]
          }
        }
      },
      "ParameterCursorBasedPagination": {
        "type": "object",
        "required": [
          "type",
          "itemsArrayField",
          "parameterName",
          "parameterField"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "PARAMETER_CURSOR"
          },
          "itemsArrayField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\npaginated data array.",
            "examples": [
              [
                "items"
              ]
            ]
          },
          "parameterName": {
            "type": "string",
            "description": "The name of the URL query parameter to populate with the cursor value from the previous\nresponse.",
            "examples": [
              "pagingCursor"
            ]
          },
          "parameterField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\nnext page’s cursor value.",
            "examples": [
              [
                "pagingInfo",
                "nextPageCursor"
              ]
            ]
          },
          "maxPages": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of pages to collect. Defaults to 1000.",
            "examples": [
              100
            ]
          }
        }
      },
      "PaginationModel": {
        "type": "object",
        "required": [
          "type",
          "itemsArrayField"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "OFFSET",
              "URL_CURSOR",
              "PARAMETER_CURSOR"
            ]
          },
          "itemsArrayField": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "JSON property name(s) that must be accessed, starting from the top level of the HTTP response, to reach the\npaginated data array.",
            "examples": [
              [
                "items"
              ]
            ]
          },
          "maxPages": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of pages to collect. Defaults to 1000.",
            "examples": [
              100
            ]
          }
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/OffsetBasedPagination"
          },
          {
            "$ref": "#/components/schemas/UrlCursorBasedPagination"
          },
          {
            "$ref": "#/components/schemas/ParameterCursorBasedPagination"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "OFFSET": "#/components/schemas/OffsetBasedPagination",
            "URL_CURSOR": "#/components/schemas/UrlCursorBasedPagination",
            "PARAMETER_CURSOR": "#/components/schemas/ParameterCursorBasedPagination"
          }
        }
      },
      "HttpEndpoint": {
        "type": "object",
        "required": [
          "name",
          "path"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "A concise name for this HTTP endpoint. Used in the name of the file(s) the Collector creates to store the\nresponse(s) it receives. Can contain only letters, digits, underscores, hyphens, and dots.",
            "examples": [
              "compute_managers"
            ]
          },
          "path": {
            "type": "string",
            "description": "The URL path for this HTTP endpoint. Must start with \"/\". May include a query string.",
            "examples": [
              "/api/v1/fabric/compute-managers"
            ]
          },
          "paginationModel": {
            "$ref": "#/components/schemas/PaginationModel",
            "description": "Instructions for fetching this HTTP endpoint’s dataset in parts (pages) using a sequence of requests. Can\nonly be used if this endpoint’s response format is JSON. Absent if this endpoint doesn’t require pagination.",
            "examples": [
              {
                "type": "OFFSET",
                "itemsArrayField": [
                  "managers"
                ],
                "parameterName": "page",
                "offsetIncrementExpression": {
                  "operator": "PLUS_ONE"
                }
              }
            ]
          }
        }
      },
      "DeviceCollectionError": {
        "type": "string",
        "enum": [
          "NONE",
          "UNKNOWN",
          "CONNECTION_TIMEOUT",
          "PROMPT_DISCOVERY_FAILED",
          "CONNECTION_REFUSED",
          "AUTHENTICATION_FAILED",
          "KEY_EXCHANGE_FAILED",
          "AUTHORIZATION_FAILED",
          "VSH_AUTHORIZATION_FAILED",
          "TWO_FACTOR_AUTHENTICATION_FAILED",
          "AVI_SHELL_AUTH_FAILED",
          "AVI_CONTROLLER_WITHOUT_HEALTHY_SERVICE_ENGINES",
          "T128_CONDUCTOR_WITHOUT_HEALTHY_ROUTERS",
          "T128_CONFIG_ABSENT",
          "NETWORK_UNREACHABLE",
          "IO_ERROR",
          "AUTHENTICATION_FAILED_WITHOUT_COLLECTION_RETRY",
          "SESSION_CLOSED",
          "SESSION_LIMIT_REACHED",
          "STATE_COLLECTION_FAILED",
          "PASSWORD_EXPIRED",
          "JUMP_SERVER_CONNECTION_TIMEOUT",
          "JUMP_SERVER_PASSWORD_AUTH_FAILED",
          "JUMP_SERVER_PASSWORD_EXPIRED",
          "JUMP_SERVER_CONNECTION_FAILED",
          "JUMP_SERVER_KEY_EXCHANGE_FAILED",
          "PROXY_SERVER_PING_FAILED",
          "PROXY_SERVER_PORT_REACHABILITY_FAILED",
          "PROXY_SERVER_CONNECTION_FAILED",
          "PROXY_SERVER_AUTHENTICATION_FAILED",
          "PRIV_PASSWORD_ERROR",
          "EXPERT_PASSWORD_ERROR",
          "DUPLICATE_DEVICE",
          "UNSUPPORTED_VERSION",
          "DEVICE_TYPE_UNDETECTED",
          "UNSUPPORTED_DEVICE_TYPE",
          "BMP_CONNECTION_FAILED",
          "BMP_CONNECTION_TIMEOUT",
          "BMP_COLLECTION_FAILED",
          "BMP_COLLECTION_TIMEOUT",
          "BMP_COLLECTION_REFUSED",
          "BMP_NOT_CONFIGURED",
          "BMP_CONFIGURED_WITH_LOCAL_IP",
          "BMP_SESSION_ALREADY_ESTABLISHED",
          "WARN_TYPE_MISMATCH",
          "DEVICE_IS_CHILD_CONTEXT",
          "MANAGER_COLLECTOR_NOT_FOUND",
          "INCOMPLETE_SETUP",
          "COLLECTION_NOT_FOUND",
          "INFINITE_LOOP_IN_COMMAND_OUTPUT",
          "MISSING_FILE",
          "UNSUPPORTED_VENDOR",
          "COMMAND_DISABLED",
          "APIC_CONFIG_COLLECTION_FAILED",
          "UNEXPECTED_KEY_EXCHANGE_MESSAGE",
          "UNDISCOVERED_ACI_FABRIC",
          "SLOW_READ_RATE_DETECTED",
          "TRANSIENT_SLOW_READ_RATE_DETECTED",
          "COLLECTION_TIMED_OUT",
          "COLLECTION_CANCELED",
          "OPERATION_TIMED_OUT",
          "CERTIFICATE_CHECK_FAILED",
          "DEVICE_IN_BAD_STATE",
          "API_SERVER_FAILED_TO_RESPOND",
          "PROJECT_VIEW_PERMISSION_MISSING",
          "NO_SPACE_LEFT_ON_COLLECTOR",
          "NO_SPACE_LEFT_ON_COLLECTED_DEVICE",
          "UNSUPPORTED_SSL_CONNECTION",
          "SOME_OID_FAILED",
          "TACACS_SESSION_EXPIRED",
          "CONFIG_COLLECTION_UNAUTHORIZED",
          "UNRESOLVABLE_HOSTNAME",
          "FILE_TRANSFER_FAILED",
          "VELOS_PARTITION_WITHOUT_BLADES"
        ]
      },
      "Attribution": {
        "type": "object",
        "properties": {
          "createdById": {
            "type": "string",
            "description": "The ID of the user who created this entity, if known. *Note*: The referenced user account might no longer\nexist since an administrator can delete accounts.",
            "examples": [
              "456"
            ]
          },
          "createdAt": {
            "type": "string",
            "description": "When this entity was created, if known.",
            "examples": [
              "2021-12-29T16:30:45.111Z"
            ]
          },
          "createdBy": {
            "type": "string",
            "description": "The username of the user who created this entity, if known. Absent if the user account has been\ndeleted.",
            "examples": [
              "me@example.com"
            ]
          },
          "updatedById": {
            "type": "string",
            "description": "The ID of the user who most recently updated this entity, if known. *Note*: The referenced user account\nmight no longer exist since an administrator can delete accounts.",
            "examples": [
              "789"
            ]
          },
          "updatedAt": {
            "type": "string",
            "description": "When this entity was most recently updated, if known.",
            "examples": [
              "2024-10-27T21:44:51.345Z"
            ]
          },
          "updatedBy": {
            "type": "string",
            "description": "The username of the user who most recently updated this entity, if known. Absent if the user account has\nbeen deleted.",
            "examples": [
              "you@example.com"
            ]
          }
        }
      }
    },
    "securitySchemes": {
      "api_token": {
        "type": "http",
        "scheme": "basic"
      }
    }
  }
}