RikaidoDeveloper

START

A first call

A recipe, its constraints, a verdict. All of it fits in one request.

The recipe

The harness reads the smallest structure a verdict can be reached on: a title, measured ingredients, ordered steps. A recipe written by ChatGPT, by your own model or read out of a book already has this shape.

recipe.json
{
  "recipe": {
    "title": "Chicken satay",
    "ingredients": [
      { "name": "chicken thigh", "quantity": "600", "unit": "g" },
      { "name": "peanut butter", "quantity": "80", "unit": "g" },
      { "name": "salt", "quantity": "1", "unit": "tsp" }
    ],
    "steps": [
      { "instruction": "Sear the thighs until deeply golden.", "tempC": 200 },
      { "instruction": "Whisk the sauce until it coats a spoon." }
    ]
  },
  "constraints": { "allergies": ["peanut"] }
}

The call

curl
curl https://api.rikaido.app/v1/harness/validate \
  -H "Authorization: Bearer $RIKAIDO_KEY" \
  -H "Content-Type: application/json" \
  -d @recipe.json
TypeScript
const res = await fetch("https://api.rikaido.app/v1/harness/validate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RIKAIDO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ recipe, constraints: { allergies: ["peanut"] } }),
});
const verdict = await res.json();
if (!verdict.safe) throw new Error("Refused: " + verdict.issues[0].message);
Python
import os, requests

r = requests.post(
    "https://api.rikaido.app/v1/harness/validate",
    headers={"Authorization": f"Bearer {os.environ['RIKAIDO_KEY']}"},
    json={"recipe": recipe, "constraints": {"allergies": ["peanut"]}},
)
verdict = r.json()
if not verdict["safe"]:
    raise ValueError(verdict["issues"][0]["message"])

What comes back

200
{
  "ok": false,
  "safe": false,
  "issues": [
    {
      "code": "allergen-violation",
      "severity": "error",
      "safety": true,
      "message": "",
      "constraint": "peanut",
      "ingredient": "peanut butter"
    },
    { "code": "salt-out-of-band", "severity": "warn", "message": "" }
  ],
  "classification": { "category": "savory", "baked": false },
  "constraints": { "allergies": ["peanut"], "dietaryPrefs": [], "exclusions": [] },
  "feedback": ""
}

The answer also carries a header, Rikaido-Usage-Op: validate, that says what the call cost without a second call. The next page reads the verdict line by line.