Skip to content

Create Rule Set

Creates rule sets inside a project. Use extractor rule sets to normalize raw usage JSON into subjects, dimensions, and charge items. Use pricing rule sets for fallback rating when extractor-attached pricing is not enough.

Creating a draft does not change production ingestion. Publish the reviewed rule set before using it in production paths.

POST /v1/projects/:project_id/extractor-rule-sets
POST /v1/projects/:project_id/pricing-rule-sets
Terminal window
Authorization: Bearer <api-key>
Content-Type: application/json

Requires rules write access.

Field Required Description
project_id Yes Project that owns the rule set.
Terminal window
curl 'http://127.0.0.1:8080/v1/projects/proj_gateway/extractor-rule-sets' \
-X POST \
-H 'Authorization: Bearer <api-key>' \
-H 'Content-Type: application/json' \
-d '{
"name": "OpenAI extractor",
"subject": {
"default_type": "user",
"type_path": "$.meta.subject_type",
"id_path": "$.meta.user_id",
"required": true
},
"dimensions": [
{"name": "provider", "path": "$.provider", "type": "string", "required": true},
{"name": "model", "path": "$.usage.model", "type": "string", "required": true},
{"name": "org_id", "path": "$.meta.org_id", "type": "string"}
],
"charge_item_extractors": [
{
"name": "input tokens",
"metric": "input_tokens",
"path": "$.usage.prompt_tokens",
"type": "number",
"unit": "token",
"currency": "USD",
"unit_price_expr": "dec(\"0.0000002\")",
"amount_expr": "dec_mul(dec(item[\"quantity\"]), dec(item[\"unit_price\"]))"
},
{
"name": "output tokens",
"metric": "output_tokens",
"path": "$.usage.output_tokens",
"type": "number",
"unit": "token",
"currency": "USD",
"unit_price_expr": "dec(\"0.0000008\")",
"amount_expr": "dec_mul(dec(item[\"quantity\"]), dec(item[\"unit_price\"]))"
}
]
}'
Field Required Description
name No Display name.
template_id No Extractor template ID to expand into this rule set.
effective_from No Effective time as Unix seconds. Defaults to create time.
subject No Subject extraction config.
dimensions No Dimension extraction configs.
charge_item_extractors No Charge item extraction and optional attached pricing configs.

Create requests are configuration-only. The service accepts only the documented request fields, including nested subject, dimensions, and charge_item_extractors fields. Unknown fields and system-managed fields such as id, version, status, tenant ID, and project ID are rejected with 400 Bad Request.

The service generates the rule set id, version, and status, then returns them in the response and list endpoints.

subject accepts the following fields:

Field Required Description
type_path No JSON path used to read the subject type. A present value must be a string matching [a-z][a-z0-9_]{0,63}.
default_type No Fallback subject type when type_path is missing, null, or empty.
id_path No JSON path used to read the subject ID. A present value must be a string.
default_id No Fallback subject ID when id_path is missing, null, or empty.
required No When true, normalization fails unless fallback resolution produces both a subject type and subject ID. Incomplete optional subjects are discarded as a pair.
{
"id": "ers_openai",
"tenant_id": "t_001",
"project_id": "proj_gateway",
"name": "OpenAI extractor",
"version": 1,
"status": "draft",
"effective_from": 1781222400,
"subject": {
"default_type": "user",
"type_path": "$.meta.subject_type",
"id_path": "$.meta.user_id",
"required": true
},
"dimensions": [
{
"name": "provider",
"path": "$.provider",
"type": "string",
"required": true
},
{
"name": "model",
"path": "$.usage.model",
"type": "string",
"required": true
}
],
"charge_item_extractors": [
{
"name": "input tokens",
"metric": "input_tokens",
"path": "$.usage.prompt_tokens",
"type": "number",
"unit": "token",
"currency": "USD",
"unit_price_expr": "dec(\"0.0000002\")",
"amount_expr": "dec_mul(dec(item[\"quantity\"]), dec(item[\"unit_price\"]))"
}
],
"created_at": 1781222400
}
Terminal window
curl 'http://127.0.0.1:8080/v1/projects/proj_gateway/pricing-rule-sets' \
-X POST \
-H 'Authorization: Bearer <api-key>' \
-H 'Content-Type: application/json' \
-d '{
"extractor_rule_set_id": "ers_openai",
"name": "OpenAI fallback pricing",
"currency": "USD",
"rules": [
{
"name": "Input tokens",
"priority": 10,
"metric": "input_tokens",
"match_expr": "dimensions[\"model\"] == \"gpt-4.1-mini\"",
"unit_price_expr": "dec(\"0.0000002\")",
"amount_expr": "dec_mul(dec(item[\"quantity\"]), dec(item[\"unit_price\"]))"
}
]
}'
Field Required Description
extractor_rule_set_id Yes Extractor rule set this pricing rule set is bound to.
name No Display name.
currency No Default currency. Defaults to USD.
effective_from No Effective time as Unix seconds. Defaults to create time.
rules No Pricing rules, sorted by priority before storing.

Pricing create requests are configuration-only. The service accepts only the documented request fields, including nested rules fields. Unknown fields and system-managed fields such as id, version, status, tenant ID, project ID, and child pricing rule IDs are rejected with 400 Bad Request.

The service generates the pricing rule set id, version, and status, then returns them in the response and list endpoints. Individual pricing rules are audited by the rule set ID/version plus the matched metric.

{
"id": "prs_openai_fallback",
"tenant_id": "t_001",
"project_id": "proj_gateway",
"extractor_rule_set_id": "ers_openai",
"name": "OpenAI fallback pricing",
"version": 1,
"status": "draft",
"currency": "USD",
"effective_from": 1781222400,
"rules": [
{
"name": "Input tokens",
"priority": 10,
"metric": "input_tokens",
"match_expr": "dimensions[\"model\"] == \"gpt-4.1-mini\"",
"amount_expr": "dec_mul(dec(item[\"quantity\"]), dec(item[\"unit_price\"]))",
"unit_price_expr": "dec(\"0.0000002\")"
}
],
"created_at": 1781222400
}
  • Use Test Rules before publishing a new rule set.
  • For stable high-volume metrics, prefer extractor charge items with attached pricing. Pricing rule sets are the advanced fallback path.