# Trash: Mosaic API reference

> Trash in Mosaic’s local REST API: 8 routes, each with its method, path, fields, what it returns and the errors it names.

Source: https://mosaicbrowser.com/docs/api/trash

**Housekeeping** REST API

## Trash

Deleting is always reversible. Purged automatically 30 days after deletion.

- [GETList trashed items](#list-trash)
- [POSTRestore a profile](#restore-profile)
- [DELETEPurge a profile](#purge-profile)
- [POSTRestore a project](#restore-project)
- [DELETEPurge a project](#purge-project)
- [POSTRestore a warm-up plan](#restore-warmup-plan)
- [DELETEPurge a warm-up plan](#purge-warmup-plan)
- [POSTEmpty the trash](#empty-trash)

## [List trashed items](#list-trash)

GET`/api/v1/trash`

Deleted profiles and projects, newest deletion first, each with how long it has left.

#### Returns

`{ total, items: TrashEntry[] }`

## [Restore a profile](#restore-profile)

POST`/api/v1/trash/profiles/:id/restore`

Brings a profile back with its browser data untouched.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

The restored `Profile`.

## [Purge a profile](#purge-profile)

DELETE`/api/v1/trash/profiles/:id`

Permanent. Removes the profile and its browser data directory from disk.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

`{ purged: true }`

## [Restore a project](#restore-project)

POST`/api/v1/trash/projects/:id/restore`

Restores the project and every profile deleted along with it.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

The restored `Project`.

## [Purge a project](#purge-project)

DELETE`/api/v1/trash/projects/:id`

Permanent, including every profile inside it.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

`{ purged: true }`

## [Restore a warm-up plan](#restore-warmup-plan)

POST`/api/v1/trash/warmup/plans/:id/restore`

Brings a trashed plan back. `DELETE /warmup/plans/:id` trashes rather than destroys — a plan is a list of sites somebody assembled by hand, and it takes longer to rebuild than to lose.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

The restored `WarmupPlan`.

## [Purge a warm-up plan](#purge-warmup-plan)

DELETE`/api/v1/trash/warmup/plans/:id`

Permanent. By id only — there is no purge-everything for plans.

#### Path parameters

| Field | Type | What it is |
| --- | --- | --- |
| `id`required | `string` | The record’s id. |

#### Returns

`{ purged: true }`

## [Empty the trash](#empty-trash)

POST`/api/v1/trash/empty`

Permanent, and the only call here that destroys more than one thing at a time — every profile it removes takes its cookies, logins and browsing history with it, and there is nothing to restore from. **It will not guess how much you meant**: an empty body is a `400`, not a full purge. Name a `projectId`, name an `os` list, or send `{ "all": true }` to mean every row. That default cost 586 profiles once — a script that meant "tidy up the one fixture I made" sent no body and purged a library — and on the single irreversible route in this API, absent must not mean maximal. A platform filter deliberately spares trashed **projects**: a project is not in a platform, and purging one because a caller named `android` would take desktop profiles nobody asked about. An unknown field is a `400` rather than a silently wider purge.

#### Body

| Field | Type | What it is |
| --- | --- | --- |
| `projectId` | `string` | Only this project’s trash. |
| `os` | `"windows" \| "macos" \| "linux" \| "android"[]` | Only these platforms’ profiles, and no projects. |
| `all` | `boolean` | Every row, with nothing spared. Cannot be combined with the other two. |

#### Returns

`{ purged: n }` — how many profiles and projects were removed.

#### Errors

- 400 — no scope at all. Say `projectId`, `os` or `all`.
- 400 — `all` combined with `projectId` or `os`.
- 400 — an unknown field, or an `os` entry that is not a platform.

```
curl -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"projectId":"'$PROJECT'","os":["android"]}' "$BASE/trash/empty"
```

## Run the API on your own profiles

The REST API and the MCP server are part of Pro: $49 a month, with the first 14 days free. Free has every browser feature and no API key.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
