# Notebooks API

> Knowledge Bash reads before it answers: notebooks, and the documents in them.

Send `Authorization: Bearer vk_test_...` on every call.

## `POST /v1/notebooks`

Its own page: [POST /v1/notebooks](https://vestra.ai/developers/reference/api/notebooks/post-v1-notebooks.md)

Create a notebook.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in every value.

### Request

Headers:

- `Idempotency-Key` (`string`): Send the same key to retry this call safely for 24 hours.

Body:

- `name` (`string`, required): Its name, as people read it, 1 to 80 characters. Limits: 1 to 80 characters. Example: `Refund policy`.
- `slug` (`string`, required): Its short name: lowercase letters, digits and hyphens, starting with a letter, up to 40. Example: `refund-policy`.
- `description` (`string`): What it holds, up to 300 characters: Bash reads this to know when to look in it. Empty by default. Default: empty. Limits: at most 300 characters.
- `access` (`object`): Who may read it. Default `{ "mode": "all" }`. Default: `{"mode":"all"}`. One of: `{ mode }`, `{ mode, user_ids }`.

### Answers 201

- `object` (`"notebook"`): Always `notebook`.
- `id` (`string`): The notebook's id. Example: `nb_8f2k`.
- `slug` (`string`): Its short name.
- `name` (`string`): Its name, as people read it.
- `description` (`string`): What it holds; empty when none was given.
- `access` (`object`): Who may read it. One of: `{ mode }`, `{ mode, user_ids }`.
- `document_count` (`integer`): How many documents it holds.
- `bytes` (`integer`): The size of its text, in bytes, at most 5 MB.
- `created_at` (`string`): When it was made, as an ISO 8601 date and time in UTC.
- `updated_at` (`string`): When it last changed, as an ISO 8601 date and time in UTC.

### Code

**HTTP**

```bash
curl -X POST "$VESTRA_BASE_URL/v1/notebooks" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Refund policy",
    "slug": "refund-policy"
  }'
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `GET /v1/notebooks`

Its own page: [GET /v1/notebooks](https://vestra.ai/developers/reference/api/notebooks/get-v1-notebooks.md)

Your notebooks.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in every value.

### Request

Query:

- `limit` (`integer`): How many items per page, 1 to 100. Default 20.
- `cursor` (`string`): Where to go on from: the `next_cursor` of the page before, unchanged. Absent: the first page.

### Answers 200

- `data` (`object[]`): The items on this page.
  - `object` (`"notebook"`): Always `notebook`.
  - `id` (`string`): The notebook's id. Example: `nb_8f2k`.
  - `slug` (`string`): Its short name.
  - `name` (`string`): Its name, as people read it.
  - `description` (`string`): What it holds; empty when none was given.
  - `access` (`object`): Who may read it. One of: `{ mode }`, `{ mode, user_ids }`.
  - `document_count` (`integer`): How many documents it holds.
  - `bytes` (`integer`): The size of its text, in bytes, at most 5 MB.
  - `created_at` (`string`): When it was made, as an ISO 8601 date and time in UTC.
  - `updated_at` (`string`): When it last changed, as an ISO 8601 date and time in UTC.
- `next_cursor` (`string | null`): Send it as `cursor` for the next page; null on the last page.

### Code

**HTTP**

```bash
curl "$VESTRA_BASE_URL/v1/notebooks" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `GET /v1/notebooks/{notebook_id}`

Its own page: [GET /v1/notebooks/{notebook_id}](https://vestra.ai/developers/reference/api/notebooks/get-v1-notebooks-notebook-id.md)

One notebook and who may read it.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).

### Answers 200

- `object` (`"notebook"`): Always `notebook`.
- `id` (`string`): The notebook's id. Example: `nb_8f2k`.
- `slug` (`string`): Its short name.
- `name` (`string`): Its name, as people read it.
- `description` (`string`): What it holds; empty when none was given.
- `access` (`object`): Who may read it. One of: `{ mode }`, `{ mode, user_ids }`.
- `document_count` (`integer`): How many documents it holds.
- `bytes` (`integer`): The size of its text, in bytes, at most 5 MB.
- `created_at` (`string`): When it was made, as an ISO 8601 date and time in UTC.
- `updated_at` (`string`): When it last changed, as an ISO 8601 date and time in UTC.

### Code

**HTTP**

```bash
curl "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `PATCH /v1/notebooks/{notebook_id}`

Its own page: [PATCH /v1/notebooks/{notebook_id}](https://vestra.ai/developers/reference/api/notebooks/patch-v1-notebooks-notebook-id.md)

Rename it, or set who may read it: every user, or named users only.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).

Body:

- `name` (`string`): A new name, 1 to 80 characters. Limits: 1 to 80 characters.
- `description` (`string`): A new description, up to 300 characters. Limits: at most 300 characters.
- `access` (`object`): Who may read it, from now on. One of: `{ mode }`, `{ mode, user_ids }`.

### Answers 200

- `object` (`"notebook"`): Always `notebook`.
- `id` (`string`): The notebook's id. Example: `nb_8f2k`.
- `slug` (`string`): Its short name.
- `name` (`string`): Its name, as people read it.
- `description` (`string`): What it holds; empty when none was given.
- `access` (`object`): Who may read it. One of: `{ mode }`, `{ mode, user_ids }`.
- `document_count` (`integer`): How many documents it holds.
- `bytes` (`integer`): The size of its text, in bytes, at most 5 MB.
- `created_at` (`string`): When it was made, as an ISO 8601 date and time in UTC.
- `updated_at` (`string`): When it last changed, as an ISO 8601 date and time in UTC.

### Code

**HTTP**

```bash
curl -X PATCH "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `DELETE /v1/notebooks/{notebook_id}`

Its own page: [DELETE /v1/notebooks/{notebook_id}](https://vestra.ai/developers/reference/api/notebooks/delete-v1-notebooks-notebook-id.md)

Delete it.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).

### Answers 200

- `object` (`"notebook"`): Always `notebook`.
- `id` (`string`): The notebook's id. Example: `nb_8f2k`.
- `deleted` (`true`): Always true: it is gone.

### Code

**HTTP**

```bash
curl -X DELETE "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `POST /v1/notebooks/{notebook_id}/documents`

Its own page: [POST /v1/notebooks/{notebook_id}/documents](https://vestra.ai/developers/reference/api/notebooks/post-v1-notebooks-notebook-id-documents.md)

Add a document, as a file or as text.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).

Headers:

- `Idempotency-Key` (`string`): Send the same key to retry this call safely for 24 hours.

Body:

- `title` (`string`, required): Its title, 1 to 200 characters. Limits: 1 to 200 characters. Example: `Refunds for cancelled flights`.
- `text` (`string`, required): Its text, up to 512 KB. Limits: 1 to 524288 characters.

### Answers 201

- `object` (`"document"`): Always `document`.
- `id` (`string`): The document's id.
- `notebook_id` (`string`): The notebook it is in.
- `title` (`string`): Its title.
- `content_type` (`string`): The type of its text, such as `text/markdown` or `text/plain`.
- `bytes` (`integer`): Its size, in bytes.
- `sha256` (`string`): A hash of its text.
- `created_at` (`string`): When it was added, as an ISO 8601 date and time in UTC.

### Code

**HTTP**

```bash
curl -X POST "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}/documents" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Refunds for cancelled flights",
    "text": "..."
  }'
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `GET /v1/notebooks/{notebook_id}/documents`

