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

# Update a note

> Change a note's title, body, topic, tags, or pin. Only what you send changes.

The body changes one way per request:

* `body` replaces all of it.
* `append` adds text at the end. A list item or table row goes on the next line, anything else after a blank line.
* `find` with `replace_with` changes one exact place, such as a table row. `find` must appear exactly once; otherwise nothing changes and you get `422`. An empty `replace_with` removes the text.

`title` sets a new title. `topic` sets the topic, and an empty string clears it. `tags` replaces all the tags, and an empty list clears them. `pinned` pins or unpins the note. `source` never changes.

The answer is the note as it is now. Read the note first with [Get a note](/api-reference/notes/get) when you change one place, so `find` matches it exactly.

| Status | Why |
| - | - |
| `403` | The key lacks `notes:write`. |
| `404` | No such note, or it is not yours. |
| `422` | Nothing to change, more than one way to change the body, `find` without `replace_with` (or the other way round), `find` not in the body or in it more than once, or the body would be longer than 20,000 characters. |

MCP tool: `update_note`.


## OpenAPI

````yaml PATCH /v1/notes/{note_id}
openapi: 3.1.0
info:
  title: Valendata REST API
  version: 1.0.0
  description: >-
    Create, run, schedule, and improve skills and workflows over JSON and HTTPS.
    Every route is under `/v1`; changes inside v1 are additive only (new routes,
    new optional parameters, new response fields). A route that will go away is
    marked `deprecated` here and answers with `Deprecation`, `Sunset` and a
    `Link` to its replacement for at least six months before it is removed.
    Errors, limits, pagination and idempotency:
    https://docs.valendata.com/api-reference/errors.
  license:
    name: Proprietary
    url: https://www.valendata.com/terms-and-conditions
servers:
  - url: https://api.valendata.com
    description: Production
security:
  - ApiKeyAuth: []
  - ApiKeyHeader: []
tags:
  - name: Skills
    description: List, create, read, update, and delete skills.
  - name: Marketplace
    description: Find a skill by the task, with its price per run and track record.
  - name: Runs
    description: Run skills and workflows, read any run, and cancel one.
  - name: Skill versions
    description: List, compare, restore, and pin a skill's versions.
  - name: Improvements
    description: >-
      Fix a skill, add fields, or re-learn its detail steps, and read its change
      history.
  - name: Schedules
    description: Run a skill or workflow on a fixed cadence.
  - name: Workflows
    description: List, create, read, update, and delete workflows.
  - name: Logins
    description: Saved website logins a skill can sign in with.
  - name: Connected apps
    description: >-
      Your own accounts (Gmail, Calendar, Slack …): connect them, list their
      tools, and run one.
  - name: Follow-ups
    description: >-
      Wait for something to arrive (a code, a link, a file, a message) or check
      back later, and read what came.
  - name: Jobs
    description: >-
      What your agents started to run in the background (skill runs, workflow
      runs, research), what came back, and stopping it.
  - name: Notes
    description: >-
      The notes on your Notes page: list and search them, read one, write,
      change, and delete them.
  - name: Account and usage
    description: Your plan, credit balance, and usage.
  - name: Webhooks
    description: The secret that signs webhook deliveries.
