Standing rules

Inject your organization's standing rules into chat as defaults. Rules are on for signed-in keys and off for developer keys unless you opt in.

Standing rules are instructions your organization sets for chat, such as "Always answer in British English." A vault can have its own. When rules apply, the gateway injects them into the turn as defaults that the user's own message overrides, never as constraints that outrank the user. The rules field on a chat request turns injection on or off for that request.

Defaults depend on the key

KeyRules when rules is omitted
Signed-in credential: device login, OAuth login, and the Cruxy web app, desktop, CLI, and mobileInjected
Developer API key or headless keyNot injected, unless the key was issued with allowed scopes that name the rules family

An unscoped developer key has every family but has not opted in, so it gets no rules by default. A key's rules are its owner's organization's guidance, and a developer key often serves people other than its owner.

Opt in

A developer key opts in one of two ways:

  • Per request: send rules: true.
  • Once, on the key: issue the key with allowed scopes that name the rules family. Every request from it then gets rules unless it sends rules: false.
curl https://api.cruxy.ai/api/v1/chat \
  -H "Authorization: Bearer $CRUXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vaani",
    "stream": false,
    "rules": true,
    "messages": [
      { "role": "user", "content": "Draft a two-line status update for the launch." }
    ]
  }'

rules: true needs a key whose allowed scopes include rules. A key without it gets 403 key_scope_forbidden with required_scope: "rules", refused before anything is billed, and such a key never gets rules. rules: false needs no scope: any key may send it to decline rules for one turn, since the user's own message already overrides them.

What gets injected

The switch covers the whole resolved ruleset: a turn gets exactly what GET /api/v1/rules/resolved returns for its context, or nothing.

  • No vault_id: the organization's rules.
  • A vault_id for a vault that inherits (the default): the organization's rules first, then the vault's own.
  • A vault_id for a vault that does not inherit: the vault's own rules only.

A vault_id you cannot read is treated as none, so the turn runs with organization rules. Injected rule text is real input and counts in usage.input_tokens. Rules are separate from memory: the memory field never affects them. POST /v1/chat/completions never injects rules.

Preview the rules a turn would get. Pass vault_id as a query parameter for a chat inside a vault:

curl https://api.cruxy.ai/api/v1/rules/resolved \
  -H "Authorization: Bearer $CRUXY_API_KEY"

Each rule carries its source, org or vault, so an unexpected instruction traces back to the ruleset that contributed it. An empty rules array is a real answer: there is no default ruleset. Unlike chat, this endpoint answers 404 vault_not_found for a vault_id you cannot read, so a mistyped id is reported rather than resolved for the wrong context.

Know when rules applied

When at least one rule applied, the response carries cruxy.rules_applied: how many rules applied and from which rulesets, never the rule text. The field is absent when nothing was injected. On a stream it rides the role primer.

{
  "cruxy": {
    "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "routed_tier": "vaani",
    "reasoning_effort": "low",
    "rules_applied": {
      "count": 3,
      "sources": [{ "scope": "org", "count": 3 }]
    }
  }
}

Edit the rules

GET /api/v1/rules returns one stored ruleset, the organization's or, with vault_id, a vault's, and PUT /api/v1/rules replaces it whole. Its permissions.can_write tells you whether you may change it: the organization's ruleset is owner or admin only, and a vault's also admits a member the vault grants can_write. A refused write is 403 rules_forbidden.

Rules are re-injected on every request in scope, so each ruleset is capped:

CapLimit
Rules per ruleset50
Characters per rule1000
Characters in total8000

Exceeding a cap is 400 rules_too_large. A rule carrying an email address, a phone number, or a card number is refused with 400 pii_rejected, and nothing is stored. API Reference has every field of the rules endpoints.

Next steps

  • Memory: recall and capture, with the same default split.
  • Get your API key: allowed scopes and other key restrictions.
  • Chat: the rest of the request and the cruxy block.

Was this page helpful?