# Restore a study set from the trash

Source: https://workroad.app/docs/api/restore-set

`POST https://workroad.app/api/v1/sets/{setId}/restore`

Brings a trashed set back with its terms, images and review history, and returns it as `GET /sets/{setId}` would. Needs `sets:delete`, the scope that trashed it. A set whose folder is still in the trash comes back unfiled.

- MCP tool: `restoreSet` on `https://workroad.app/api/mcp`
- Required scopes: sets:delete
- Test mode: `POST https://workroad.app/api/test/v1/sets/{setId}/restore` checks the request and returns the example response without changing anything.

## Path parameters

- `setId`: string (uuid), required. Study set id, scoped to the key's user.

## Headers

- `Idempotency-Key`: string, optional, 1-255 visible ASCII characters. Makes the POST safe to retry: a retry with the same key and body replays the first response, and the same key with a different body returns 409 `idempotency_conflict`. Kept for 24 hours. Over MCP it is the `idempotencyKey` argument.

## Response

`200` OK

- `data`: object, required
  - `id`: string (uuid), required
  - `name`: string, required
  - `description`: string or null, required
  - `subjectId`: string or null, required. Subject id, when set.
  - `termCount`: integer, required
  - `createdAt`: string (date-time), required. Creation timestamp.
  - `lastUsed`: string (date-time) or null, required. Last study session, if any.
  - `updatedAt`: string (date-time), required. Last update timestamp.
  - `terms`: array of objects, required. The first 500 terms by id. When `termsTruncated` is true, page the rest with `GET /sets/{setId}/terms`.
    - `id`: string (uuid), required
    - `term`: string, required
    - `definition`: string, required
    - `hints`: array of string, required
  - `termsTruncated`: boolean, required

### Example

```json
{
  "data": {
    "id": "7e6d5c4b-3a2f-4e1d-8c0b-9a8f7e6d5c4b",
    "name": "Spanish verbs",
    "description": "Irregular preterite forms.",
    "subjectId": "5f0c1d2e-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
    "termCount": 1,
    "createdAt": "2026-01-15T09:30:00.000Z",
    "lastUsed": "2026-02-01T12:00:00.000Z",
    "updatedAt": "2026-02-01T12:00:00.000Z",
    "terms": [
      {
        "id": "2a1b0c9d-8e7f-4a6b-9c5d-4e3f2a1b0c9d",
        "term": "tener (yo)",
        "definition": "tuve",
        "hints": [
          "irregular stem tuv-"
        ]
      }
    ],
    "termsTruncated": false
  }
}
```

## Errors

Every error has the body `{ "error": { "code", "message", "details" } }`.

- `400`: Invalid request body or query
- `401`: Missing, invalid, disabled or expired API key
- `402`: `api_allowance_reached`: this month's API and AI app requests on the free plan are used up. `details` has `limit`, `used`, `resetsAt` and `upgradeUrl`. Nothing ran; WorkRoad Plus has no monthly limit.
- `403`: The API key lacks the required scope
- `404`: No study set with that id is in the trash for this key's user.
- `405`: Method not allowed. Use a method from the Allow header.
- `409`: The Idempotency-Key was reused with a different request body, or a request with the same key is still in progress.
- `429`: Rate limit exceeded. Wait for Retry-After before retrying. The rate-limit headers are absent when the key's own limiter rejected the request before the per-endpoint bucket check ran.
- `500`: Internal server error
