Skip to content

Style Rules

Style rule sets let you enforce concrete, checkable writing conventions on your translations — capitalization, address forms, number formatting, terminology consistency, and free-text instructions. Unlike style references (which describe tone by example), style rules are explicit rules that the QA stage checks and corrects.

Each rule belongs to a rule set. A set can be scoped to specific target languages and can be marked mandatory so it applies to every job in the account.

Common use cases:

  • Force sentence-case (or title-case) headlines
  • Pin the address form (formal/informal) per language
  • Enforce a decimal separator (, vs .)
  • Keep recurring terms translated consistently
  • Add free-text instructions the QA agent must honor

The Style Rule object

A rule set contains a list of rules. Each rule has this shape:

Field Type Required Description
id string no Auto-generated (rule_xxxxxxxx) if omitted
type string yes Rule type key from the catalog (e.g. cap.segment_start)
params object no Type-specific parameters (see the params_schema of each catalog entry)
target_lang string no Restrict this rule to one target language; must fall within the set's target_langs
text string no Free-text instruction — only for type: custom.freetext
example_source string no Optional example (source side)
example_target string no Optional example (target side)
enabled boolean no Defaults to true

List the rule catalog

GET /v1/style-rules/catalog

Returns every available rule type with its label, description, check strength, allowed enum values, and parameter schema. Use this to build dynamic forms. No authentication required.

curl -X GET https://api.falara.io/v1/style-rules/catalog
resp = requests.get("https://api.falara.io/v1/style-rules/catalog")
catalog = resp.json()
const resp = await fetch("https://api.falara.io/v1/style-rules/catalog");
const catalog = await resp.json();

Response 200 OK

{
  "types": [
    {
      "key": "cap.segment_start",
      "label": "Capitalize segment start",
      "description": "First letter of each segment is uppercase.",
      "check_strength": "deterministic",
      "enum_values": [],
      "params_schema": []
    },
    {
      "key": "register.address_form",
      "label": "Address form",
      "description": "Pin the formal/informal address form per language.",
      "check_strength": "llm",
      "enum_values": [],
      "params_schema": [
        { "key": "value", "kind": "enum", "required": true, "per_target_lang": true }
      ]
    }
  ],
  "address_forms": {
    "de": ["du", "Sie"],
    "fr": ["tu", "vous"]
  }
}
Field Type Description
types[].key string Rule type key used as a rule's type
types[].label string Human-readable name
types[].description string What the rule checks
types[].check_strength string deterministic (regex-style check), llm (model-judged), or none
types[].enum_values array Allowed values for enum-style params (if any)
types[].params_schema array Parameter descriptors for the rule's params object
address_forms object Allowed address-form values per language (for register.address_form)

Available rule types

cap.segment_start, cap.after_pipe, cap.preserve_allcaps, cap.quoted_terms, cap.headline_titlecase, register.address_form, register.idiomatic, format.slug, format.decimal_separator, format.foreign_phrases, consistency.recurring_terms, consistency.parallel_structures, custom.freetext. Always read the live catalog for the authoritative list and parameters.


Create a style rule set

POST /v1/style-rules

Authentication: X-API-Key header Status: 201 Created

curl -X POST https://api.falara.io/v1/style-rules \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "German web copy",
    "description": "House style for DE marketing pages",
    "target_langs": ["de"],
    "rules": [
      { "type": "register.address_form", "params": { "value": "Sie" }, "target_lang": "de" },
      { "type": "format.decimal_separator", "params": { "value": "," } },
      { "type": "custom.freetext", "text": "Never translate the product name \"Falara\"." }
    ]
  }'
resp = requests.post(
    "https://api.falara.io/v1/style-rules",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "name": "German web copy",
        "description": "House style for DE marketing pages",
        "target_langs": ["de"],
        "rules": [
            {"type": "register.address_form", "params": {"value": "Sie"}, "target_lang": "de"},
            {"type": "format.decimal_separator", "params": {"value": ","}},
            {"type": "custom.freetext", "text": 'Never translate the product name "Falara".'},
        ],
    },
)
rule_set = resp.json()
const resp = await fetch("https://api.falara.io/v1/style-rules", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "German web copy",
    description: "House style for DE marketing pages",
    target_langs: ["de"],
    rules: [
      { type: "register.address_form", params: { value: "Sie" }, target_lang: "de" },
      { type: "format.decimal_separator", params: { value: "," } },
      { type: "custom.freetext", text: 'Never translate the product name "Falara".' },
    ],
  }),
});
const ruleSet = await resp.json();