Its own page: [GET /v1/notebooks/{notebook_id}/documents](https://vestra.ai/developers/reference/api/notebooks/get-v1-notebooks-notebook-id-documents.md)

Its documents.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).

### Answers 200

- `data` (`object[]`): The items on this page.
  - `object` (`"document"`): Always `document`.
  - `id` (`string`): The document's id.
  - `notebook_id` (`string`): The notebook it is in.
  - `title` (`string`): Its title.
  - `content_type` (`string`): The type of its text, such as `text/markdown` or `text/plain`.
  - `bytes` (`integer`): Its size, in bytes.
  - `sha256` (`string`): A hash of its text.
  - `created_at` (`string`): When it was added, as an ISO 8601 date and time in UTC.
- `next_cursor` (`string | null`): Send it as `cursor` for the next page; null on the last page.

### Code

**HTTP**

```bash
curl "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}/documents" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.

## `DELETE /v1/notebooks/{notebook_id}/documents/{document_id}`

Its own page: [DELETE /v1/notebooks/{notebook_id}/documents/{document_id}](https://vestra.ai/developers/reference/api/notebooks/delete-v1-notebooks-notebook-id-documents-document-id.md)

Remove one.

Your API key, scope `setup` or `all`. On the card: [`deploy`](https://vestra.ai/developers/deploy.md). Over HTTP it is made from the contract: fill in each {…} and every value.

### Request

Path:

- `notebook_id` (`string`, required): The notebook's id (`nb_...`).
- `document_id` (`string`, required): The document's id (`doc_...`).

### Answers 200

- `object` (`"document"`): Always `document`.
- `id` (`string`): The removed document's id.
- `deleted` (`true`): Always true: it is gone.

### Code

**HTTP**

```bash
curl -X DELETE "$VESTRA_BASE_URL/v1/notebooks/{notebook_id}/documents/{document_id}" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**TypeScript, Python, CLI, MCP**: No sample in your language for this route, so here it is over HTTP.
