Taxonomy
REST API (v2)

POST /schemas/:version/validate

Validate a datachain instance against a schema version.
The HTTP status is 200 for both ok: true and ok: false. Validation success/failure is a semantic answer carried in the body — it is not a transport failure.

Summary

Validate a DTPR datachain instance against a schema version. The response carries structured errors with fix_hints that an agent can feed into a repair loop.

Request

POST https://api.dtpr.io/api/v2/schemas/:version/validate
Content-Type: application/json

{
  "id": "acme-resume-screener",
  "title": [{ "locale": "en", "value": "Acme resume screener" }],
  "description": [{ "locale": "en", "value": "Pre-screens job applicants against the role brief." }],
  "schema_version": "dtpr@2026-09-01-beta",
  "created_at": "2026-09-01T00:00:00Z",
  "elements": [
    { "element_id": "employment" },
    {
      "element_id": "organization",
      "context_type_id": "deployer",
      "variables": [
        { "id": "title", "value": [{ "locale": "en", "value": "Acme Corp" }] },
        { "id": "description", "value": [{ "locale": "en", "value": "Runs the screener and makes the final hiring call." }] }
      ]
    },
    {
      "element_id": "people",
      "context_type_id": "subject",
      "variables": [
        { "id": "title", "value": [{ "locale": "en", "value": "Job applicants" }] },
        { "id": "description", "value": [{ "locale": "en", "value": "Anyone who submits a resume for an open role." }] }
      ]
    },
    { "element_id": "recommends", "context_type_id": "human_decides" }
  ]
}
ParamInDescription
versionpathCanonical version.
(body)JSONA DatachainInstance. id, schema_version, created_at, and a non-empty elements[] are required; everything else defaults. Shape is published in the schema's schema_json. The optional authoring_provenance block is accepted on this endpoint — see Authoring provenance.

Response — valid

HTTP/1.1 200 OK
Content-Type: application/json
DTPR-Content-Hash: sha256-…
Cache-Control: no-store

{
  "ok": true,
  "warnings": []
}

Response — invalid

HTTP/1.1 200 OK
Content-Type: application/json
DTPR-Content-Hash: sha256-…
Cache-Control: no-store

{
  "ok": false,
  "errors": [
    {
      "code": "REQUIRED_CATEGORY_MISSING",
      "message": "Instance is missing at least one element from required category 'purpose'",
      "severity": "error",
      "path": "instance.elements[].category_id",
      "fix_hint": "Add at least one element whose category_id is 'purpose' (category defined at categories[9])."
    }
  ],
  "warnings": []
}

Response — malformed JSON body

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "ok": false,
  "errors": [
    {
      "code": "bad_request",
      "message": "Invalid JSON body.",
      "fix_hint": "Send a valid JSON datachain-instance payload."
    }
  ]
}

Response — shape errors (400-adjacent)

When the JSON parses but the datachain shape fails Zod validation, the status stays 200 and the body carries code: parse_error entries:

{
  "ok": false,
  "errors": [
    {
      "code": "parse_error",
      "message": "Invalid input: expected string, received undefined",
      "path": "created_at",
      "fix_hint": "Fix the field shape and retry."
    }
  ]
}

Errors

CodeHTTPMeaning
bad_request400Invalid JSON body or malformed :version.
not_found404Version is not registered.
parse_error200Datachain shape failed Zod validation.
element_provenance_unknown_element200A key in authoring_provenance.element_provenance does not match any placement element_id.
variable_rationale_unknown_variable200A key inside an element_provenance[<id>].variable_rationale map references a variable not declared on the placed element's category.
Semantic validator codes200Shape-valid but semantically wrong. SCREAMING_SNAKE codes such as REQUIRED_CATEGORY_MISSING, INSTANCE_ELEMENT_UNKNOWN, INSTANCE_REQUIRED_VARIABLE_MISSING, CONTEXT_TYPE_UNKNOWN.

Example

curl -s https://api.dtpr.io/api/v2/schemas/dtpr@2026-09-01-beta/validate \
  -H 'content-type: application/json' \
  --data '{
    "id": "acme-resume-screener",
    "schema_version": "dtpr@2026-09-01-beta",
    "created_at": "2026-09-01T00:00:00Z",
    "elements": [
      {"element_id":"employment"},
      {"element_id":"organization","context_type_id":"deployer","variables":[
        {"id":"title","value":[{"locale":"en","value":"Acme Corp"}]},
        {"id":"description","value":[{"locale":"en","value":"Runs the screener."}]}]},
      {"element_id":"people","context_type_id":"subject","variables":[
        {"id":"title","value":[{"locale":"en","value":"Job applicants"}]},
        {"id":"description","value":[{"locale":"en","value":"Anyone who submits a resume."}]}]},
      {"element_id":"recommends","context_type_id":"human_decides"}
    ]
  }'

See also