> ## Documentation Index
> Fetch the complete documentation index at: https://docs.manthan.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# Policies

> POST /policies/validate — confirm a policy exists and is readable

## Validate a policy

```
POST /policies/validate
```

Implemented in `packages/api/src/routes/policies.ts`, mounted at `/policies` in `app.ts` with the `/validate` subpath defined on the router. Calls `policyRepository.load(policyId, policyVersion)` directly — the same [`FilePolicyRepository.load`](/docs/packages/policy) (`packages/policy/src/FilePolicyRepository.ts`) used internally when a Business Transaction is executed.

```bash theme={null}
curl -X POST http://localhost:3000/policies/validate \
  -H "Content-Type: application/json" \
  -d '{ "policyId": "vendor-payment", "policyVersion": "1.0.0" }'
```

<Note>
  Despite the field name, `policyId` is a policy **name** (e.g. `vendor-payment`), not a UUID — `FilePolicyRepository` resolves it to `policies/<name>/<version>/policy.json` on disk. The monorepo root `policies/` directory ships `vendor-payment`, `wire-transfer`, `fraud-block`, `payment-release`, `autonomous-driving`, `medical-treatment`, `multi-agent`, and `custom-policy`, each versioned in its own subdirectory (e.g. `policies/vendor-payment/1.0.0/` and `policies/vendor-payment/2.0.0/`).
</Note>

<Warning>
  "Validate" here means **existence and readability**, not schema or business-rule validation. `FilePolicyRepository.load` only checks that `policies/<policyId>/<policyVersion>/policy.json` exists and parses as JSON — it does not check the policy's internal structure against a schema. A malformed-but-present `policy.json` that still parses as valid JSON would report `valid: true`.
</Warning>

**Response `200`**

```json theme={null}
{ "valid": true, "errors": [] }
```

**Response `400`** — missing `policyId` or `policyVersion`

```json theme={null}
{ "valid": false, "errors": ["policyId is required."] }
```

**Response `404`** — policy not found on disk

```json theme={null}
{ "valid": false, "errors": ["Policy \"vendor-payment\" version \"9.9.9\" not found."] }
```

<Note>
  This route does not use the shared `errorHandler` middleware's error shape at all — it catches `Error` locally and always responds with `{ valid, errors }`, even for the not-found case that other routes would report as `{ "error": "..." }` with a plain 404. See [Error Model](/docs/api/error-model) for how this compares to other routes.
</Note>

<Warning>
  **Specification gap.** `openapi/openapi.yaml` documents `GET /policies` (list) and `GET /policies/{name}/{version}` (get one) under the `Policies` tag — neither exists as an implemented route. Conversely, the OpenAPI spec does not document `POST /policies/validate` at all, even though it's the only policy-related endpoint that actually exists in `packages/api/src/routes/`.
</Warning>

## SDK equivalents

<CodeGroup>
  ```ts TypeScript theme={null}
  const result = await client.validatePolicy({
    policyId: "vendor-payment",
    policyVersion: "1.0.0",
    schemaVersion: "1.0.0",
    signalsSchema: { amount: "number" },
    rules: [],
  });
  ```

  ```python Python theme={null}
  result = client.policy.validate(policy)
  ```
</CodeGroup>

<Note>
  TypeScript's `PolicyApi.validate()` (`typescript/src/client/PolicyApi.ts`) is typed to accept a full `Policy` object from `@parmana/policy` — `{ policyId, policyVersion, schemaVersion, signalsSchema, rules }` — and posts it as-is. Note this is a different shape from the `PolicyReference` (`{ name, version, schemaVersion }`) used inside a `BusinessTransaction`'s own `policy` field (see [`typescript/src/models/policy.ts`](/docs/typescript-sdk/models)). The server route only reads `policyId`/`policyVersion` off whatever body it receives and ignores the rest, so in practice only those two fields matter for this call.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="Policy" href="/docs/concepts/policy">The concept behind what's being validated.</Card>
  <Card title="policy package" href="/docs/packages/policy">Policy loading and evaluation internals.</Card>
  <Card title="Error Model" href="/docs/api/error-model">Why this route's error shape doesn't match the others.</Card>
  <Card title="Execute" href="/docs/api/execute">Where an unvalidated, missing policy fails instead — inside execution, not up front.</Card>
</CardGroup>
