> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
title: "Create a quality case"
description: "Open a quality case, optionally linked to the run or score that surfaced it."
method: "POST"
endpoint: "/api/v1/projects/:projectId/quality/cases"
order: 2
last_verified: 2026-07-27
---

<ApiEndpoint
  method="POST"
  endpoint="/api/v1/projects/:projectId/quality/cases"
  description="Open a quality case, optionally linked to the run or score that surfaced it."
>
  <section>
    ### Body parameters

    <ApiAttribute name="title" type="string" description="A short summary of the issue." required={true} />
    <ApiAttribute name="description" type="string" description="What's wrong and where it was observed." required={false} />
    <ApiAttribute name="severity" type="string" description="e.g. low, medium, high, critical." required={false} />
    <ApiAttribute name="category" type="string" description="One of behavior_quality, eval_regression, production_failure, deployment_health, runtime_infra, support_request, release_risk. Defaults to production_failure." required={false} />
    <ApiAttribute name="source_type" type="string" description="One of runtime_run, eval_run_item, eval_alert, guardrail_decision, deployment, deployment_failure, worker_health, runtime_cluster, behavior_topic, manual, support_ticket. Defaults to manual." required={false} />
    <ApiAttribute name="experiment_run_id" type="string" description="The experiment run that surfaced this case, if any." required={false} />
    <ApiAttribute name="experiment_run_item_id" type="string" description="The specific run item that failed, if any." required={false} />
    <ApiAttribute name="expected_behavior" type="string" description="What should have happened." required={false} />
    <ApiAttribute name="observed_behavior" type="string" description="What actually happened." required={false} />
  </section>

  <Callout type="info">
`category` and `source_type` are only validated at the database layer, not by the API itself. An unlisted value doesn't return a clean `400` — it surfaces as a generic insert error.
  </Callout>

  <section>
    ### Request example

    <MultiLanguageCodeBlock
      languages={["bash", "javascript"]}
      value={[
        {
          language: 'bash',
          code: `curl -X POST https://api.agnt5.com/api/v1/projects/b6f1a3e2-.../quality/cases \\
  -H "X-API-KEY: {api_key}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "title": "Vendor name misread on scanned invoices with logos",
    "severity": "high",
    "experiment_run_id": "7f6e5d4c-..."
  }'`
        },
        {
          language: 'javascript',
          code: `fetch(\`https://api.agnt5.com/api/v1/projects/\${projectId}/quality/cases\`, {
  method: 'POST',
  headers: { 'X-API-KEY': apiKey, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'Vendor name misread on scanned invoices with logos',
    severity: 'high',
    experiment_run_id: experimentRunId
  })
})`
        }
      ]}
    />
  </section>
</ApiEndpoint>
