---
title: "Validate a structured query plan before execution"
method: POST
path: "/v1/verify"
tags: ["Semantic Query", "Semantic Query"]
---

# Validate a structured query plan before execution

`POST /v1/verify`

## Request

- Base URL: `https://api.algenta.ai`
- URL: `https://api.algenta.ai/v1/verify`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

**LLM calls this after reading /v1/sources/schema.**

Submit the exact source + column names chosen by the LLM. The engine verifies:
- Source exists in registry
- metric_column exists and is numeric
- aggregation is valid for the column's role
- group_column exists (if given)
- join path exists with sufficient confidence (if join_source_name given)

Returns `valid: true` + resolved names on success, or `valid: false` + errors + suggestions on failure. **Call /v1/execute (or /v1/query with exact-spec) only after verify returns valid.**

## Request body

- VerifyRequest: LLM-produced execution plan. All names are EXACT (from schema endpoint). Mojo checks: source exists, columns exist, aggregation is valid for the column role, and join keys have sufficient confidence.
  - `source_name` string, nullable: Exact source name from schema
  - `dataset_id` string, nullable: Public dataset ID alias for a registered source. When provided, verification is scoped to that one registered dataset.
  - `metric_column` string, nullable: Exact column name to aggregate
  - `aggregation` string, nullable: sum | avg | count | max | min
  - `group_column` string, nullable: Exact column name for group-by
  - `join_source_name` string, nullable: Second source name for join
  - `join_columns` string[], nullable: [local_col, remote_col] — join key pair. Omit to auto-detect.
  - `min_join_confidence` number: Reject join paths below this confidence threshold. Default 0.85 — only statistically solid joins are accepted. Lower to 0.50 to allow weaker joins at your own risk.
  - `mode` string: strict — reject invalid plans with no suggestions (enterprise enforcement). assist — reject invalid plans AND return corrective suggestions (default, LLM-friendly).
  - `resolved_plan` ResolvedPlanInput
    - `source_name` string, required
    - `metric_column` string, required
    - `aggregation` string: sum | avg | count | max | min
    - `group_column` string, nullable
    - `join_path` JoinPathSpec: Explicit multi-hop join contract replacing single-hop join fields.
      - `base_source` string, required: Source that owns the metric column and anchors the path.
      - `group_source` string, nullable: Final source expected to provide the group column, if different from base_source.
      - `edges` JoinEdgeSpec[]: Ordered join edges from base_source toward the dimension source.
        - `left_source` string, required: Source on the left side of the join edge.
        - `right_source` string, required: Source on the right side of the join edge.
        - `left_key` string, required: Exact join key column in left_source.
        - `right_key` string, required: Exact join key column in right_source.
        - `join_type` string: Join type. Initial implementation supports inner.
        - `min_confidence` number: Minimum acceptable confidence for this hop.
        - `expected_cardinality` string, nullable: Optional expected cardinality such as one_to_many, many_to_one, or many_to_many.
        - `allow_many_to_many` boolean: If false, planner/executor must reject many_to_many fanout on this hop.
      - `max_hops` integer: Maximum allowed join hops for this request. Defaults to 4; explicit opt-in can raise this to 6 hops (7 tables).
      - `min_path_confidence` number: Minimum acceptable composed confidence across the full join path.
      - `reject_on_ambiguity` boolean: Reject if more than one viable path exists with insufficient score separation.
      - `reject_on_fanout` boolean: Reject if estimated path fanout exceeds safe execution thresholds.
    - `filter` FilterSpec: Time or value filter.
      - `time_filter` string, nullable: Relative time window. One of: last_quarter, this_quarter, last_month, this_month, last_year, this_year.
      - `conditions` FilterConditionSpec[]: Optional deterministic non-time predicates applied on the metric source. These are record predicates over normalized rows, not SQL clauses. Use exact column when schema is known, or dimension_hint for categorical dimensions when only the semantic label is known, including Redis and other non-SQL sources after normalization. Supported ops: eq, in, gt, gte, lt, lte, is_null, is_not_null.
        - `column` string, nullable: Exact source column name for this filter when schema is known.
        - `dimension_hint` string, nullable: Weak semantic label for the filter dimension when the exact column name is not known yet. Best for status/type/category style filters.
        - `op` 'eq' | 'in' | 'gt' | 'gte' | 'lt' | 'lte' | 'is_null' | 'is_not_null': Deterministic filter operator.
        - `value` unknown
        - `values` unknown[], nullable: List comparison values for in.
          - unknown
    - `limit` integer, nullable
    - `order` string: desc | asc
    - `constraints` ConstraintSpec
      - `requires_derived` boolean: Reject if metric column is not a derived_measure (formula-proven).
      - `no_cross_source` boolean: Reject if query requires a cross-source join.
      - `min_column_confidence` number: Reject if column_confidence component < this value.
      - `max_join_hops` integer: Safe default join-path budget for planner-generated cross-source queries. Defaults to 4 hops; explicit opt-in can raise this to 6 hops (7 tables).
    - `schema_revision` string, required

## Response `200`

Successful Response

- VerifyResponse
  - `valid` boolean, required
  - `errors` string[], required
  - `suggestions` string[], required
  - `resolved` object, required
  - `valid_dimensions` string[]
  - `valid_measures` string[]
  - `source_behavior` string
  - `latency_ms` number, required
  - `verified` boolean
  - `request_id` string, nullable
  - `schema_revision` string, nullable
  - `plan_hash` string, nullable
  - `verification_mode` string
  - `rejection_reason` string, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/codna/apis/algenta-api.md) · [All operations](https://skmtc.dev/codna/apis/algenta-api/llms.txt) · [OpenAPI document](https://skmtc.dev/codna/apis/algenta-api/revisions/35d30f84a5df?raw)
