---
title: "Check metadata against what is declared"
method: POST
path: "/v1/projects/{project_id}/metadata-schemas/validate"
tags: ["Metadata Schemas"]
---

# Check metadata against what is declared

`POST /v1/projects/{project_id}/metadata-schemas/validate`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/metadata-schemas/validate`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

Answers what a write would be told, without writing: a caller preparing a batch learns which declaration would refuse it, and why, before it sends anything.

It reports; it does not enforce. The refusal itself lives in each resource's own write path, because a check a writer has to call is advisory and the writer who skips it is the one the rule exists for.

## Request body

- object
  - `path` string, required: The path the document would be filed at, which decides which declaration governs it.
  - `metadata` NullableMetadataBag, nullable: A `MetadataBag` on a request field where `null` is meaningful: a full-replacement update that clears the bag. A record whose bag is unset leaves the field out.

## Response `200`

The verdict

- object
  - `valid` boolean, required: Whether a write of this metadata at this path would be accepted.
  - `resource_type` 'document', required
  - `metadata_schema_id` string, nullable, required: The declaration that would refuse it; `null` when the metadata is accepted or nothing governs the path.
  - `path_prefix` string, nullable, required: The refusing declaration's selector.
  - `error` StoredError, required: Why a resource's work failed, in the shape of an error response's `error` without `hint` and `docs_url`. Every `error` field a resource records carries it, so `code` can be read without first checking the type of `error`.
    - `code` string, required: A key from the server's ERROR_CODES registry, documented on the Error Codes page. `INTERNAL_ERROR`, with the message `Internal Server Error`, records an unexpected failure whose detail reaches the server log only.
    - `message` string, required
    - `meta` object: The failure's own structured context, when it names any.

## Other responses

- `401`: Unauthorized
- `403`: Forbidden

---

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