{
  "openapi": "3.0.3",
  "info": {
    "title": "Client Endpoint Security API",
    "version": "1.0.0",
    "description": "Client endpoint security \u2014 Zscaler (CrowdStrike Falcon is reached through the Integrations API)."
  },
  "servers": [
    {
      "url": "https://versus-demo.com"
    }
  ],
  "paths": {
    "/api/zscaler/activate-pending/": {
      "post": {
        "operationId": "zscaler_activate_pending_create",
        "description": "Check for foreign pending changes on a ZIA source before activating.\nPOST /api/zscaler/activate-pending/ with body {\"source_id\": <id>}",
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "Create activate pending"
      }
    },
    "/api/zscaler/apply/": {
      "post": {
        "operationId": "zscaler_apply_create",
        "description": "POST /api/zscaler/apply/\nBody: {source_id, mutations: [{method, path, body, object_id}], dry_run: bool}\nRuns ZIAWritePath.apply() and returns the result.",
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "Create apply"
      }
    },
    "/api/zscaler/foreign-pending/": {
      "post": {
        "operationId": "zscaler_foreign_pending_create",
        "description": "Check for foreign pending changes on a ZIA source before activating.\nPOST /api/zscaler/activate-pending/ with body {\"source_id\": <id>}",
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "No response body"
          }
        },
        "summary": "Create foreign pending"
      }
    },
    "/api/zscaler/nss-endpoints/": {
      "get": {
        "operationId": "zscaler_nss_endpoints_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedNSSLSSEndpointList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List nss endpoints"
      },
      "post": {
        "operationId": "zscaler_nss_endpoints_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NSSLSSEndpoint"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create nss endpoint"
      }
    },
    "/api/zscaler/nss-endpoints/{id}/": {
      "get": {
        "operationId": "zscaler_nss_endpoints_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this nsslss endpoint.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NSSLSSEndpoint"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve nss endpoint"
      },
      "put": {
        "operationId": "zscaler_nss_endpoints_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this nsslss endpoint.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/NSSLSSEndpointRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NSSLSSEndpoint"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update nss endpoint"
      },
      "patch": {
        "operationId": "zscaler_nss_endpoints_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this nsslss endpoint.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedNSSLSSEndpointRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedNSSLSSEndpointRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedNSSLSSEndpointRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NSSLSSEndpoint"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update nss endpoint"
      },
      "delete": {
        "operationId": "zscaler_nss_endpoints_destroy",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this nsslss endpoint.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete nss endpoint"
      }
    },
    "/api/zscaler/pep-nodes/": {
      "get": {
        "operationId": "zscaler_pep_nodes_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedZscalerPEPNodeList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List pep nodes"
      },
      "post": {
        "operationId": "zscaler_pep_nodes_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerPEPNode"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create pep node"
      }
    },
    "/api/zscaler/pep-nodes/{id}/": {
      "get": {
        "operationId": "zscaler_pep_nodes_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler pep node.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerPEPNode"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve pep node"
      },
      "put": {
        "operationId": "zscaler_pep_nodes_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler pep node.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerPEPNodeRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerPEPNode"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update pep node"
      },
      "patch": {
        "operationId": "zscaler_pep_nodes_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler pep node.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerPEPNodeRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerPEPNodeRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerPEPNodeRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerPEPNode"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update pep node"
      },
      "delete": {
        "operationId": "zscaler_pep_nodes_destroy",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler pep node.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete pep node"
      }
    },
    "/api/zscaler/snapshots/": {
      "get": {
        "operationId": "zscaler_snapshots_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedZscalerSnapshotList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List snapshots"
      }
    },
    "/api/zscaler/snapshots/{id}/": {
      "get": {
        "operationId": "zscaler_snapshots_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler snapshot.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSnapshot"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve snapshot"
      }
    },
    "/api/zscaler/sources/": {
      "get": {
        "operationId": "zscaler_sources_list",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Which field to use when ordering the results.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "A page number within the paginated result set.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page_size",
            "required": false,
            "in": "query",
            "description": "Number of results to return per page.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "A search term.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedZscalerSourceList"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "List sources"
      },
      "post": {
        "operationId": "zscaler_sources_create",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSource"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Create source"
      }
    },
    "/api/zscaler/sources/{id}/": {
      "get": {
        "operationId": "zscaler_sources_retrieve",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler source.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSource"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Retrieve source"
      },
      "put": {
        "operationId": "zscaler_sources_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler source.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSource"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update source"
      },
      "patch": {
        "operationId": "zscaler_sources_partial_update",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler source.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerSourceRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerSourceRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PatchedZscalerSourceRequest"
              }
            }
          }
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSource"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Update source"
      },
      "delete": {
        "operationId": "zscaler_sources_destroy",
        "description": "Deploy-safe base for making an existing DRF ModelViewSet tenant-isolated\n(VS-SPEC-TENANT-IDENTITY-001 \u00a714). Use as the FIRST base:\n\n    class DeviceViewSet(TenantScopedModelViewSet, viewsets.ModelViewSet):\n        queryset = Device.objects.select_related(...)\n        ...\n\nUnlike the strict TenantScopedViewSet pilot, this **degrades gracefully**:\nit is INERT unless the tenant_scoped alias is configured\n(TENANT_SCOPED_DATABASE_URL) AND the request carries a tenant_id claim.\nWhen inert it behaves exactly like a plain ModelViewSet \u2014 so the rollout\nlands additively and isolation switches on only once the non-superuser\nPostgres role exists (mirrors tenant_subdomain.py's \"inert unless\nconfigured\" contract). When active: reads route through the RLS-enforcing\nconnection and tenant_id is stamped server-side (never client input).",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler source.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No response body"
          }
        },
        "summary": "Delete source"
      }
    },
    "/api/zscaler/sources/{id}/sync/": {
      "post": {
        "operationId": "zscaler_sources_sync_create",
        "description": "Inline synchronisation: pull ZIA and/or ZPA inventory for this source,\nsave a ZscalerSnapshot, and run the normaliser to update FirewallRule rows.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "description": "A unique integer value identifying this zscaler source.",
            "required": true
          }
        ],
        "tags": [
          "zscaler"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ZscalerSourceRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "jwtAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZscalerSource"
                }
              }
            },
            "description": ""
          }
        },
        "summary": "Sync: source"
      }
    }
  },
  "components": {
    "schemas": {
      "NodeTypeEnum": {
        "enum": [
          "zscaler_zia_tenant",
          "zscaler_zia_location",
          "zscaler_zpa_tenant",
          "zscaler_app_connector_group"
        ],
        "type": "string",
        "description": "* `zscaler_zia_tenant` - ZIA Tenant\n* `zscaler_zia_location` - ZIA Location\n* `zscaler_zpa_tenant` - ZPA Tenant\n* `zscaler_app_connector_group` - ZPA App Connector Group"
      },
      "ZscalerSnapshotStatusEnum": {
        "enum": [
          "pending",
          "success",
          "failed"
        ],
        "type": "string",
        "description": "* `pending` - Pending\n* `success` - Success\n* `failed` - Failed"
      },
      "ZscalerSourceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "auth_mode": {
            "$ref": "#/components/schemas/AuthModeEnum"
          },
          "vanity_domain": {
            "type": "string",
            "description": "e.g. acme.zslogin.net",
            "maxLength": 300
          },
          "client_id": {
            "type": "string",
            "maxLength": 500
          },
          "client_secret": {
            "type": "string",
            "writeOnly": true,
            "description": "OneAPI client secret (write-only)"
          },
          "zpa_customer_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_microtenant_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_cloud": {
            "type": "string",
            "maxLength": 200
          },
          "zia_cloud": {
            "type": "string",
            "description": "e.g. zscaler.net",
            "maxLength": 200
          },
          "zia_username": {
            "type": "string",
            "maxLength": 200
          },
          "zia_password": {
            "type": "string",
            "writeOnly": true,
            "description": "ZIA admin password (write-only)"
          },
          "zia_api_key": {
            "type": "string",
            "writeOnly": true,
            "description": "ZIA legacy API key (write-only)"
          },
          "products_enabled": {
            "description": "[\"zia\",\"zpa\",\"zdx\"]"
          },
          "gov_cloud": {
            "type": "boolean",
            "description": "GOV/GOVUS: legacy auth only, read-only"
          },
          "device": {
            "type": "integer",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "name"
        ]
      },
      "PaginatedZscalerPEPNodeList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ZscalerPEPNode"
            }
          }
        }
      },
      "PaginatedZscalerSnapshotList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ZscalerSnapshot"
            }
          }
        }
      },
      "ZscalerSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "auth_mode": {
            "$ref": "#/components/schemas/AuthModeEnum"
          },
          "vanity_domain": {
            "type": "string",
            "description": "e.g. acme.zslogin.net",
            "maxLength": 300
          },
          "client_id": {
            "type": "string",
            "maxLength": 500
          },
          "zpa_customer_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_microtenant_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_cloud": {
            "type": "string",
            "maxLength": 200
          },
          "zia_cloud": {
            "type": "string",
            "description": "e.g. zscaler.net",
            "maxLength": 200
          },
          "zia_username": {
            "type": "string",
            "maxLength": 200
          },
          "products_enabled": {
            "description": "[\"zia\",\"zpa\",\"zdx\"]"
          },
          "gov_cloud": {
            "type": "boolean",
            "description": "GOV/GOVUS: legacy auth only, read-only"
          },
          "device": {
            "type": "integer",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "last_synced": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "id",
          "last_synced",
          "name",
          "updated_at"
        ]
      },
      "AuthModeEnum": {
        "enum": [
          "oneapi",
          "legacy"
        ],
        "type": "string",
        "description": "* `oneapi` - OneAPI (ZIdentity OAuth2)\n* `legacy` - Legacy API Key"
      },
      "ZscalerSnapshot": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "source": {
            "type": "integer",
            "readOnly": true
          },
          "product": {
            "$ref": "#/components/schemas/ProductEnum"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ZscalerSnapshotStatusEnum"
              }
            ],
            "readOnly": true
          },
          "data": {
            "readOnly": true
          },
          "diff": {
            "readOnly": true
          },
          "error": {
            "type": "string",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "data",
          "diff",
          "error",
          "id",
          "product",
          "source",
          "status",
          "version"
        ]
      },
      "NSSLSSEndpointRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "integer"
          },
          "product": {
            "$ref": "#/components/schemas/ProductEnum"
          },
          "endpoint_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "shared_secret": {
            "type": "string",
            "writeOnly": true,
            "description": "Shared HMAC secret (write-only)"
          },
          "log_type": {
            "type": "string",
            "minLength": 1,
            "description": "firewall | web | dns (ZIA) | user_activity (ZPA)",
            "maxLength": 50
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "endpoint_key",
          "product",
          "source"
        ]
      },
      "ZscalerPEPNode": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "source": {
            "type": "integer"
          },
          "node_type": {
            "$ref": "#/components/schemas/NodeTypeEnum"
          },
          "node_id": {
            "type": "string",
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "maxLength": 300
          },
          "zone": {
            "type": "string",
            "maxLength": 200
          },
          "metadata": {}
        },
        "required": [
          "id",
          "name",
          "node_id",
          "node_type",
          "source"
        ]
      },
      "NSSLSSEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "source": {
            "type": "integer"
          },
          "product": {
            "$ref": "#/components/schemas/ProductEnum"
          },
          "endpoint_key": {
            "type": "string",
            "maxLength": 200
          },
          "log_type": {
            "type": "string",
            "description": "firewall | web | dns (ZIA) | user_activity (ZPA)",
            "maxLength": 50
          },
          "is_active": {
            "type": "boolean"
          },
          "last_received": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "records_received": {
            "type": "integer",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "endpoint_key",
          "id",
          "last_received",
          "product",
          "records_received",
          "source"
        ]
      },
      "PatchedZscalerSourceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "auth_mode": {
            "$ref": "#/components/schemas/AuthModeEnum"
          },
          "vanity_domain": {
            "type": "string",
            "description": "e.g. acme.zslogin.net",
            "maxLength": 300
          },
          "client_id": {
            "type": "string",
            "maxLength": 500
          },
          "client_secret": {
            "type": "string",
            "writeOnly": true,
            "description": "OneAPI client secret (write-only)"
          },
          "zpa_customer_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_microtenant_id": {
            "type": "string",
            "maxLength": 200
          },
          "zpa_cloud": {
            "type": "string",
            "maxLength": 200
          },
          "zia_cloud": {
            "type": "string",
            "description": "e.g. zscaler.net",
            "maxLength": 200
          },
          "zia_username": {
            "type": "string",
            "maxLength": 200
          },
          "zia_password": {
            "type": "string",
            "writeOnly": true,
            "description": "ZIA admin password (write-only)"
          },
          "zia_api_key": {
            "type": "string",
            "writeOnly": true,
            "description": "ZIA legacy API key (write-only)"
          },
          "products_enabled": {
            "description": "[\"zia\",\"zpa\",\"zdx\"]"
          },
          "gov_cloud": {
            "type": "boolean",
            "description": "GOV/GOVUS: legacy auth only, read-only"
          },
          "device": {
            "type": "integer",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "ZscalerPEPNodeRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "integer"
          },
          "node_type": {
            "$ref": "#/components/schemas/NodeTypeEnum"
          },
          "node_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "zone": {
            "type": "string",
            "maxLength": 200
          },
          "metadata": {}
        },
        "required": [
          "name",
          "node_id",
          "node_type",
          "source"
        ]
      },
      "PatchedZscalerPEPNodeRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "integer"
          },
          "node_type": {
            "$ref": "#/components/schemas/NodeTypeEnum"
          },
          "node_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "zone": {
            "type": "string",
            "maxLength": 200
          },
          "metadata": {}
        }
      },
      "PatchedNSSLSSEndpointRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "integer"
          },
          "product": {
            "$ref": "#/components/schemas/ProductEnum"
          },
          "endpoint_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "shared_secret": {
            "type": "string",
            "writeOnly": true,
            "description": "Shared HMAC secret (write-only)"
          },
          "log_type": {
            "type": "string",
            "minLength": 1,
            "description": "firewall | web | dns (ZIA) | user_activity (ZPA)",
            "maxLength": 50
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "PaginatedZscalerSourceList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ZscalerSource"
            }
          }
        }
      },
      "PaginatedNSSLSSEndpointList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=4"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?page=2"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NSSLSSEndpoint"
            }
          }
        }
      },
      "ProductEnum": {
        "enum": [
          "zia",
          "zpa",
          "zdx"
        ],
        "type": "string",
        "description": "* `zia` - ZIA\n* `zpa` - ZPA\n* `zdx` - ZDX"
      }
    }
  }
}