# Test case search API

> Cross-suite test case search with full-text q and custom-field cf filters.

The search endpoint returns test cases across all suites of a project in a single request — no cursor, no lazy tree loading. It is designed for the repository filter bar but available to any integrator needing cross-suite access.

## Search

`GET /api/v1/projects/{projectId}/test-cases/search`

`{projectId}` is the project **code** (for example `ACME`).

### Query parameters

| Parameter      | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `q`            | Substring match applied according to `scope`. Blank values are ignored.                                                                                                                                                                                                                                                                                                                                                                                |
| `scope`        | `all` (default), `cases`, or `suites`. With `cases`, `q` matches `title` OR `display_id`. With `suites`, `q` matches the parent suite name and returns its cases (unassigned cases never match). With `all`, both predicates are ORed. Has no effect without a non-blank `q`. Unknown values return `422 validation_failed`.                                                                                                                           |
| `cf`           | Repeatable. Each entry is `<fieldUlid>:<value[,value…]>`. Matches custom fields of entity `test_case`. Option-based fields accept option ULIDs; `checkbox` accepts `true`/`false`; `user_picker` accepts a user ULID. The sentinel `empty` matches cases with no stored row for that field. Entries AND-compose across fields; values within one entry OR-compose. Invalid field, unsupported type, or foreign option returns `422 validation_failed`. |
| `reviewStatus` | Comma-separated review statuses: `not_reviewed`, `in_review`, `approved`. Only cases with one of them match. An unknown value returns `422 validation_failed`.                                                                                                                                                                                                                                                                                         |
| `limit`        | Integer 1–200, default 50. Out-of-range values return `422 validation_failed`.                                                                                                                                                                                                                                                                                                                                                                         |

### Response

```json
{
  "items": [...],
  "total": 42
}
```

`items` contains full test case objects (same shape as the detail endpoint, including `suiteUlid`, `customFieldValues` and `reviewStatus`), ordered by ULID ascending. Archived cases are excluded.

`total` is the full match count regardless of `limit`. When `total` exceeds `items.length`, the UI shows a cap notice prompting filter refinement.

### Example

```bash
curl -sS \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/projects/ACME/test-cases/search?q=login&cf=<priorityFieldUlid>:<highOptionUlid>"
```
