---
title: "Validate expose manifest without project schema"
method: POST
path: "/projects/v1/expose/validate"
tags: ["Projects"]
---

# Validate expose manifest without project schema

`POST /projects/v1/expose/validate`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/projects/v1/expose/validate`
- Auth: API key in header `SIGN-IN-WITH-X`

Validate an expose manifest without applying it or executing migration SQL. Requires a valid SIWX wallet identity but does not require an active tier. Validation runs against an empty existing schema universe merged with optional parsed migration_sql.

## Request body

- ExposeManifestValidationRequest
  - `manifest` object, required: Expose manifest v1 JSON object. Shape failures are returned as schema-shape validation issues.
  - `migration_sql` string: Optional SQL parsed only for CREATE TABLE/VIEW/FUNCTION and ALTER TABLE ADD COLUMN reference checks. It is never executed.

## Response `200`

Validation result. Returned even when has_errors is true.

- ExposeManifestValidationResult
  - `errors` ExposeManifestValidationIssue[], required: Only issues with severity=error.
    - `type` 'missing-table' | 'missing-column' | 'missing-view-base' | 'missing-rpc' | 'ambiguous-rpc' | 'unrestricted-ack-required' | 'sensitive-column-public-write' | 'grant-to-role-unknown' | 'force-owner-without-owner-column' | 'validation-inconclusive' | 'schema-shape', required
    - `severity` 'error' | 'warning', required
    - `detail` string, required
    - `fix` string
  - `warnings` ExposeManifestValidationIssue[], required: Only issues with severity=warning.
    - `type` 'missing-table' | 'missing-column' | 'missing-view-base' | 'missing-rpc' | 'ambiguous-rpc' | 'unrestricted-ack-required' | 'sensitive-column-public-write' | 'grant-to-role-unknown' | 'force-owner-without-owner-column' | 'validation-inconclusive' | 'schema-shape', required
    - `severity` 'error' | 'warning', required
    - `detail` string, required
    - `fix` string
  - `has_errors` boolean, required: True when errors is non-empty.
  - `effective_access` object[]: Declared access preview; pending until PostgreSQL rehearsal/apply. Custom operations may be null. Row checks remain runtime checks.
    - `table` string
    - `role` 'anon' | 'authenticated'
    - `declared_operations` string[], nullable
    - `required_privileges` string[], nullable
    - `validation` 'pending' | 'structural'
    - `row_checks` 'runtime'
    - `findings` string[]

## Other responses

- `400`: Malformed validation request envelope
- `401`: Missing or invalid authentication. Run402-originated JSON bodies use the canonical ErrorEnvelope.

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
