Rules are the written instructions your Agents follow, for example a pricing policy, a tone of voice, or a definition your organization agrees on. A Rule belongs to an organization, and its text lives in versions rather than on the Rule itself: every edit appends a new version, and you decide which version your Agents apply by publishing it.
This guide walks through the complete lifecycle:
Create a Rule, which starts as a draft.
Read the text of a Rule.
Save a new version.
Publish a version so Agents apply it.
Link the Rule to an Agent.
Roll back, unpublish, and delete.
You need:
A Luzmo API key and token. Keep these credentials on your server.
A Designer or Owner role in the Luzmo organization to create, edit, publish, or delete a Rule. Every member of the organization can read every Rule, including drafts written by someone else.
The ID of an Agent if you want to link the Rule to one. See Creating and using Agents through the API .
Call the Create AIRule endpoint with a name and the text of the Rule. Both are required.
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "create",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"properties": {
"name": "Discount policy",
"content": "Never quote a discount below cost price. Escalate to the account manager instead."
}
}' Luzmo stores the text as the first version of the Rule and returns the Rule with latest_version_id pointing at it:
{
"id": "c1f4a0c2-6c9e-4f6b-9a5a-3f0d2b8f1e77",
"name": "Discount policy",
"status": "draft",
"has_unpublished_changes": false,
"latest_version_id": "9b1d2f34-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"published_version_id": null,
"published_name": null,
"published_at": null
} A new Rule is a draft, which means no Agent applies it yet. Store both id and latest_version_id : the first identifies the Rule, the second is what you publish.
name is limited to 120 characters and content to 20000; both are trimmed, and an empty value is rejected with a 400 .
Four attributes describe the lifecycle, and none of them can be written directly:
| Attribute | Meaning |
|---|---|
latest_version_id | The version being edited, i.e. the draft. Moves on every change. |
published_version_id | The version Agents apply, or null when the Rule is not published. |
status | draft while published_version_id is null , otherwise published . |
has_unpublished_changes | true only when a published Rule has a newer version than the one it publishes. |
You write published_version_id ; status and has_unpublished_changes follow from it automatically.
The text of a Rule is not an attribute of the Rule. Retrieve it by including the version you are interested in: latest_version for the draft, published_version for what the Agents apply.
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "get",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"find": {
"where": { "id": "<rule-id>" },
"include": [
{ "model": "AIRuleVersion", "as": "latest_version" },
{ "model": "AIRuleVersion", "as": "published_version" }
]
}
}'published_version is null for a Rule that is not published. To read the full history instead, include versions , or query the AIRuleVersion resource directly with ai_rule_id .
Edit a Rule with the Update AIRule endpoint . Send name , content , or both.
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "update",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"id": "<rule-id>",
"properties": {
"content": "Never quote a discount below cost price. Escalate to the account manager, and record the reason."
}
}' Luzmo appends a version and moves latest_version_id to it. Saving does not change what your Agents apply: a published Rule keeps serving its published version until you publish the new one, and comes back with has_unpublished_changes: true .
Renaming works the same way, and carries the stored text into the new version. Sending exactly the name and text that are already stored writes nothing and leaves latest_version_id where it is, so retrying a save is safe.
Publishing is pointing the Rule at one of its own versions.
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "update",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"id": "<rule-id>",
"properties": {
"published_version_id": "<rule-version-id>"
}
}' The Rule returns with status: "published" , a published_at timestamp, and published_name set to the name of that version. A Rule has at most one published version, so publishing another one replaces the previous publication. Publishing the version that is already published leaves published_at untouched.
Publishing always refers to a version that already exists, so saving and publishing is two calls: save the new text, then publish the latest_version_id that call returned.
A version that belongs to another Rule is rejected with a 400 and the message The published version does not belong to this rule. .
name always follows the most recent version, while published_name keeps the name the Rule had when it was published. Renaming a published Rule therefore changes name immediately but leaves published_name alone until you publish again — which is what you want when you show the draft name to editors and the live name to everyone else.
Link a Rule to an Agent with the linked_agents role, from the Rule:
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "associate",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"id": "<rule-id>",
"resource": {
"role": "linked_agents",
"id": "<agent-id>"
}
}' The same link can be made from the Agent with Associate Agent and the linked_rules role; both write the same relation. Linking is checked on both ends: you need read access to the Rule, which every member of the organization has, and the right to modify the Agent.
An Agent applies the published version of a linked Rule, read at the moment it runs. A Rule with no published version contributes nothing, even while it is linked, and unpublished edits never reach an Agent until you publish them.
Linking a draft up front is fine: the Rule starts applying as soon as you publish a version. To stop one Agent from applying a Rule, use Dissociate AIRule ; to stop every Agent at once, unpublish the Rule.
Every version is kept, so a rollback is just publishing an older one. Retrieve the history first:
curl https://api.luzmo.com/0.1.0/airuleversion \
-H "Content-Type: application/json" \
-d '{
"action": "get",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"find": {
"where": { "ai_rule_id": "<rule-id>" },
"order": [["version", "asc"]]
}
}' Then publish the id of the version you want. Because the newest version is no longer the published one, the Rule comes back with has_unpublished_changes: true .
Versions are immutable: they cannot be created, edited, or deleted through the API. They are written by Luzmo whenever a Rule changes, and removed together with their Rule.
Clear the published version to take a Rule out of service:
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "update",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"id": "<rule-id>",
"properties": {
"published_version_id": null
}
}' The Rule becomes a draft again, published_at and published_name are cleared, and every Agent linked to it stops applying it. No version is lost.
status and has_unpublished_changes are stored on the Rule, so you can filter, search, order, and paginate on them in one call, and the returned count reflects the filter.
curl https://api.luzmo.com/0.1.0/airule \
-H "Content-Type: application/json" \
-d '{
"action": "get",
"version": "0.1.0",
"key": "<your-api-key>",
"token": "<your-api-token>",
"find": {
"where": { "status": "published" },
"search": { "match_types": ["published_name"], "keyphrase": "discount" },
"order": [["published_name", "asc"]],
"limit": 20,
"offset": 0
}
}'Useful combinations:
| Goal | where |
|---|---|
| Rules nobody has published yet | { "status": "draft" } |
| Everything that is live | { "status": "published" } |
| Live, but the draft moved on | { "status": "published", "has_unpublished_changes": true } |
| Live and up to date | { "status": "published", "has_unpublished_changes": false } |
Search on name to match the draft and on published_name to match what your Agents see. A Rule published as Discount policy and renamed to Pricing policy afterwards matches the old name on the published tab and the new one on the drafts.
Delete AIRule removes the Rule with its full version history, and drops the links to the Agents that applied it. The Agents themselves are not affected.
A published Rule cannot be deleted: the call is rejected with a 400 and the message A published rule must be unpublished before it can be deleted. . Unpublish it first, so that taking a Rule away from your Agents is always a deliberate step rather than a side effect of a delete.
Create AIRule , Search AIRule , Update AIRule , and Delete AIRule .
Search AIRuleVersion for the version history of a Rule.
Creating and using Agents through the API to configure the Agents that apply your Rules.
Managing AI context to describe your dashboards, datasets, columns, and formulas to Luzmo IQ.