---
title: "Items API"
description: "Use when you list, create, delete, enrich, flag or re-import books over HTTP with the /items endpoints. Reading and writing page text have their own pages."
url: https://docs.heytrove.ai/reference/api/items
updated: 2026-10-01
---

# Items API

> Load this page when: you need to list books, create a markdown book, delete books or change book metadata over HTTP

## For agents

- List books with GET /items and the optional shelf query.
- Delete with a JSON body of ids, not a query string.
- Enrich uses PATCH, not POST.

These endpoints manage books as objects. To read text, see [Reading API](https://docs.heytrove.ai/reference/api/items-read.md). To edit text, see [Writing API](https://docs.heytrove.ai/reference/api/items-write.md).

## List items

`GET https://heytrove.ai/api/v1/items`

Returns every book you can access: your own, marketplace books you added, and books shared with you. The list has no paging. A locked book stays in the list with `locked: true`.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `shelf` | query | string | no | up to 64 characters of letters, digits, `_` and `-` | Shelf slug or id. Show only books on that shelf. |

**Request**

```bash
curl "https://heytrove.ai/api/v1/items?shelf=backend" \
  -H "Authorization: Bearer trove_your_key"
```

**Response**

```json
{
  "items": [
    {
      "id": "cmabc123",
      "title": "Use The Index, Luke",
      "description": null,
      "author": "Markus Winand",
      "sourceType": "pdf",
      "status": "READY",
      "needsEnrichment": false,
      "enrichmentConfidence": 0.9,
      "pageCount": 42,
      "health": "ok",
      "healthReason": null,
      "isSystem": false,
      "isSubscribed": false,
      "proOnly": false,
      "locked": false,
      "shelves": [{ "id": "cmshelf1", "slug": "backend", "name": "Backend" }]
    }
  ],
  "enrichmentQueue": [],
  "pickUrl": "https://heytrove.ai/library/usable"
}
```

`pickUrl` appears only when some book is locked. An unknown `shelf` returns `{ "items": [], "enrichmentQueue": [] }` with status 200, not 404. Other fields on each item are `enrichedAt`, `metadataConfirmedAt`, `createdAt`, `updatedAt` and `isWeeklyFeatured`.

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 400 | `Invalid shelf parameter` | `SHELF_PARAM_INVALID` | Use a slug or id of up to 64 safe characters. |

**CLI equivalent**: [trove items list](https://docs.heytrove.ai/reference/cli/items.md#trove-items-list).

## Delete items

`DELETE https://heytrove.ai/api/v1/items`

Deletes books you own. This cannot be undone. A locked book can still be deleted, which is how you get back under your limit.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `ids` | body | string array | yes | not empty | Ids of books to delete. |

**Request**

```bash
curl -X DELETE https://heytrove.ai/api/v1/items \
  -H "Authorization: Bearer trove_your_key" \
  -H "Content-Type: application/json" \
  -d '{"ids":["cmabc123"]}'
```

**Response**

```json
{ "deleted": ["cmabc123"], "notFound": [] }
```

Ids that are not your own books come back in `notFound`. `storageErrors` lists books whose stored file could not be removed. The rows are deleted anyway.

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 400 | `Invalid JSON body` | none | Send valid JSON. |
| 400 | `ids array is required` | `INVALID_INPUT` | Send a non-empty `ids` array. |
| 400 | `ids must be strings` | `INVALID_INPUT` | Send strings. |
| 403 | `System books cannot be deleted` | `FORBIDDEN` | Remove built-in books from the request. Nothing was deleted. |

**CLI equivalent**: [trove items remove](https://docs.heytrove.ai/reference/cli/items-writing.md#trove-items-remove).

## Create a markdown book

`POST https://heytrove.ai/api/v1/items/markdown`

Creates a book from markdown text. Top-level `# ` headings split the text into pages. It counts against your library limit.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `title` | body | string | yes | 1 to 200 characters | Book title. |
| `description` | body | string | no | up to 4,000 characters | Short description. |
| `content` | body | string | no | up to 1,000,000 bytes, up to 1,000 pages | Markdown text. |

**Request**

```bash
curl https://heytrove.ai/api/v1/items/markdown \
  -H "Authorization: Bearer trove_your_key" \
  -H "Content-Type: application/json" \
  -d '{"title":"Team runbook","content":"# Deploys\n\nRun the pipeline."}'
```

**Response**

Status 201.

```json
{
  "id": "cmrun456",
  "title": "Team runbook",
  "description": null,
  "sourceType": "markdown",
  "status": "READY",
  "pageCount": 1,
  "createdAt": "2026-10-01T09:00:00.000Z",
  "updatedAt": "2026-10-01T09:00:00.000Z"
}
```

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 400 | `title is required` | `INVALID_INPUT` | Send a title. |
| 400 | `content must be a string` | `INVALID_INPUT` | Send text. |
| 413 | `content exceeds maximum size of 1000000 bytes per request — create the item with the first part, then add the rest in further calls` | `PAYLOAD_TOO_LARGE` | Create with the first part, then [append](https://docs.heytrove.ai/reference/api/items-write.md#append-or-prepend-pages). |
| 403 | `Your library is full. Upgrade to add more items.` | `PLAN_LIMIT_EXCEEDED` | See [Errors](https://docs.heytrove.ai/reference/api.md#errors). |
| 429 | `Too many content writes in a short window — wait a minute and retry.` | `RATE_LIMITED` | Wait for `Retry-After`. |

**CLI equivalent**: [trove items create](https://docs.heytrove.ai/reference/cli/items-writing.md#trove-items-create).

## Enrich a book

`PATCH https://heytrove.ai/api/v1/items/enrich`

Sets title, author, description, table of contents and related metadata. You need write access to the book.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `itemId` | body | string | yes | none | Book to change. |
| `title` | body | string | no | up to 200 characters | New title. |
| `author` | body | string | no | up to 200 characters | Author name. |
| `description` | body | string | no | up to 4,000 characters | Description. |
| `confidence` | body | number | no | 0 to 1 | Confidence in the metadata. |
| `toc` | body | array | no | entries with `title`, `page` of 1 or more, optional `level` of 1 or more | Table of contents. |
| `addPrompt` | body | object | no | `prompt` required, optional `context` and `multiBook` | A prompt to show with the book. |
| `sampleQuestion` | body | string | no | none | A sample question. |
| `outcomes` | body | string array | no | up to 6 items of up to 140 characters | The short list of what a reader gets. An empty array clears it. |

**Request**

```bash
curl -X PATCH https://heytrove.ai/api/v1/items/enrich \
  -H "Authorization: Bearer trove_your_key" \
  -H "Content-Type: application/json" \
  -d '{"itemId":"cmabc123","author":"Markus Winand","confidence":0.9}'
```

**Response**

```json
{
  "item": {
    "id": "cmabc123",
    "title": "Use The Index, Luke",
    "author": "Markus Winand",
    "description": null,
    "needsEnrichment": false,
    "enrichmentConfidence": 0.9,
    "enrichedAt": "2026-10-01T09:00:00.000Z"
  }
}
```

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 400 | `Invalid JSON body` | none | Send a JSON object. |
| 400 | `itemId is required` | `INVALID_INPUT` | Send `itemId`. |
| 400 | `confidence must be between 0 and 1` | `INVALID_INPUT` | Use a value in range. |
| 400 | `Each TOC entry must have a page number >= 1` | `INVALID_INPUT` | Fix the entry. |

**CLI equivalent**: [trove items enrich](https://docs.heytrove.ai/reference/cli/items-writing.md#trove-items-enrich).

## Flag a book

`POST https://heytrove.ai/api/v1/items/flag`

Marks a book as needing enrichment. Only the owner can flag a book.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `itemId` | body | string | yes | none | Book to flag. |

**Request**

```bash
curl https://heytrove.ai/api/v1/items/flag \
  -H "Authorization: Bearer trove_your_key" \
  -H "Content-Type: application/json" \
  -d '{"itemId":"cmabc123"}'
```

**Response**

```json
{ "item": { "id": "cmabc123", "title": "Use The Index, Luke", "needsEnrichment": true } }
```

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 400 | `itemId is required` | none | Send `itemId`. |
| 404 | `Item not found` | `NOT_FOUND` | Check the id. |
| 403 | `You can only flag books you own for enrichment` | `FORBIDDEN` | Ask the owner. |

**CLI equivalent**: [trove items flag](https://docs.heytrove.ai/reference/cli/items-writing.md#trove-items-flag).

## Reprocess a book

`POST https://heytrove.ai/api/v1/items/{itemId}/reprocess`

Rebuilds a book from the file it was uploaded from. The old pages stay readable until the new ones are ready. Only the owner can do it.

**Parameters**

| Name | In | Type | Required | Constraints | Meaning |
| --- | --- | --- | --- | --- | --- |
| `itemId` | path | string | yes | none | Book to rebuild. |

**Request**

```bash
curl -X POST https://heytrove.ai/api/v1/items/cmabc123/reprocess \
  -H "Authorization: Bearer trove_your_key"
```

**Response**

```json
{
  "item": { "id": "cmabc123", "title": "Use The Index, Luke", "status": "READY" },
  "job": { "id": "cmjob789", "status": "PENDING" }
}
```

**Errors**

| Status | Message | Code | Fix |
| --- | --- | --- | --- |
| 404 | `Item not found` | `NOT_FOUND` | Check the id. |
| 400 | `Built-in books can't be reprocessed.` | `INVALID_INPUT` | Pick another book. |
| 400 | `This book has no original file to re-import — it was written directly rather than uploaded.` | `INVALID_INPUT` | Nothing to rebuild. |

**CLI equivalent**: [trove items reprocess](https://docs.heytrove.ai/reference/cli/items-writing.md#trove-items-reprocess).
