> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.scripe.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Notes

# Notes

A **note** is a piece of raw content captured against a project — a
recording, a written snippet, an imported article, etc. Notes are the
input side of Scripe's content pipeline; once a note has been turned
into a post draft (via "Turn into post" in the dashboard or the future
write API), the post lives in [posts](./posts.md).

The v1 API exposes the notes the authenticated workspace owns, scoped
to a specific project, with date filters and cursor pagination. Notes
attached to deleted projects are not returned.

A note may have **at most one** queue slot — the day on which it's
scheduled for content production. The slot is included inline so you
don't have to make a second call.

***

## `GET /v1/notes`

List notes inside a project. `projectId` is required; everything else is
optional.

```bash theme={null}
curl -i 'https://api.scripe.io/v1/notes?projectId=proj_01J9ZA…&limit=100' \
  -H "Authorization: Bearer scripe_sk_live_…" \
  -H "Scripe-Api-Version: 2026-08-01"
```

### Query parameters

| Name        | Type    | Required | Default | Notes                                                                            |
| ----------- | ------- | -------- | ------- | -------------------------------------------------------------------------------- |
| `projectId` | string  | yes      | —       | `proj_*` id. 404 if the project doesn't belong to the workspace.                 |
| `folderId`  | string  | no       | —       | Filter to a single folder (UI grouping). Pass an empty value or omit to disable. |
| `dateFrom`  | string  | no       | —       | `YYYY-MM-DD`. Filters by the note's queue-slot date. Inclusive.                  |
| `dateTo`    | string  | no       | —       | `YYYY-MM-DD`. Inclusive. End-of-day in UTC.                                      |
| `limit`     | integer | no       | 50      | 1…200.                                                                           |
| `cursor`    | string  | no       | —       | Opaque cursor from a previous response.                                          |

`dateFrom` / `dateTo` filter on the **queue slot's date**, not on the
note's `createdAt`. A note without a slot is excluded from a date-filtered
result set; remove the date params to see notes that aren't yet
scheduled.

### Response

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    {
      "id": "note_01J9ZA…",
      "projectId": "proj_01J9ZA…",
      "folderId": null,
      "content": "Brain-dump from this morning's call …",
      "createdAt": "2026-05-15T08:21:00.000Z",
      "updatedAt": "2026-05-15T08:23:11.000Z",
      "slot": {
        "id": "slot_01J9ZA…",
        "date": "2026-05-20",
        "contentType": "PERSONAL"
      }
    }
  ],
  "pagination": {
    "next_cursor": "eyJjcmVhdGVkQXQiOiIyMDI2L…",
    "has_more": true
  }
}
```

### Field reference

| Path               | Type                  | Notes                                                                                                    |
| ------------------ | --------------------- | -------------------------------------------------------------------------------------------------------- |
| `id`               | string (`note_*`)     |                                                                                                          |
| `projectId`        | string (`proj_*`)     | Always the project the note belongs to. Mirrors the request.                                             |
| `folderId`         | string \| null        | Internal id of the folder grouping in the dashboard, if any.                                             |
| `content`          | string                | Raw note body. May be empty for notes captured by audio first.                                           |
| `createdAt`        | string (ISO 8601)     |                                                                                                          |
| `updatedAt`        | string \| null        | `null` if the note hasn't been edited since creation.                                                    |
| `slot`             | object \| null        | The queue slot, if the note is scheduled. See below.                                                     |
| `slot.id`          | string                | Internal slot id; opaque.                                                                                |
| `slot.date`        | string (`YYYY-MM-DD`) | UTC date the note is queued for.                                                                         |
| `slot.contentType` | string \| null        | `PERSONAL` \| `BUSINESS` \| `EDUCATIONAL` \| `INSPIRATIONAL` \| `NEWS`. `null` until the user picks one. |

The `content` field is the **raw user content**. We do not redact PII or
strip HTML — if you're rendering this somewhere user-facing, sanitize
on your end.

### Pagination caveats

* Order is `(createdAt DESC, id DESC)` — newest first. The cursor
  encodes that tuple.
* Changing any filter (`projectId`, `folderId`, `dateFrom`, `dateTo`,
  `limit`) mid-loop will likely emit `400 bad_cursor`. Restart the loop
  with the new filters.

***

## `GET /v1/notes/{noteId}`

Single note read. Returns the same shape, wrapped in `data`.

```bash theme={null}
curl -i https://api.scripe.io/v1/notes/note_01J9ZA… \
  -H "Authorization: Bearer scripe_sk_live_…" \
  -H "Scripe-Api-Version: 2026-08-01"