Request Body

Field Type Required Description
name string yes Set name (1–120 characters)
description string no Optional description
mandatory boolean no If true, applies to all jobs in the account. Owner/admin only. Defaults to false
target_langs array no Languages this set applies to. null = all languages; if given, must contain at least one
rules array no List of rule objects (max 50 per set)

Response 201 Created — returns the full set:

{
  "id": "a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
  "name": "German web copy",
  "description": "House style for DE marketing pages",
  "mandatory": false,
  "target_langs": ["de"],
  "rules": [
    { "id": "rule_a1b2c3d4", "type": "register.address_form", "params": { "value": "Sie" }, "target_lang": "de", "text": null, "example_source": null, "example_target": null, "enabled": true }
  ],
  "created_at": "2026-06-17T09:30:00Z",
  "updated_at": "2026-06-17T09:30:00Z"
}

Mandatory sets cannot collide

Two mandatory sets may not declare the same rule type for an overlapping target language. A conflicting create/update returns 422 naming the colliding set. custom.freetext rules never collide.


List style rule sets

GET /v1/style-rules

Returns all sets for the current API key. The list view omits the rules array and adds a rule_count instead.

Authentication: X-API-Key header Status: 200 OK

curl -X GET https://api.falara.io/v1/style-rules \
  -H "X-API-Key: YOUR_API_KEY"
resp = requests.get(
    "https://api.falara.io/v1/style-rules",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
sets = resp.json()
const resp = await fetch("https://api.falara.io/v1/style-rules", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const sets = await resp.json();

Response 200 OK

[
  {
    "id": "a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
    "name": "German web copy",
    "description": "House style for DE marketing pages",
    "mandatory": false,
    "target_langs": ["de"],
    "rule_count": 3,
    "created_at": "2026-06-17T09:30:00Z",
    "updated_at": "2026-06-17T09:30:00Z"
  }
]

Get a style rule set

GET /v1/style-rules/{set_id}

Returns a single set including its full rules array.

Authentication: X-API-Key header Status: 200 OK

curl -X GET https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f \
  -H "X-API-Key: YOUR_API_KEY"
resp = requests.get(
    "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
rule_set = resp.json()
const resp = await fetch(
  "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const ruleSet = await resp.json();

Update a style rule set

PATCH /v1/style-rules/{set_id}

Send only the fields you want to change. Omitted fields are left untouched; passing rules replaces the entire rule list.

Authentication: X-API-Key header Status: 200 OK

curl -X PATCH https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Updated DE house style" }'
resp = requests.patch(
    "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"description": "Updated DE house style"},
)
const resp = await fetch(
  "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
  {
    method: "PATCH",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ description: "Updated DE house style" }),
  }
);

Request Body (all fields optional)

Field Type Description
name string New name (1–120 characters)
description string New description
mandatory boolean Toggle mandatory. Owner/admin only (also required to unset an existing mandatory set)
target_langs array New language scope (null = all)
rules array Replaces the full rule list (max 50)

Delete a style rule set

DELETE /v1/style-rules/{set_id}

Authentication: X-API-Key header Status: 204 No Content

curl -X DELETE https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f \
  -H "X-API-Key: YOUR_API_KEY"
resp = requests.delete(
    "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
assert resp.status_code == 204
await fetch(
  "https://api.falara.io/v1/style-rules/a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);

Applying rule sets to a job

Non-mandatory sets are opt-in per request: pass their IDs in style_rule_set_ids when (re)translating. Mandatory sets always apply and need not be listed. The field is accepted on retranslate (single and batch) and on synchronous translation.

curl -X POST https://api.falara.io/v1/jobs/{job_id}/retranslate \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "style_rule_set_ids": ["a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f"]
  }'
resp = requests.post(
    "https://api.falara.io/v1/jobs/<job_id>/retranslate",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"style_rule_set_ids": ["a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f"]},
)
const resp = await fetch(
  "https://api.falara.io/v1/jobs/<job_id>/retranslate",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      style_rule_set_ids: ["a3f1c2e8-7b9d-4e10-8c5a-1f2b3c4d5e6f"],
    }),
  }
);

Errors

Status Reason
401 Unauthorized Missing or invalid API key
403 Forbidden Only an owner/admin may create or toggle a mandatory set
404 Not Found Rule set ID does not exist
422 Unprocessable Entity Validation error (unknown rule type, >50 rules, empty target_langs, rule target_lang outside set scope, or a mandatory collision)