Skip to content

Parsing Validation Responses

This page explains the structured error objects the public API returns, how severity differs between validate and submit, and how an agent should self-correct. For the full code list with anchors, see the Validation reference.

The Error Object Shape

Wherever the API reports a per-field problem — in a top-level errors array on an error envelope, or inside errors / warnings of a validate report — each entry has the same shape:

json
{
  "field": "email",
  "code": "format",
  "message": "Value is not a valid email address.",
  "help": "https://docs.kinoforms.com/developer/api/validation#format"
}
  • field — the form field key the problem is about. May be absent for form-level problems.
  • code — a stable machine code. Branch on this. The full set is in the Validation reference.
  • message — a human-readable description. Show it to humans; do not parse it in code.
  • help — a deep link to the documentation anchor for this exact code, e.g. .../developer/api/validation#format. An agent can fetch this to learn the rule and the fix.

Where Errors Appear

EndpointResultWhere problems show up
validatealways 200data.errors, data.warnings, data.missingRequired
submit200 on success, 422 on bad datatop-level errors array (with code: "validation_failed")
submit?partial=true200top-level errors for malformed fields; data.missingRequired for gaps

Severity: Validate vs Submit

The same problem can be a warning in one place and an error in another. This is intentional: validate is permissive so you can explore; submit is strict so bad data never lands.

SituationOn validateOn submit
Missing required fieldreported in missingRequired (still valid: false)error422 validation_failed
unknown_field (field not in schema)warning (field ignored)error422 validation_failed
Malformed value (format, type_mismatch, pattern, …)error in errorserror422 validation_failed

In partial mode (submit?partial=true), missing required fields are downgraded to missingRequired (no error), but malformed values are still errors.

How an Agent Should Self-Correct

The reliable pattern is validate-loop, then submit once:

text
1. Build the best `data` you can.
2. POST /validate  →  read data.errors, data.warnings, data.missingRequired.
3. If errors or missingRequired is non-empty:
     - For each error: look up code (or fetch `help`), fix the field's value.
     - For each missingRequired key: supply a value.
     - For each unknown_field warning: drop that key (submit would reject it).
     - Go to step 2.
4. When valid === true and missingRequired is empty:  POST /submit.
5. If submit still returns 422 (a race, or a rule only checked on write):
     read the errors array, fix, and re-validate before retrying.

Notes for robust agents:

  • Branch on code, never on message. Messages may change; codes are stable.
  • Resolve unknown_field before submit. It is only a warning on validate, but it is a hard error on submit. Drop the offending key or map it to a real field key.
  • Use help when you do not recognize a code. It points at the exact rule and how to fix it.
  • Respect rate limits. Validate is throttled generously for iteration; submit is 1 per 5 seconds per agent. Iterate on validate, not on submit.
  • Treat missingRequired as a checklist. Keep validating until it is empty.

Worked Example

Validate response:

json
{
  "data": {
    "valid": false,
    "errors": [
      { "field": "age", "code": "type_mismatch", "message": "Expected a number.",
        "help": "https://docs.kinoforms.com/developer/api/validation#type_mismatch" }
    ],
    "warnings": [
      { "field": "nickname", "code": "unknown_field", "message": "Field is not part of this form.",
        "help": "https://docs.kinoforms.com/developer/api/validation#unknown_field" }
    ],
    "missingRequired": ["email"]
  },
  "apiVersion": "v1"
}

The agent should:

  1. agetype_mismatch: coerce "42" to 42.
  2. nicknameunknown_field warning: remove the nickname key (submit would reject it).
  3. missingRequired: ["email"]: add a valid email.
  4. Re-validate → valid: true, missingRequired: [].
  5. submit.

KinoForms documentation