/*
* server
*
* ## Authentication Authenticate with the API using [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), get API keys in the project settings: - username: Langfuse Public Key - password: Langfuse Secret Key ## Exports - OpenAPI spec: https://cloud.langfuse.com/generated/api/openapi.yml - Self-hosted deployments: interactive API reference at `/api/docs` and OpenAPI spec at `/api/openapi.yaml`
*
* The version of the OpenAPI document:
*
* Generated by: https://openapi-generator.tech
*/
use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};
/// struct for typed errors of method [`unstable_evaluation_rules_create`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnstableEvaluationRulesCreateError {
Status400(serde_json::Value),
Status401(serde_json::Value),
Status403(serde_json::Value),
Status404(serde_json::Value),
Status405(serde_json::Value),
Status409(models::UnstablePublicApiError),
Status422(models::UnstablePublicApiError),
Status429(models::UnstablePublicApiError),
Status500(models::UnstablePublicApiError),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`unstable_evaluation_rules_delete`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnstableEvaluationRulesDeleteError {
Status400(serde_json::Value),
Status401(serde_json::Value),
Status403(serde_json::Value),
Status404(serde_json::Value),
Status405(serde_json::Value),
Status429(models::UnstablePublicApiError),
Status500(models::UnstablePublicApiError),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`unstable_evaluation_rules_get`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnstableEvaluationRulesGetError {
Status400(serde_json::Value),
Status401(serde_json::Value),
Status403(serde_json::Value),
Status404(serde_json::Value),
Status405(serde_json::Value),
Status429(models::UnstablePublicApiError),
Status500(models::UnstablePublicApiError),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`unstable_evaluation_rules_list`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnstableEvaluationRulesListError {
Status400(serde_json::Value),
Status401(serde_json::Value),
Status403(serde_json::Value),
Status404(serde_json::Value),
Status405(serde_json::Value),
Status429(models::UnstablePublicApiError),
Status500(models::UnstablePublicApiError),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`unstable_evaluation_rules_update`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnstableEvaluationRulesUpdateError {
Status400(serde_json::Value),
Status401(serde_json::Value),
Status403(serde_json::Value),
Status404(serde_json::Value),
Status405(serde_json::Value),
Status422(models::UnstablePublicApiError),
Status429(models::UnstablePublicApiError),
Status500(models::UnstablePublicApiError),
UnknownValue(serde_json::Value),
}
/// **Deprecated:** On Langfuse Cloud, this unstable endpoint is deprecated and will be removed on September 4, 2026. Use the stable `/api/public/v2/evaluation-rules` API instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4). Create an evaluation rule. An evaluation rule defines **what** incoming data should be evaluated and **how prompt variables should be populated** from that data. Use this resource after choosing an evaluator from the evaluator endpoints. Key rules: - `name` must be unique within the project for public evaluation rules - `target` must be `observation` or `experiment` - provide either the compatibility `evaluator` field or the new `evaluators` array, never both - each evaluator `name` + `type` must identify an existing evaluator family returned by the evaluator endpoints - Langfuse resolves that family to its latest version before saving the evaluation rule - for `target=experiment`, use dataset `id` values from `GET /api/public/v2/datasets` when filtering by `datasetId` - an omitted LLM-as-judge assignment mapping inherits the evaluator version's default mapping - the effective mapping must map every evaluator prompt variable exactly once - for `code` evaluators, Langfuse uses the fixed code runtime mapping; omit `mapping` in create and update requests - for user-provided `llm_as_judge` mappings, `expected_output` and `experiment_item_metadata` are only valid for `target=experiment` - if `enabled=true`, Langfuse validates that the referenced evaluator can currently run - at most 500 evaluation rules can be effectively active in one project at the same time (enforced identically by the API, the MCP tools, and the app) If an evaluation rule with the same `name` already exists in the project, the API returns `409`. In that case, update the existing resource with `PATCH /api/public/unstable/evaluation-rules/{evaluationRuleId}` instead of creating a second one. If enabling this resource would exceed the 500-active limit, the API also returns `409`. In that case, disable or pause another active evaluation rule before enabling a new one. Current scope: - evaluation rules are live-ingestion rules only - they do not trigger historical backfills Recovery guidance: - `400 invalid_filter_value`: fix the filter `column` or `value` using `details.column`, `details.invalidValues`, and `details.allowedValues` - `400 invalid_filter_value` with `details.column=datasetId`: call `GET /api/public/v2/datasets`, then retry with dataset `id` values from that response - `400 missing_variable_mapping`: for `llm_as_judge` evaluators, fetch the evaluator again and make sure every variable in `variables` appears exactly once in `mapping` - `400 duplicate_variable_mapping`: remove repeated mappings for the same variable - `400 invalid_variable_mapping`: for `llm_as_judge`, switch to a valid `source` for the selected `target`, or fix the variable name - `400 invalid_json_path`: remove or correct the `jsonPath` - `422 evaluator_preflight_failed`: the selected evaluator cannot run with the resolved model configuration. Fix the evaluator/default model setup, then retry the create request.
#[deprecated]
#[bon::builder]
pub async fn unstable_evaluation_rules_create(
configuration: &configuration::Configuration,
unstable_create_evaluation_rule_request: models::UnstableCreateEvaluationRuleRequest,
) -> Result<models::UnstableEvaluationRule, Error<UnstableEvaluationRulesCreateError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_unstable_create_evaluation_rule_request = unstable_create_evaluation_rule_request;
let uri_str = format!(
"{}/api/public/unstable/evaluation-rules",
configuration.base_path
);
let mut req_builder = configuration
.client
.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref auth_conf) = configuration.basic_auth {
req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
};
req_builder = req_builder.json(&p_body_unstable_create_evaluation_rule_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRule`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRule`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UnstableEvaluationRulesCreateError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// **Deprecated:** On Langfuse Cloud, this unstable endpoint is deprecated and will be removed on September 4, 2026. Use the stable `/api/public/v2/evaluation-rules` API instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4). Delete an evaluation rule. This removes the live-ingestion rule only. It does not delete the referenced evaluator.
#[deprecated]
#[bon::builder]
pub async fn unstable_evaluation_rules_delete(
configuration: &configuration::Configuration,
evaluation_rule_id: &str,
) -> Result<models::UnstableDeleteEvaluationRuleResponse, Error<UnstableEvaluationRulesDeleteError>>
{
// add a prefix to parameters to efficiently prevent name collisions
let p_path_evaluation_rule_id = evaluation_rule_id;
let uri_str = format!(
"{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
configuration.base_path,
evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref auth_conf) = configuration.basic_auth {
req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableDeleteEvaluationRuleResponse`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableDeleteEvaluationRuleResponse`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UnstableEvaluationRulesDeleteError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// **Deprecated:** On Langfuse Cloud, this unstable endpoint is deprecated and will be removed on September 4, 2026. Use the stable `/api/public/v2/evaluation-rules` API instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4). Get one evaluation rule by its identifier. Use this endpoint to inspect the current evaluator, target, mapping, filters, execution timing, and effective runtime status. Legacy `trace` and `dataset` rules are returned for migration and are read-only through this API.
#[deprecated]
#[bon::builder]
pub async fn unstable_evaluation_rules_get(
configuration: &configuration::Configuration,
evaluation_rule_id: &str,
) -> Result<models::UnstableReadableEvaluationRule, Error<UnstableEvaluationRulesGetError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_evaluation_rule_id = evaluation_rule_id;
let uri_str = format!(
"{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
configuration.base_path,
evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref auth_conf) = configuration.basic_auth {
req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableReadableEvaluationRule`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableReadableEvaluationRule`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UnstableEvaluationRulesGetError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// **Deprecated:** On Langfuse Cloud, this unstable endpoint is deprecated and will be removed on September 4, 2026. Use the stable `/api/public/v2/evaluation-rules` API instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4). List evaluation rules in the authenticated project. This includes legacy `trace` and `dataset` rules so they can be inspected and migrated to v4 rules. Legacy rules are read-only through this API; create, update, and delete continue to support only `observation` and `experiment` rules.
#[deprecated]
#[bon::builder]
pub async fn unstable_evaluation_rules_list(
configuration: &configuration::Configuration,
page: Option<i32>,
limit: Option<i32>,
) -> Result<models::UnstableEvaluationRules, Error<UnstableEvaluationRulesListError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_query_page = page;
let p_query_limit = limit;
let uri_str = format!(
"{}/api/public/unstable/evaluation-rules",
configuration.base_path
);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_query_page {
req_builder = req_builder.query(&[("page", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_query_limit {
req_builder = req_builder.query(&[("limit", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref auth_conf) = configuration.basic_auth {
req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRules`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRules`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UnstableEvaluationRulesListError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
/// **Deprecated:** On Langfuse Cloud, this unstable endpoint is deprecated and will be removed on September 4, 2026. Use the stable `/api/public/v2/evaluation-rules` API instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4). Update an evaluation rule. Typical uses: - enable or disable live execution - switch to another evaluator - adjust sampling - change filters - update LLM-as-judge variable mappings Important behavior: - provide only the fields you want to change - if you provide `evaluator`, Langfuse resolves that evaluator family to its latest version before saving - changing `target`, `filter`, or an LLM-as-judge `mapping` must still produce a valid target-specific configuration - if you change `target` for an LLM-as-judge rule, also send a compatible `filter` and `mapping` in the same request unless the existing ones are still valid for the new target - for `code` evaluator rules, omit `mapping`; Langfuse stores the fixed code runtime mapping automatically - if the resulting config is enabled, Langfuse re-validates that the selected evaluator can run - if the update would move a non-active evaluation rule into the active state and the project already has 500 active evaluation rules, the API returns `409` Recovery guidance: - if an LLM-as-judge update fails with `missing_variable_mapping` or `invalid_variable_mapping` after changing `evaluator` or `target`, resend the request with a complete new `mapping` - if the update fails with `invalid_filter_value` after changing `target`, resend the request with a target-compatible `filter`
#[deprecated]
#[bon::builder]
pub async fn unstable_evaluation_rules_update(
configuration: &configuration::Configuration,
evaluation_rule_id: &str,
unstable_update_evaluation_rule_request: models::UnstableUpdateEvaluationRuleRequest,
) -> Result<models::UnstableReadableV2EvaluationRule, Error<UnstableEvaluationRulesUpdateError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_path_evaluation_rule_id = evaluation_rule_id;
let p_body_unstable_update_evaluation_rule_request = unstable_update_evaluation_rule_request;
let uri_str = format!(
"{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
configuration.base_path,
evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
);
let mut req_builder = configuration
.client
.request(reqwest::Method::PATCH, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref auth_conf) = configuration.basic_auth {
req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
};
req_builder = req_builder.json(&p_body_unstable_update_evaluation_rule_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableReadableV2EvaluationRule`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableReadableV2EvaluationRule`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<UnstableEvaluationRulesUpdateError> =
serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}