---
title: HTTP API Reference
description: Complete reference for all Sentinel REST endpoints — suites, cases, runs, baselines, red team, prompts, scenarios, and reports.
---

All endpoints are under `/sentinel` and return JSON. Authentication and tenant resolution depend on your Forge middleware configuration.

## Suites

### `POST /sentinel/suites`

Create a suite.

**Request**

```json
{
  "name": "string (required)",
  "description": "string",
  "system_prompt": "string",
  "model": "string (default: engine default)",
  "temperature": 0,
  "persona_ref": "string (optional)",
  "metadata": {}
}
```

**Response** `201 Created` — Suite object with generated `id`.

---

### `GET /sentinel/suites`

List suites for the current app.

**Query parameters**

| Param | Type | Description |
|-------|------|-------------|
| `limit` | int | Max results (default: 20) |
| `offset` | int | Pagination offset |

**Response** `200 OK` — array of Suite objects.

---

### `GET /sentinel/suites/:id`

Get a suite by ID.

---

### `PUT /sentinel/suites/:id`

Update a suite.

---

### `DELETE /sentinel/suites/:id`

Delete a suite and all associated cases, runs, and baselines.

---

## Cases

### `POST /sentinel/suites/:suiteId/cases`

Create a test case in a suite.

**Request**

```json
{
  "name": "string (required)",
  "input": "string (required)",
  "expected": "string",
  "scenario_type": "standard",
  "scorers": [{"name": "contains", "config": {"substring": "hello"}}],
  "tags": ["tag1"],
  "context": {},
  "metadata": {}
}
```

---

### `GET /sentinel/suites/:suiteId/cases`

List cases for a suite.

---

### `POST /sentinel/suites/:suiteId/cases/import`

Bulk import cases from JSON, CSV, or JSONL format.

**Request** — raw file body with `Content-Type` header indicating format.

---

### `PUT /sentinel/cases/:id`

Update a case.

---

### `DELETE /sentinel/cases/:id`

Delete a case.

---

## Runs

### `POST /sentinel/suites/:suiteId/run`

Execute an evaluation run.

**Request**

```json
{
  "model": "string (optional override)",
  "temperature": 0,
  "target_tenant_id": "string (optional)"
}
```

**Response** `201 Created` — Run object with `state: "running"`.

---

### `GET /sentinel/runs`

List runs with optional filters.

| Param | Type | Description |
|-------|------|-------------|
| `suite_id` | string | Filter by suite |
| `state` | string | Filter by state |
| `limit` | int | Max results |
| `offset` | int | Pagination offset |

---

### `GET /sentinel/runs/:id`

Get a specific run.

---

### `GET /sentinel/runs/:id/results`

List all results for a run.

---

### `GET /sentinel/runs/:id/stats`

Get aggregate statistics for a run.

**Response** `200 OK`

```json
{
  "total_cases": 50,
  "passed": 45,
  "failed": 3,
  "errored": 2,
  "pass_rate": 0.9,
  "avg_score": 0.87,
  "avg_latency_ms": 1200,
  "total_tokens": 50000,
  "total_cost": 2.50,
  "dimension_scores": {"skill": 0.92, "trait": 0.88}
}
```

---

## Baselines

### `POST /sentinel/baselines/:suiteId`

Save a baseline from a run.

---

### `GET /sentinel/baselines/:suiteId`

Get the latest baseline for a suite.

---

### `GET /sentinel/baselines/:suiteId/baselines`

List all baselines for a suite.

---

## Red Team

### `POST /sentinel/redteam/:suiteId/generate`

Generate adversarial test cases for a suite.

---

### `POST /sentinel/redteam/:suiteId/run`

Run adversarial evaluation against the suite's target.

---

## Prompt Versions

### `POST /sentinel/prompts/:suiteId`

Create a new prompt version.

**Request**

```json
{
  "system_prompt": "string (required)",
  "changelog": "string"
}
```

---

### `GET /sentinel/prompts/:suiteId`

List all prompt versions for a suite.

---

### `PUT /sentinel/prompts/:suiteId/current`

Set the current active prompt version.

---

## Scenarios

### `POST /sentinel/scenarios/:suiteId/generate`

Auto-generate test cases for a specific evaluation dimension.

**Request**

```json
{
  "scenario_type": "skill_challenge",
  "count": 10
}
```

---

### `GET /sentinel/scenarios/:suiteId`

List generated scenarios.

---

## Reports

### `GET /sentinel/reports/:runId/report`

Generate a report for a run.

| Param | Type | Description |
|-------|------|-------------|
| `format` | string | `terminal`, `json`, `html`, or `ci` |

---

### `GET /sentinel/reports/:runId/report/export`

Export a report in the specified format.

---

## Error format

All error responses use a consistent JSON envelope:

```json
{
  "error": "human-readable message",
  "code": "ERROR_CODE"
}
```

| HTTP status | `code` | Cause |
|-------------|--------|-------|
| `400` | `BAD_REQUEST` | Missing required field, empty input, invalid state |
| `404` | `NOT_FOUND` | Suite, case, run, or baseline not found |
| `409` | `CONFLICT` | Suite with same name already exists |
| `500` | `INTERNAL_ERROR` | Store or target failure |
