Formula Studio API Instructions
This page is for humans and robots. Humans can read and copy examples. Robots can use the endpoint list and schemas directly.
Base URL: https://formulastudio.net
Auth: none currently required.
Available Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/api/instructions | This human-readable guide. |
GET |
/api/idm-spec | Machine-readable JSON spec for IDM syntax, functions, aliases, and CSV schema. |
GET |
/api/idm-instructions | Markdown instructions for LLM/agent integration. |
GET |
/api/idm-instructions?download=1 | Downloads the markdown instruction pack. |
GET |
/api/idm-group-rules | Returns usage schema for the group-rule compiler API. |
POST |
/api/idm-group-rules | Compiles JSON or CSV group rules into normalized IDM formulas. |
POST |
/api/idm-validate | Validates formula syntax + guardrails and returns errors/warnings. |
POST |
/api/idm-format | Formats formulas and canonicalizes aliases (ex: equal -> equals). |
POST |
/api/idm-test | Runs formula against test cases and returns pass/fail output. |
Quick Start (recommended 4-call flow)
- Format with
POST /api/idm-format(canonicalize aliases + normalize layout). - Validate with
POST /api/idm-validate(syntax + guardrails). - Lint with
POST /api/idm-validateand{"mode":"lint"}(logic-risk checks). - Test with
POST /api/idm-testusing sample records.
For group rules from structured inputs, use POST /api/idm-group-rules before step 1.
Feature Modes (open-ended)
- Set A: Deterministic CSV Compiler — use the standard group-rule CSV schema and compile with zero AI interpretation.
- Set B: Group Rule Builder — convert JSON/CSV rules into per-rule and nested IDM formulas.
- Set C: OU Logic Builder — write and format OU-focused IDM formulas with validation.
- Set D: Validation + Debug — run format/validate/lint/test before production use.
These are capabilities, not rigid scripts — users and agents can compose them as needed.
Validation Result Types
| Type | Meaning | Action |
|---|---|---|
error | Invalid formula or broken guardrail. | Must fix before use. |
warning | Likely risky logic pattern. | Review intent before use. |
info | Style/maintainability guidance. | Optional cleanup. |
Important Constraints
forEachargument 3 must be URL-encoded (example:%7B%7Bs.name%7D%7D).- String literals cannot contain raw double quotes.
- Nested
ifformulas should include an explicit fallback output. - Group rule request limits: max 200 rules per request; max 100 conditions per rule.
POST JSON Example
curl -X POST "https://formulastudio.net/api/idm-group-rules" \
-H "Content-Type: application/json" \
-d '{
"defaultOutput": "uncategorized",
"rules": [
{
"priority": 1,
"output": "Group A",
"match": "all",
"conditions": [
{ "field": "school_name", "operator": "equals", "value": "A" },
{ "field": "student.sis_id", "operator": "startsWith", "value": "2" }
]
}
]
}'
POST CSV Example
curl -X POST "https://formulastudio.net/api/idm-group-rules" \
-H "Content-Type: application/json" \
-d '{
"defaultOutput": "uncategorized",
"csv": "priority,output,match,field_1,operator_1,value_1,field_2,operator_2,value_2\n1,Group A,all,school_name,equals,A,student.sis_id,startsWith,2\n2,Group B,all,school_name,equals,B,,,"
}'
CSV Input Contract (strict schema)
Required columns: priority, output, match.
Allowed match values: all or any.
Condition column styles:
- Wide columns:
field_1,operator_1,value_1,field_2,operator_2,value_2,... - Compact conditions: single
conditionscolumn asfield|operator|value;field|operator|value
No AI interpretation is applied in deterministic CSV mode. CSV must match schema.
CSV Example
priority,output,match,field_1,operator_1,value_1,field_2,operator_2,value_2
1,Group A,all,school_name,equals,A,student.sis_id,startsWith,2
2,Group B,all,school_name,equals,B,,,
Common CSV Errors
- Missing one of the required columns:
priority,output,match. - Unsupported
matchvalue (must beallorany). - No valid conditions found on a row.
- Unsupported operator in a condition.
Data Structures (for humans + robots)
Group rule object:
{
"priority": 1,
"output": "Group A",
"match": "all",
"conditions": [
{ "field": "school_name", "operator": "equals", "value": "A" },
{ "field": "student.sis_id", "operator": "startsWith", "value": "2" }
]
}
/api/idm-group-rules response shape:
{
"success": true,
"count": 2,
"defaultOutput": "uncategorized",
"rules": [ ...normalized rules... ],
"formulas": {
"list": [
{
"priority": 1,
"output": "Group A",
"condition": "{{and equals school_name "A" equals substr student.sis_id 0 1 "2"}}",
"formula": "{{if and equals school_name "A" equals substr student.sis_id 0 1 "2" "Group A" ""}}"
}
],
"nested": "{{if and equals school_name "A" equals substr student.sis_id 0 1 "2" "Group A" "uncategorized"}}"
}
}
/api/idm-format response shape:
{
"success": true,
"formula": "{{if
equals school_name "A"
"Group A"
"uncategorized"}}",
"options": { "pretty": true, "canonicalize": true }
}
/api/idm-validate response shape:
{
"success": true,
"valid": true,
"errors": [],
"warnings": ["if expression has an empty fallback output."]
}
/api/idm-test response shape:
{
"success": true,
"count": 2,
"compared": 2,
"passCount": 2,
"failCount": 0,
"results": [
{ "name": "row 1", "output": "Group A", "expected": "Group A", "passed": true }
]
}
/api/idm-validate response shape (lint mode):
{
"success": true,
"mode": "lint",
"valid": true,
"findings": [
{
"ruleId": "L004",
"severity": "warning",
"title": "Potentially unreachable branch (broader condition first)",
"message": "branch 1 may shadow branch 2 (broader condition appears first).",
"guidance": "Place specific conditions before broader catch-all conditions."
}
]
}
Agent Prompt Starter (Cursor / Claude Code)
Visit https://formulastudio.net/api/instructions and follow the Quick Start flow.
Use deterministic CSV mode only when the CSV matches the documented schema exactly.
If input is ambiguous or non-standard, convert it to structured rules first, then call /api/idm-group-rules.
Always run validate + lint + test before final output.
Linter Rule Documentation
- L001 — Non-canonical function alias. Example:
equalinstead ofequals. - L002 — Empty fallback output in
if. Valid but easy to misuse if you expected explicit catch-all grouping. - L003 — Potentially unreachable branch (duplicate condition). A later branch repeats an earlier branch condition.
- L004 — Potentially unreachable branch (broader condition first). Example:
AbeforeA AND B. - L005 —
forEacharg3 may not be URL-encoded. - L006 — Deep nested if-chain. Harder to maintain/debug past configured depth threshold.
- L007 — Large
in-list. Valid but brittle if the token list grows too large.
Use GET /api/idm-validate for machine-readable rule metadata (id, severity, message, guidance), and POST /api/idm-validate with {"mode":"lint"} to run linting.