paths:
  /v1/notes/{note_id}:
    patch:
      tags:
        - Notes
      summary: Update a note
      description: >-
        Change a note; only what you send changes. The body changes one way per
        request: `body` replaces all of it, `append` adds text at the end (on
        the next line when it continues a list or a table), or `find` with
        `replace_with` changes one exact place, such as a table row. `find` must
        appear exactly once, or nothing changes and you get 422. Also sets
        `title`, `topic` (empty clears it), `tags` (replaces them; an empty list
        clears them) and `pinned`. Answers with the note as it is now. Only your
        own; anyone else gets 404. Needs `notes:write`.
      operationId: update_note
      parameters:
        - name: note_id
          in: path
          required: true
          schema:
            type: string
            title: Note Id
          example: 3b9e6f2a-1c4d-4e8f-9a7b-5d2c0e1f8a6b
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateNoteRequest'
            example:
              find: '| Tobi | 12,000 | owes |'
              replace_with: '| Tobi | 12,000 | paid |'
      responses:
        '200':
          description: The note as it is now.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Note'
              example:
                id: 3b9e6f2a-1c4d-4e8f-9a7b-5d2c0e1f8a6b
                title: Dinner split 27 Sep
                body: |-
                  | Who | Owes | Status |
                  | --- | --- | --- |
                  | Ada | 12,000 | paid |
                  | Tobi | 12,000 | paid |
                topic: Money
                tags:
                  - dinner
                  - split
                pinned: true
                source: api
                created_at: '2026-10-10T09:00:00Z'
                updated_at: '2026-10-10T09:30:00Z'
                link: /notes/3b9e6f2a-1c4d-4e8f-9a7b-5d2c0e1f8a6b
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - ApiKeyAuth: []
        - ApiKeyHeader: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 255
      description: >-
        Any unique string (such as your order id). Resending the same request
        with the same key within 24 hours returns the first answer (with
        `Idempotent-Replayed: true`) and does nothing twice; the same key with a
        different request is a 422 `idempotency_key_reused`.
      example: order-1234
  schemas:
    UpdateNoteRequest:
      properties:
        title:
          anyOf:
            - type: string
              maxLength: 200
              minLength: 1
            - type: 'null'
          title: Title
          description: A new title.
        body:
          anyOf:
            - type: string
              maxLength: 20000
            - type: 'null'
          title: Body
          description: 'A new body: replaces all of it.'
        append:
          anyOf:
            - type: string
              maxLength: 20000
              minLength: 1
            - type: 'null'
          title: Append
          description: >-
            Text to add at the end of the body: on the next line when it
            continues a list or a table, after a blank line otherwise.
        find:
          anyOf:
            - type: string
              maxLength: 20000
              minLength: 1
            - type: 'null'
          title: Find
          description: >-
            Exact text in the body to change, e.g. a whole table row. It must
            appear exactly once. Send with `replace_with`.
        replace_with:
          anyOf:
            - type: string
              maxLength: 20000
            - type: 'null'
          title: Replace With
          description: What `find` becomes; empty removes it.
        topic:
          anyOf:
            - type: string
              maxLength: 64
            - type: 'null'
          title: Topic
          description: A new topic; empty clears it.
        tags:
          anyOf:
            - items:
                type: string
                maxLength: 40
              type: array
              maxItems: 10
            - type: 'null'
          title: Tags
          description: >-
            The new tags, replacing the old ones; an empty list clears them. Up
            to 10 short tags (each at most 40 characters). They are kept
            lowercase, without a leading #, each once.
        pinned:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Pinned
          description: Pin or unpin it.
      type: object
      title: UpdateNoteRequest
      description: >-
        Only what is sent changes. The body changes one way per call: ``body``
        (all of it),

        ``append`` (added at the end) or ``find`` + ``replace_with`` (one exact
        place).
    Note:
      properties:
        id:
          type: string
          title: Id
        title:
          type: string
          title: Title
          description: One line, at most 200 characters.
        body:
          type: string
          title: Body
          description: The note itself, in Markdown (tables and checklists work).
        topic:
          anyOf:
            - type: string
            - type: 'null'
          title: Topic
          description: One short topic, e.g. 'Travel'; null when none.
        tags:
          items:
            type: string
          type: array
          title: Tags
          description: Short lowercase tags.
        pinned:
          type: boolean
          title: Pinned
          description: Pinned notes come first in the list.
          default: false
        source:
          type: string
          enum:
            - user
            - igris
            - session
            - brain
            - api
          title: Source
          description: >-
            Who wrote it first: `user` (you, on the Notes page), `igris` (the
            assistant), `session` (a chat session's agent), `brain` (a
            workflow's Brain) or `api` (the API or an AI assistant you
            connected).
        created_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Created At
        updated_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Updated At
        link:
          type: string
          title: Link
          description: The path of the note's page in the Valendata app, e.g. /notes/{id}.
      type: object
      required:
        - id
        - title
        - body
        - source
        - link
      title: Note
    Error:
      type: object
      required:
        - detail
        - code
        - type
        - request_id
      properties:
        detail:
          description: What went wrong. A string, or an object for errors with more to say.
          oneOf:
            - type: string
            - additionalProperties: true
              type: object
        code:
          type: string
          description: >-
            Stable machine-readable code. Known values: `bad_request`,
            `invalid_json`, `invalid_cursor`, `invalid_idempotency_key`,
            `unauthorized`, `payment_required`, `permission_denied`,
            `not_found`, `method_not_allowed`, `conflict`, `app_not_connected`,
            `idempotency_key_in_use`, `idempotent_replay_unavailable`,
            `payload_too_large`, `unsupported_media_type`, `validation_error`,
            `idempotency_key_reused`, `rate_limited`, `internal_error`,
            `upstream_error`, `service_unavailable`.
          example: not_found
        type:
          type: string
          enum:
            - invalid_request_error
            - authentication_error
            - billing_error
            - permission_error
            - conflict_error
            - idempotency_error
            - rate_limit_error
            - api_error
          description: The broad category of the error.
        request_id:
          type: string
          description: Also in the `X-Request-ID` header.
          example: 3f9a1c2b7d4e
        param:
          type: string
          description: >-
            The field at fault, on validation errors (dotted path, e.g.
            `inputs.city`).
        errors:
          type: array
          items:
            additionalProperties: true
            type: object
          description: Every validation problem, on a 422 from request validation.
  headers:
    X-Request-ID:
      description: >-
        This request's id (yours, if you sent a valid `X-Request-ID`). Quote it
        to support.
      schema:
        type: string
    X-RateLimit-Limit:
      description: Requests a minute this API key may make.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current minute.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix time (seconds) the current window ends.
      schema:
        type: integer
    Idempotent-Replayed:
      description: >-
        `true` when this is the stored answer to an earlier request with the
        same Idempotency-Key.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  responses:
    BadRequest:
      description: >-
        The request is malformed: the body is not JSON, the cursor or
        Idempotency-Key is not valid.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              The request is malformed: the body is not JSON, the cursor or
              Idempotency-Key is not valid.
            code: invalid_json
            type: invalid_request_error
            request_id: 3f9a1c2b7d4e
    Unauthorized:
      description: The API key is missing, malformed, revoked, or expired.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: The API key is missing, malformed, revoked, or expired.
            code: unauthorized
            type: authentication_error
            request_id: 3f9a1c2b7d4e
    Forbidden:
      description: >-
        The key lacks a scope, is limited to other skills or workflows, or you
        may not do this.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              The key lacks a scope, is limited to other skills or workflows, or
              you may not do this.
            code: permission_denied
            type: permission_error
            request_id: 3f9a1c2b7d4e
    NotFound:
      description: It does not exist, or it is not yours to see.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: It does not exist, or it is not yours to see.
            code: not_found
            type: invalid_request_error
            request_id: 3f9a1c2b7d4e
    Conflict:
      description: >-
        A conflict with the current state, or a request with this
        Idempotency-Key is still running.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              A conflict with the current state, or a request with this
              Idempotency-Key is still running.
            code: conflict
            type: conflict_error
            request_id: 3f9a1c2b7d4e
    Unprocessable:
      description: >-
        A field is invalid (`param` names it), or the Idempotency-Key was used
        with a different request.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: 'Invalid request — name: Field required'
            code: validation_error
            type: invalid_request_error
            request_id: 3f9a1c2b7d4e
            param: name
            errors:
              - type: missing
                loc:
                  - body
                  - name
                msg: Field required
    RateLimited:
      description: >-
        Too many requests for this key, or too many runs in progress. Wait
        `Retry-After` seconds.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Too many requests for this key, or too many runs in progress. Wait
              `Retry-After` seconds.
            code: rate_limited
            type: rate_limit_error
            request_id: 3f9a1c2b7d4e
    InternalError:
      description: >-
        Something broke on our side. Retry; runs that fail on our side are
        refunded.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Something broke on our side. Retry; runs that fail on our side are
              refunded.
            code: internal_error
            type: api_error
            request_id: 3f9a1c2b7d4e
    ServiceUnavailable:
      description: >-
        This part of the API is not available on the server right now. Retry
        later.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              This part of the API is not available on the server right now.
              Retry later.
            code: service_unavailable
            type: api_error
            request_id: 3f9a1c2b7d4e
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: vd_sk_...
      description: >-
        API key with the `vd_sk_` prefix, as `Authorization: Bearer vd_sk_...`.
        Create keys in Settings → API Keys.
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: The same API key in the `x-api-key` header.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.