---
title: "Search the cards of a workspace by a word (any member; any token scope)"
method: GET
path: "/api/workspaces/{slug}/cards"
tags: ["Cards"]
---

# Search the cards of a workspace by a word (any member; any token scope)

`GET /api/workspaces/{slug}/cards`

## Request

- Base URL: `https://tre-app.com`
- URL: `https://tre-app.com/api/workspaces/{slug}/cards`
- Auth: HTTP bearer

The REST twin of MCP `list_cards` with `workspace` in place of `boardId` (design record 2026-09-25-workspace-lexical-search-design): one query over every non-archived board the caller can read in the workspace — public boards plus the private ones they are a member of — never a fan-out. Requires `textContains` and `view=summary`, and nothing else: the per-board filters (`titleContains`, `updatedSince`, `citing`, `includeDeleted`) are refused beside the workspace address by name, 400 VALIDATION_ERROR, exactly as MCP refuses them (the shared `workspaceCardListQuerySchema` in lib/schemas/card.ts). Answers `{ cards, truncated }`: the `CardSummary` rows of the per-board search — `match: { field, snippet }` included, same fields, same precedence, same snippet — each with `boardId` and `board` (the board's slug), ranked by the field that holds every word of the search — title, then an `ALIASES:` line, the description, a comment, a checklist item, a subtask title, and last the cards whose words are spread over several fields — most recently updated first within a rank, at most 50, so the cap keeps the best hits (since 2026-10-16; before, time alone). `truncated: true` means more matched than the cap lists (add a word); `truncated: false` is a statement of absence: no other live card on the boards you can read carries every word. Archived boards are out of a search as they are out of a listing. A slug the caller does not belong to, and any slug but its audience for a workspace-bound token, answers 404 NOT_FOUND like an unknown one.

## Query parameters

- `textContains` string, required
- `view` 'summary', required

## Response `200`

Success

- WorkspaceCardSearchResponse
  - `cards` object[], required
    - `id` string, uuid, required
    - `cardKey` string, required
    - `title` string, required
    - `listId` string, uuid, required
    - `startDate` string, date, nullable, required
    - `endDate` string, date, nullable, required
    - `scheduleState` 'unclassified' | 'planned' | 'suspended' | 'cancelled', required: Meaning of the retained schedule. Unclassified means its intent has not been reviewed; suspended/cancelled retain the plan for retrospective comparison.
    - `actualStartDate` string, date, nullable, required: Observed start, explicitly recorded from evidence. Independent of the schedule; null means unknown, never not started.
    - `actualEndDate` string, date, nullable, required: Observed end, explicitly recorded from evidence. May fall outside the plan. Null means unknown, never incomplete.
    - `verifiedOn` string, date, nullable, required: Day the named source was actually checked, never later than the server UTC day. Independent of updatedAt and the status date in the description; never advance for editorial work.
    - `updatedAt` string, date-time, required
    - `statusDate` string, date, nullable, required
    - `stale` boolean, required
    - `match` object
      - `field` 'title' | 'description' | 'comment' | 'checklist' | 'subtask', required
      - `snippet` string, required
    - `boardId` string, uuid, required
    - `board` string, required
  - `truncated` boolean, required: True when more than 50 cards matched and only the 50 best ranked are listed (by the field holding every word — title, ALIASES line, description, comment, checklist, subtask, then words spread over fields — most recently updated first within a rank); false means every match on the boards you can read is here.

## Other responses

- `400`: Invalid request
- `401`: Unauthenticated
- `403`: Forbidden: insufficient role or token scope; scope denials name the held scope and the operation
- `404`: Not found
- `409`: Conflict
- `429`: Rate limited
- `500`: Internal server error
- `503`: Temporarily unavailable

---

[API](https://skmtc.dev/tre-app/apis/tre-rest-api.md) · [All operations](https://skmtc.dev/tre-app/apis/tre-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tre-app/apis/tre-rest-api/revisions/26a7187a05fc?raw)