```

### Response

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": {
    "id": "note_01J9ZA…",
    "projectId": "proj_01J9ZA…",
    "folderId": null,
    "content": "Brain-dump from this morning's call …",
    "createdAt": "2026-05-15T08:21:00.000Z",
    "updatedAt": "2026-05-15T08:23:11.000Z",
    "slot": null
  }
}
```

### Errors

| Status | Code                                                             |
| ------ | ---------------------------------------------------------------- |
| 400    | `invalid_request`, `bad_cursor`, `bad_pagination`                |
| 401    | `unauthenticated`, `invalid_token`, `key_revoked`, `key_expired` |
| 403    | `scope_missing` (need `notes:read`), `plan_not_eligible`         |
| 404    | `not_found`                                                      |
| 429    | `rate_limited`                                                   |

***

## `POST /v1/notes`

Create a note + paired calendar slot. Required scope: `notes:write`.

```bash theme={null}
curl -i https://api.scripe.io/v1/notes \
  -X POST \
  -H "Authorization: Bearer scripe_sk_live_…" \
  -H "Scripe-Api-Version: 2026-08-01" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-id-from-your-side" \
  -d '{
    "projectId": "proj_01J9ZA…",
    "content": "Brain-dump from the standup",
    "contentType": "PERSONAL"
  }'
```

### Request body

| Field         | Type              | Required | Notes                                                                                                          |
| ------------- | ----------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| `projectId`   | string (`proj_*`) | yes      | Must belong to the workspace; otherwise `404 not_found`.                                                       |
| `content`     | string            | no       | Up to 100,000 chars. Defaults to empty string.                                                                 |
| `folderId`    | string \| null    | no       | Internal folder id from the dashboard. Omit or `null` for the inbox.                                           |
| `date`        | string (ISO 8601) | no       | Slot placement. Defaults to "now".                                                                             |
| `contentType` | string            | no       | One of `PERSONAL`, `BUSINESS_INTERNAL`, `BUSINESS_EXTERNAL`, `EDUCATIONAL`, `UNKNOWN`. Defaults to `PERSONAL`. |

We strongly recommend setting `Idempotency-Key` on every write — see
[idempotency.md](./idempotency.md). Replay within 24h returns the same
response with header `Idempotent-Replayed: true`.

### Response

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json
Idempotent-Replayed: false

{
  "data": {
    "id": "note_01J9ZA…",
    "projectId": "proj_01J9ZA…",
    "folderId": null,
    "content": "Brain-dump from the standup",
    "createdAt": "2026-05-15T08:21:00.000Z",
    "updatedAt": "2026-05-15T08:21:00.000Z",
    "slot": {
      "id": "note_01J9ZA…",
      "date": "2026-05-15T08:21:00.000Z",
      "contentType": "PERSONAL"
    }
  }
}
```

### Errors

| Status | Code                                                             |
| ------ | ---------------------------------------------------------------- |
| 400    | `invalid_request` (missing `projectId`)                          |
| 401    | `unauthenticated`, `invalid_token`, `key_revoked`, `key_expired` |
| 403    | `scope_missing` (need `notes:write`), `plan_not_eligible`        |
| 404    | `not_found` (project not in workspace)                           |
| 409    | `idempotency_key_conflict` (same key, different body)            |
| 413    | `payload_too_large` (`content` > 100KB)                          |
| 422    | `unprocessable` (bad shape, invalid `contentType`)               |
| 429    | `rate_limited`                                                   |

***

## What's NOT here (yet)

* **Audio / transcript downloads.** A note may have an attached
  recording; the v1 API doesn't expose the storage URLs. Use
  [sources](./sources.md) for the truncated transcript.
* **Pinned / starred filters.** Dashboard-only state, not exposed in v1.
* **Search / full-text query.** No `?q=` parameter. Filter client-side
  for now.
* **Update / delete endpoints.** `PATCH` / `DELETE` are out of scope
  for v1.
