---
title: "Test which pricing definition matches a model name and calculate cost"
method: POST
path: "/api/{org_id}/llm/models/test"
tags: ["LLM"]
---

# Test which pricing definition matches a model name and calculate cost

`POST /api/{org_id}/llm/models/test`

## Request

- Base URL: `https://api.openobserve.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.openobserve.ai/api/{org_id}/llm/models/test`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/openobserve/apis/openobserve-api-http/docs/api/:org_id/llm/models/test/post.ts> (a function with typed inputs; its response is checked against the schema)

Simulates the pricing lookup for a given model name and optional usage data, returning the matched definition, selected tier, and cost breakdown. With `match_pattern`, also lists the known models that pattern would price if saved as a rule in this organization.

## Path parameters

- `org_id` string, required

## Request body

- TestModelMatchRequest: Request body for the test-model-match endpoint.
  - `attributes` object: Optional span attributes (e.g. {"openai.response.service_tier": "flex"}) for tier rules.
  - `match_pattern` string, nullable: An unsaved rule pattern to preview. When set, the response lists in `captured_models` every known model this pattern would price if it were saved in this org. The `model_name` test is unaffected and still runs against the saved rules.
  - `model_name` string: The model name to test (e.g. "gpt-4o", "claude-opus-3-5"). Empty skips the single-name test, e.g. when only previewing `match_pattern`.
  - `rule_id` string, nullable: Id of the rule being edited. It is left out of the preview, so its saved pattern does not compete with the edited one.
  - `timestamp` integer, nullable: Optional span timestamp in microseconds. When provided, only definitions whose `valid_from` <= timestamp are considered, and tiers restricted to recurring UTC time-of-day windows (peak / off-peak) are resolved against it.
  - `usage` object: Optional token counts keyed by usage type (e.g. {"input": 1000, "output": 500}). When provided, cost is calculated using the matched pricing definition.

## Response `200`

Success

- TestModelMatchResponse: Response for the test-model-match endpoint.
  - `captured_models` CapturedModel[], required: The known models the previewed `match_pattern` would price, the model the pattern names first. Empty when no pattern was sent.
    - `match_kind` 'approximate' | 'exact', required: How a pricing pattern matched a model name. Ordered so that `Exact > Approximate`: when several patterns of the same source match, an exact match wins.
    - `model_name` string, required: A model name some pricing rule is written for.
    - `primary` boolean, required: True for the model the pattern itself names (its literal text); false for every other model the pattern also catches.
    - `replaces` PricingRuleRef: The name and source of a pricing rule.
      - `name` string, required
      - `source` 'built_in' | 'meta_org' | 'org', required: Ownership source of a model pricing definition.
  - `costs` object, required: Per-usage-key costs (excluding "total").
  - `match_kind` 'approximate' | 'exact': How a pricing pattern matched a model name. Ordered so that `Exact > Approximate`: when several patterns of the same source match, an exact match wins.
  - `matched` ModelPricingDefinition: A model pricing definition that maps model names (via regex) to pricing tiers.
    - `children` object[]: Definitions shadowed by this one (same match_pattern, lower source/sort priority). Only populated in list responses — not stored in the database.
    - `created_at` integer: Created timestamp in microseconds
    - `description` string: Human-readable description. Populated for built-in entries.
    - `enabled` boolean: Whether this definition is active
    - `id` string, nullable: Unique identifier (KSUID)
    - `match_pattern` string: Regex pattern to match model names from incoming spans. Example: "(?i)^gpt-4o" or "(?i)^(claude-sonnet-4-6)$" Max length: 512 characters.
    - `name` string: Display name for the model (e.g., "GPT-4o", "Claude Sonnet 4.6")
    - `org_id` string: Organization ID
    - `provider` string: Provider name (e.g., "OpenAI", "Anthropic"). Populated for built-in entries.
    - `sort_order` integer: Explicit sort order for deterministic tie-breaking when multiple definitions match the same model name and have equal (or absent) `valid_from` values. Lower values are checked first; the first match wins. Defaults to 0 — set a lower number to make a definition take priority.
    - `source` 'built_in' | 'meta_org' | 'org': Ownership source of a model pricing definition.
    - `tiers` PricingTierDefinition[]: Pricing tiers; `ranks_tiers()` decides between first-match and highest-rank selection.
      - `condition` TierCondition: Condition for a pricing tier.
        - `operator` 'gt' | 'gte' | 'lt' | 'lte' | 'eq' | 'neq': Comparison operators for tier conditions.
        - `usage_key` string: The usage key to evaluate (e.g., "input")
        - `value` number, double: Threshold value (e.g., 200000 for extended context pricing)
      - `name` string: Display name for this tier (e.g., "Default", "Extended Context")
      - `prices` object: Prices per token, keyed by usage type. Keys must exactly match usage keys produced by the span extractor: "input", "output", "cache_read_input_tokens", "cache_creation_input_tokens", etc. Values are price per single token (e.g., 0.000003 = $3/1M tokens). **Precision note:** `f64` provides ~15 significant decimal digits, which is more than sufficient for cost *estimation* on observability data. These values are not used for billing or financial accounting — they produce approximate cost figures for dashboards and alerts. The multiplication `token_count as f64 * price` is exact for token counts < 2^53 (~9 quadrillion), well beyond practical span sizes.
      - `priority` integer: Breaks ties between matching tiers before the restriction count; higher wins.
      - `rules` TierRule[]: Span-attribute rules (service tier, speed, region) that must all hold.
        - `keys` string[]: Attribute keys tried in order; compared ignoring case and `_`/`-`/`.` separators.
        - `op` 'in' | 'not_in' | 'exists' | 'not_exists' | 'gt' | 'gte' | 'lt' | 'lte' | 'unknown': Operators for [`TierRule`].
        - `value` number, double, nullable: Threshold for the numeric operators.
        - `values` string[]: Accepted values for `in` / `not_in`, compared trimmed and case-insensitively.
      - `utc_windows` UtcTimeWindow[]: Recurring UTC time-of-day windows during which this tier applies. Empty (the default) means the tier is not time-restricted. Providers such as DeepSeek publish "peak" and "off-peak" rates that repeat every day, which is a time-of-day range rather than an absolute cutover (that is what `valid_from` is for). A tier applies when the span falls in ANY of its windows *and* its `condition` (if set) passes, so windows compose with context-length tiering.
        - `end_minute` integer: Exclusive end, minutes since UTC midnight (0–1440).
        - `start_minute` integer: Inclusive start, minutes since UTC midnight (0–1440).
    - `updated_at` integer: Updated timestamp in microseconds
    - `valid_from` integer, nullable: Optional Unix timestamp (microseconds) from which this definition is valid. When multiple definitions match the same model name, the one with the greatest `valid_from` that is still <= the span's start time is used. If None, the definition is valid for all time.
  - `tier` string, nullable: The name of the selected pricing tier, or null if no definition matched.
  - `tier_index` integer, nullable: Index of the selected tier in `matched.tiers`, which stays unambiguous when names repeat.
  - `total_cost` number, double, required: Sum of all per-key costs.

## Other responses

- `500`: Internal server error

---

[API](https://skmtc.dev/openobserve/apis/openobserve-api-http.md) - [All operations](https://skmtc.dev/openobserve/apis/openobserve-api-http/llms.txt) - [OpenAPI document](https://skmtc.dev/openobserve/apis/openobserve-api-http/revisions/0529b8a10252?raw)
