# Quick Start

The [Query Builder](/4yItIzMvkpAvMVFAamTf/features/search/query-builder.md) is fundamental to [Rules](/4yItIzMvkpAvMVFAamTf/features/insights/rules-and-alerts.md) and [Risks](/4yItIzMvkpAvMVFAamTf/features/insights/risks.md), enabling external notifications and enhanced search visibility based on query constraints and conditions. When combined with [Webhooks](/4yItIzMvkpAvMVFAamTf/administration/administration/notifications/destinations/webhooks.md) for remediation workflows, these can offer in-the-box tools to begin integrating Veza with external processes.

As Veza does not write changes to your environment, you can use the query builder API to build your own tools and integrate Veza with your internal systems and security processes.

For example, you might use Veza APIs to:

* Programmatically detect and add Snowflake users to a role when another role already exists with the required permissions
* Progressively query for data resources matching a naming pattern or other condition, and apply tags with the provider's built-in APIs
* Discover and alter overly permissive policies granting access to sensitive data

Your Veza success team can offer additional support and access to development tools including a Python SDK. This guide covers some simple examples to help get started with custom queries, including links to additional documentation.

### Authentication

To run the provided commands, you'll need to first generate a token from **Administration >** [*API Keys*](/4yItIzMvkpAvMVFAamTf/developers/api/authentication.md). You'll also need to know the base URL of your Veza deployment, such as `your-org.veza.com`.

### Query specifications

You can validate that a query is functioning as intended before saving it with [GetAssessmentQuerySpecResult](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecresult.md), which will return the total number of entities in the search results.

[GetAssessmentQuerySpecNodes](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecnodes.md) returns a paginated list of query results, including entity details. This operation does not return a total count of results. A query spec does not require the full saved query [parameters](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/parameters.md), and instead takes a condensed payload.

[GetAssessmentQuerySpecDestinationNodes](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecdestinationnodes.md) returns the related destination nodes for a single entity in the results of a saved query. This endpoint can be used, for example, to review the related roles for an individual user when the query specifies User > Role.

**Sample Request**

Post your request to [`/query_spec:nodes`](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecnodes.md) or [`/query_spec:result`](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecresult.md), depending on whether you need a list of the included nodes (including all entity properties), or want the full result count:

```bash
curl -X 'POST' "$VEZA_URL/api/v1/assessments/query_spec:nodes?page_token-page_size=1" \
-H "authorization: Bearer $VEZA_TOKEN" \
-d '{
 "node_relationship_type": "EFFECTIVE_ACCESS",
 "query_type": "SOURCE_TO_DESTINATION",
 "include_nodes": true,
 "no_relation": false,
 "source_node_types": {
  "nodes": [
   {
    "node_type": "OktaUser",
    "condition_expression": {
     "specs": [
      {
       "id": "b952cf69-5e31-42e5-ae66-372a45b2045b",
       "property": "mfa_active",
       "fn": "EQ",
       "value": false,
       "not": false
      }
     ],
     "operator": "AND"
    }
   }
  ]
 },
 "destination_node_types": {
  "nodes": [
   {
    "node_type": "S3Bucket",
    "condition_expression": {
     "specs": [
      {
       "id": "b78d3e44-0272-4023-ba34-33abaf608e7e",
       "property": "block_public_acls",
       "fn": "EQ",
       "value": false,
       "not": false
      }
     ],
     "operator": "AND"
    }
   }
  ]
 }
}'
```

See [Query Builder Parameters](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/parameters.md) for more information about possible options.

**Sample Response**

The response always returns a `value`, `next_page_token`, and `has_more`. If more results are available, you can get the next page of results by passing the `page_token` in the request query.

The `values` array will contain the Individual entity details:

