Rule Sets reference
A rule set describes what a valid output looks like for a given task. The contract field in API requests is the JSON object that defines a rule set — always specify type; the rest is optional.
Type: text (default)
Generic substring + length checks. Filler tokens are always rejected.
{
"type": "text",
"min_length": 10,
"max_length": 500,
"must_contain": ["Order confirmed"],
"must_not_contain": ["as an AI", "I cannot"],
"must_match": ["^Order [#]\\d+"] // regex strings
}
Leftover AI text. For text and html rule sets, the boolean key block_leftover_ai_text (default true when absent) flags AI chatter pasted into a real message, such as “Here’s a more polished version…” at the start, “Let me know if you’d like me to…” at the end, or placeholders like [Your Name]. Set "block_leftover_ai_text": false to turn it off. Each match is reported as leftover:<phrase>.
Block private data. For text and html rule sets, the boolean key block_private_data blocks a reply that contains a payment card number (13 to 19 digits that pass the card check, spaces or dashes allowed), a US social security number (###-##-####, invalid ranges excluded) or a secret-looking key (sk_live_, sk_test_, wtk_live_, wtk_test_, an AWS key starting AKIA, or a -----BEGIN ... PRIVATE KEY----- block). It is on by default for new rule sets and new Safe AI connections; rule sets and connections you already have keep it off until you turn it on. When absent, it is off. The reason reads “It included private data (a card number)” and the matched text is never repeated in the reason, the history or the follow-up sent to your AI. Each match is reported as private_data:<kinds>, for example private_data:card.
Type: html
Structural + brand-conformance checks for generated HTML.
{
"type": "html",
"html": {
"require_doctype": true,
"require_head_body": true,
"palette": ["#0a0a0a", "#ff6b35"], // ≥1 must be present
"fonts": ["Inter", "Oswald"], // ≥1 must be referenced
"cta": "Book now"
},
"must_not_contain": ["lorem ipsum"],
"repair": true
}
When repair: true and a check fails, Nexxtool AI attempts to fix doctype/palette/CTA gaps and returns the repaired HTML. Costs 2 checks per call (1 for the check + 1 for the repair attempt).
Type: json
JSON Schema (draft-07) plus required dotted paths.
{
"type": "json",
"schema": {
"type": "object",
"required": ["customer", "amount"],
"properties": {
"customer": {"type": "string"},
"amount": {"type": "number"}
}
},
"required_paths": ["customer", "amount"]
}
Type: script
For generated automation/Node scripts.
{
"type": "script",
"script": {
"min_length": 200,
"required_env": ["STRIPE_SECRET_KEY"],
"require_entrypoint": true // must define a main() or require.main check
}
}
Type: research
For research/synthesis outputs with structured findings.
{
"type": "research",
"research": {
"min_summary_length": 60,
"min_findings": 3,
"min_sources": 2
}
}
Checks that the output object has the shape { synthesis: { summary, key_findings[] }, sources[] }.
Issue codes
| Code | Meaning |
|---|---|
filler:<token> | Output contains a built-in filler/slop token |
blocked:<phrase> | Output contains a phrase from your must_not_contain (previously reported as filler:) |
leftover:<phrase> | Leftover AI text (e.g. here's a more polished in the first ~200 characters, let me know if you'd like me to in the last ~300, or [your name] anywhere) |
missing:<substr> | Required substring not present |
schema:<path> <msg> | JSON Schema violation |
too_short:N<M | Output shorter than min_length |
missing_doctype | HTML doesn’t start with <!doctype html> |
palette_missing / palette_partial:N/M | Required colors not present |
cta_missing | Required CTA string not in HTML |
regex_miss:<pattern> | A must_match regex didn’t match |
See the full list in the errors reference.