---
title: "DryEvalPolicy"
description: "Dry-eval a policy against a SQL statement"
canonical: "https://pgbeam.com/docs/go-sdk/policies/dryEvalPolicy"
last-updated: "2026-09-14T19:37:21.000Z"
---

# DryEvalPolicy

> Dry-eval a policy against a SQL statement

URL: https://pgbeam.com/docs/go-sdk/policies/dryEvalPolicy

Evaluates a single SQL statement against a policy (either a draft policy supplied inline or an existing policy referenced by id) and returns the decision the proxy would make: allow, block, mask, or row-filter. The evaluation reuses the data plane's own policy engine (the same parser, allow/block rules, row-filter rewriter, and masking analysis enforced on live agent sessions), so a what-if verdict matches real enforcement. Stateful checks a single-statement preview cannot model (per-region query and egress budgets, human approvals, and rollback/sandbox write routing) are reported as informational notes, not verdicts. This is a pure compute endpoint; it does not connect to the upstream database and persists nothing.

## Usage

## Parameters

Parameter

Type

Required

Description

ctx

`context.Context`

Yes

Request context

projectID

`string`

Yes

Unique project identifier (prefixed, e.g. prj\_xxx).

req

`pgbeam.DryEvalInput`

Yes

Request body

req.SQL

`string`

Yes

The single SQL statement to evaluate.

req.PolicyID

`*string`

No

ID of an existing saved policy profile to evaluate against.

req.Policy

`*pgbeam.PolicyProfileInput`

No

Mutable fields of a policy profile (used for create and update).

## Response

`(*pgbeam.DryEvalResult, error)`: the dry-eval decision.

## Example

## Errors

Status

Description

400

The request was rejected. `code` is `INVALID_INPUT`, and `errors` names the offending fields when the failure was a validation one.

401

Missing or invalid authentication. `code` is `UNAUTHORIZED`.

403

The caller is authenticated but not allowed to perform this operation. `code` is `FORBIDDEN` when the caller's role is insufficient, and `PLAN_LIMIT_REACHED` when the organization's plan is what stands in the way. The two are answered differently, so branch on the code rather than the status.

404

The resource does not exist, or the caller is not entitled to know that it does. `code` is `NOT_FOUND`.

413

The request body exceeds the 2 MB limit. `code` is `PAYLOAD_TOO_LARGE`.

415

The request body is not JSON, or carries a body without declaring a Content-Type. `code` is `UNSUPPORTED_MEDIA_TYPE`.

429

Rate limited. `code` is `RATE_LIMITED`.

500

The request failed for a reason on our side. `code` is `INTERNAL_ERROR`. Quote `request_id` when reporting it.