| `id`                     | Unique Access Graph entity ID.                                                                                               |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `type`                   | Type of entity.                                                                                                              |
| `destination_node_count` | Number of related entities matching the query conditions.                                                                    |
| `permissions`            | For [get-destination-nodes](#get-destination-nodes), the permissions the source entity has to a specific destination entity. |

```json
{
  "values": [
    {
      "id": "00upa6s0hSGtl1eGL5d5",
      "type": "OktaUser",
      "properties": {
        "created_at": "2020-11-12T20:56:34Z",
        "datasource_id": "dev-5150036.okta.com",
        "email": "Abel_Maclead@cookiedemo.onmicrosoft.com",
        "first_name": "Abel",
        "idp_unique_id": "Abel_Maclead@cookiedemo.onmicrosoft.com",
        "is_active": true,
        "last_name": "Maclead",
        "login": "Abel_Maclead@cookiedemo.onmicrosoft.com",
        "mfa_active": false,
        "name": "Abel_Maclead@cookiedemo.onmicrosoft.com",
        "provider_id": "dev-5150036.okta.com",
        "status": "STAGED",
        "updated_at": "2020-11-12T20:56:34Z"
      },
      "destination_node_count": 5,
      "permissions": [],
      "engagement_access_stats": null,
      "access_stats": null,
      "destination_node_ids": [],
      "risk_level": "WARNING",
      "raw_permissions": [],
      "effective_permissions": []
    }
  ],
  "path_values": [],
  "next_page_token": "eyJGaXJzdCI6eyJkdXBsaWNhdGlvbl9zY29wZV9pZCI6IjQwZjFlZGZiLWQ1Y2UtNGU4ZC1hNWVmLWY2MzhmMDgxYzMzYiIsImlkIjoiMDB1Nmg4cnI2dkFzSUJqMW41ZDciLCJsb3dlcl9uYW1lIjoiYWFyb24uYmluZm9yZEB2ZXphdGVzdC5jb20ifSwiTGFzdCI6eyJkdXBsaWNhdGlvbl9zY29wZV9pZCI6IjQwZjFlZGZiLWQ1Y2UtNGU4ZC1hNWVmLWY2MzhmMDgxYzMzYiIsImlkIjoiMDB1cGE2czBoU0d0bDFlR0w1ZDUiLCJsb3dlcl9uYW1lIjoiYWJlbF9tYWNsZWFkQGNvb2tpZWRlbW8ub25taWNyb3NvZnQuY29tIn19",
  "has_more": true
}
```

For more information, see [Query Builder Results](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/results.md).

### Get destination nodes

Use [GetAssessmentQuerySpecDestinationNodes](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/getassessmentqueryspecdestinationnodes.md) to find the related entities for an individual result for a query spec. Specify the `source_node_id` of the entity to get relationships for:

**Sample Request**

```bash
curl -X 'POST' "$VEZA_URL/api/v1/assessments/query_spec:destination_nodes?page_size=0&page_token=" \
-H "authorization: Bearer $VEZA_TOKEN" \
-d '{
  "spec": {
 "node_relationship_type": "EFFECTIVE_ACCESS",
 "query_type": "SOURCE_TO_DESTINATION",
 "include_nodes": true,
 "no_relation": false,
 "source_node_types": {
  "nodes": [
   {
    "node_type": "OktaUser",
    "id": "StartNode",
    "condition_expression": {
     "specs": [
      {
       "id": "b952cf69-5e31-42e5-ae66-372a45b2045b",
       "property": "mfa_active",
       "fn": "EQ",
       "value": false,
       "not": false
      }
     ],
     "operator": "AND"
    }
   }
  ]
 },
 "destination_node_types": {
  "nodes": [
   {
    "node_type": "S3Bucket",
    "id": "EndNode",
    "condition_expression": {
     "specs": [
      {
       "id": "b78d3e44-0272-4023-ba34-33abaf608e7e",
       "property": "block_public_acls",
       "fn": "EQ",
       "value": false,
       "not": false
      }
     ],
     "operator": "AND"
    }
   }
  ]
 }
},
  "source_node_id": "00upa6s0hSGtl1eGL5d5"
}'
```

**Sample response**

```json
{
  "values": [
    {
      "id": "arn:aws:s3:::cct-cct02-engineering",
      "type": "S3Bucket",
      "properties": {
        "allows_acls": true,
        "aws_account_id": "123456789012",
        "block_public_access_enabled": false,
        "block_public_acls": false,
        "block_public_policy": false,
        "created_at": "2021-03-18T08:26:23Z",
        "datasource_id": "123456789012:s3",
        "default_encryption_enabled": true,
        "default_retention_mode": "DISABLED",
        "has_public_policy": true,
        "hosts_website": false,
        "ignore_public_acls": false,
        "name": "cct-cct02-engineering",
        "object_lock_enabled": false,
        "object_ownership_controls": "ObjectWriter",
        "provider_id": "123456789012",
        "region": "us-east-2",
        "replication_rules_count": 0,
        "request_payer": "BucketOwner",
        "restrict_public_buckets": false,
        "server_access_logs_enabled": false
      },
      "destination_node_count": 0,
      "permissions": [
        {
          "id": "arn:aws:iam::123456789012:role/FederatedS3::eperm::123456789012/S3Bucket/affd3e3cd4f3d7f544628ecce27415ae13a984bb",
          "type": "AwsIamEffectivePermission",
          "properties": {
            "aws_account_id": "123456789012",
            "datasource_id": "123456789012::eperm::123456789012:s3",
            "name": "Read",
            "permissions": [
              "s3:GetObject",
              "s3:GetObjectVersion"
            ],
            "provider_id": "123456789012"
          },
          "destination_node_count": 0,
          "permissions": [],
          "engagement_access_stats": null,
          "access_stats": null,
          "destination_node_ids": [],
          "risk_level": "NONE",
          "raw_permissions": [],
          "effective_permissions": []
        },
        {
          "id": "arn:aws:iam::123456789012:role/FederatedRedshiftAndS3::eperm::123456789012/S3Bucket/affd3e3cd4f3d7f544628ecce27415ae13a984bb",
          "type": "AwsIamEffectivePermission",
          "properties": {
            "aws_account_id": "123456789012",
            "datasource_id": "123456789012::eperm::123456789012:s3",
            "name": "Read",
            "permissions": [
              "s3:GetObject",
              "s3:GetObjectVersion"
            ],
            "provider_id": "123456789012"
          },
          "destination_node_count": 0,
          "permissions": [],
          "engagement_access_stats": null,
          "access_stats": null,
          "destination_node_ids": [],
          "risk_level": "NONE",
          "raw_permissions": [],
          "effective_permissions": []
        }
      ],
      "engagement_access_stats": null,
      "access_stats": null,
      "destination_node_ids": [],
      "risk_level": "CRITICAL",
      "raw_permissions": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "effective_permissions": [
        "Read"
      ]
    }
  ],
  "path_values": [],
  "next_page_token": "",
  "has_more": false
}
```

### Save a query

If you want to run the same query repeatedly, or enable Veza [Rules](/4yItIzMvkpAvMVFAamTf/features/insights/rules-and-alerts.md) or [Risks](/4yItIzMvkpAvMVFAamTf/features/insights/risks.md) based on the results, you can save it under [`/assessments/queries`](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/createassessmentquery.md).

A saved query includes a name and description, along with any other [query parameters](/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/parameters.md).

### Get saved query result count or entity details

Use the query ID to run a saved query. Just as for `query_spec` operations, you can request the paginated entity details or the result count, or get destination nodes for a result:

{% code title="get query nodes" %}

```bash
curl 'https://<baseUrl>/api/v1/assessments/queries/ab5b66df-6873-4e53-98e5-aa55b88c76bd:nodes?page_size=100' \
  -H 'authorization: <authToken>'
```

{% endcode %}

{% code title="get query result" %}

```bash
curl 'https://<baseUrl>/api/v1/assessments/queries/ab5b66df-6873-4e53-98e5-aa55b88c76bd:result' \
  -H 'authorization: Bearer <authToken>'
```

{% endcode %}

Responses will contain the node details or the total count, depending on the method used.

{% code title="get query nodes" %}

```json
{
  "values": [
    {
      "id": "arn:aws:s3:::cct-cct01-finance",
      "type": "S3Bucket",
      "properties": {
        "block_public_acls": false,
        "name": "cct-cct01-finance"
      },
      "destination_node_count": 0,
      "permissions": []
    }
  ],
  "next_page_token": "MTAw",
  "has_more": false
}
```

{% endcode %}

{% code title="get query result" %}

```json
{"result_type":"number","number_value":"1"}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/developers/api/query-builder/usage-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
