Skip to main content
For validation, style-lock, and policy errors, Kynva often returns a details[] array. Each entry can include:
  • fix_patch — a list of RFC 6902 JSON Patch ops to apply to your request body to make it pass.
  • violation_rect — a bounding box for visual issues, useful for highlighting in your UI.
These let you build “did-you-mean” flows and one-click fixes without writing rule-specific logic.

Example: applying a fix_patch

The server says color #FF00FF violates a BrandKit lock and suggests #7C3AED:
{
  "error": {
    "code": "STYLE_LOCK_VIOLATION",
    "details": [{
      "path": "$.brief.color",
      "severity": "error",
      "message": "Color is locked to '#7C3AED'.",
      "fix_patch": [
        { "op": "replace", "path": "/brief/color", "value": "#7C3AED",
          "rationale": "Match locked primary color." }
      ]
    }]
  }
}
Apply it before retrying:
import { applyPatch } from "fast-json-patch";

async function renderWithAutoFix(body: object, attempt = 0): Promise<Response> {
  const res = await fetch("https://api.kynva.ai/api/v1/facade/generate", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KYNVA_API_KEY!}`,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify(body),
  });

  if (res.ok || attempt >= 1) return res;

  const err = await res.clone().json();
  const patches = err.error?.details?.flatMap((d: any) => d.fix_patch ?? []);
  if (!patches?.length) return res;

  const patched = applyPatch(structuredClone(body), patches).newDocument;
  return renderWithAutoFix(patched, attempt + 1);
}
import os, copy, uuid, requests, jsonpatch

def render_with_auto_fix(body, attempt=0):
    res = requests.post(
        "https://api.kynva.ai/api/v1/facade/generate",
        headers={
            "Authorization": f"Bearer {os.environ['KYNVA_API_KEY']}",
            "Content-Type": "application/json",
            "Idempotency-Key": str(uuid.uuid4()),
        },
        json=body,
        timeout=60,
    )

    if res.ok or attempt >= 1:
        return res

    err = res.json()
    patches = [op for d in err.get("error", {}).get("details", [])
                  for op in d.get("fix_patch", [])]
    if not patches:
        return res

    patched = jsonpatch.JsonPatch(patches).apply(copy.deepcopy(body))
    return render_with_auto_fix(patched, attempt + 1)

When not to auto-apply

  • Policy errors — applying the patch may produce something semantically different from what your user asked for. Always confirm.
  • More than one detail with conflicting patches — apply the first, retry, and let the server tell you about the next one.
  • High-trust contexts (e.g., billing copy) — patches are suggestions; surface them as “did you mean…?” in your UI rather than silently applying.

violation_rect

For visual errors (text overflow, image clipping), the server returns the offending rectangle so you can highlight it:
{
  "violation_rect": { "x": 32, "y": 96, "w": 256, "h": 48 }
}
Coordinates are in the rendered output’s pixel space (top-left origin). Overlay this on top of the preview image to point users at the problem.