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.
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
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
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
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
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.
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) |