---
title: "Submit an action"
method: POST
path: "/notes/~/v1"
---

# Submit an action

`POST /notes/~/v1`

Parses the body as a `RequestEnvelope`, registers the
`requestId` in the agent's `requests` map with this Eyre
request's id as the held HTTP slot, then dispatches the
wrapped action. Returns when a terminal response-update
arrives (typical), the host nacks (error), or the 20 s
per-request behn timer fires (pending).

## Request body

- RequestEnvelope
  - `requestId` string — Canonical Hoon `@uv` (base-32 with `.` separators every 5 chars from the right, prefixed `0v`). A correlation id for the request. OPTIONAL on POST: if you omit it (or send something that isn't a valid `@uv`), the server mints one and returns it in the response. You only need to supply your own if you intend to poll `GET /request/{requestId}` or subscribe to the SSE request stream — for the common case (read the held-open POST response inline) you can leave it out entirely.
  - `action` union, required
    - ActionCreateNotebook
      - `type` 'create-notebook', required
      - `title` string, required
    - ActionJoin
      - `ship` string, required — Host ship, `~`-prefixed (e.g. `~zod`).
      - `name` string, required — Slug part of the flag (`@tas`-validated, lowercase).
      - `type` 'join', required
    - ActionLeave
      - `ship` string, required — Host ship, `~`-prefixed (e.g. `~zod`).
      - `name` string, required — Slug part of the flag (`@tas`-validated, lowercase).
      - `type` 'leave', required
    - ActionAcceptInvite
      - `ship` string, required — Host ship, `~`-prefixed (e.g. `~zod`).
      - `name` string, required — Slug part of the flag (`@tas`-validated, lowercase).
      - `type` 'accept-invite', required
    - ActionDeclineInvite
      - `ship` string, required — Host ship, `~`-prefixed (e.g. `~zod`).
      - `name` string, required — Slug part of the flag (`@tas`-validated, lowercase).
      - `type` 'decline-invite', required
    - ActionNotebookEnvelope
      - `type` 'notebook', required
      - `flag` string, required — Notebook flag as a `~ship/name` string (e.g. `~zod/my-notebook`). Note this envelope takes the string form, unlike the `{host, flagName}` object used by create-group-notebook.
      - `action` union, required
        - NbRename
          - `type` 'rename', required
          - `title` string, required
        - NbDelete
          - `type` 'delete', required
        - NbVisibility
          - `type` 'visibility', required
          - `visibility` 'public' | 'private', required
        - NbInvite
          - `type` 'invite', required
          - `who` string, required — Invitee ship.
        - NbCreateFolder
          - `type` 'create-folder', required
          - `parent` integer, nullable — Parent folder id; null = root.
          - `name` string, required
        - NbFolderEnvelope
          - `type` 'folder', required
          - `id` integer, required
          - `action` union, required
            - object
              - …
            - object
              - …
            - object
              - …
        - NbCreateNote
          - `type` 'create-note', required
          - `folder` integer, required
          - `title` string, required
          - `body` string, required
        - NbNoteEnvelope
          - `type` 'note', required
          - `id` integer, required
          - `action` union, required
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
        - NbBatchImport
          - `type` 'batch-import', required
          - `folder` integer, required
          - `notes` object[], required
            - `title` string, required
            - `body` string, required
        - NbBatchImportTree
          - `type` 'batch-import-tree', required
          - `parent` integer, required
          - `tree` ImportNode[], required
            - union — A folder (has `children`) or a note (has `title` + `body`).
              - …
    - ActionRegenerateApiKey — Replace the stored `X-Api-Key` with a fresh random value. Invalidates any bots / scripts still using the previous key.
      - `type` 'regenerate-api-key', required
    - ActionClearApiKey — Erase the stored `X-Api-Key`. Disables the bypass entirely — afterward only eyre-cookie-authenticated requests pass the v1 dispatch gate. Re-mint via `regenerate-api-key`.
      - `type` 'clear-api-key', required

## Response `200`

Terminal or pending response from the agent

- Response
  - `requestId` string, required — Canonical Hoon `@uv` (base-32 with `.` separators every 5 chars from the right, prefixed `0v`). A correlation id for the request. OPTIONAL on POST: if you omit it (or send something that isn't a valid `@uv`), the server mints one and returns it in the response. You only need to supply your own if you intend to poll `GET /request/{requestId}` or subscribe to the SSE request stream — for the common case (read the held-open POST response inline) you can leave it out entirely.
  - `body` union, required
    - ResponseOk
      - `type` 'ok', required
      - `response` union, required
        - RSnapshot
          - `type` 'snapshot', required
          - `host` string, required
          - `flagName` string, required
          - `visibility` 'public' | 'private', required
        - RUpdate
          - `type` 'update', required
          - `host` string, required
          - `flagName` string, required
          - `time` integer, required — Unix seconds when the host applied the change.
          - `update` union, required
            - UNbCreated
              - …
            - UNbUpdated
              - …
            - UNbDeleted
              - …
            - UNbVisibilityChanged
              - …
            - UMemberJoined
              - …
            - UMemberLeft
              - …
            - UInviteReceived
              - …
            - UInviteRemoved
              - …
            - UFolderUpdate
              - …
            - UNoteUpdate
              - …
    - ResponseNoChange
      - `type` 'no-change', required
    - ResponseNotebook — Returned by `create-notebook` — the new notebook's summary so the caller learns the slugified flag + metadata without a follow-up read.
      - `type` 'notebook', required
      - `notebook` NotebookSummary, required
        - `host` string, required
        - `flagName` string, required
        - `notebook` Notebook, required
          - `id` integer, required
          - `title` string, required
          - `rootFolderId` integer, required — Id of the notebook's root folder. Pass this as `parent` when creating a folder/note at the top level. Equal to `id + 1`.
          - `createdBy` string, required
          - `createdAt` integer, required — Unix seconds
          - `updatedAt` integer, required
          - `updatedBy` string, required
        - `visibility` 'public' | 'private', required
    - ResponseApiKey — Returned by `regenerate-api-key` (new key) and `clear-api-key` (apiKey: null). `apiKey` is the value to send as `X-Api-Key`.
      - `type` 'api-key', required
      - `apiKey` string, nullable, required
    - ResponseError
      - `type` 'error', required
      - `errorType` 'not-authorized' | 'not-found' | 'invalid-name' | 'conflict' | 'request-too-large' | 'unknown', required — Structured failure mode. `conflict` corresponds to an `expectedRevision` mismatch on a note update. Today most host-side crashes surface as `unknown` (raw nack); future work will route revision-mismatch and visibility errors to their typed variants.
      - `message` string[], required — Hoon `tang` rendered as JSON strings. Empty for now.
    - ResponsePending
      - `type` 'pending', required
      - `status` 'sending' | 'acked' | 'nacked', required — Where the cross-ship poke stood when the timeout fired. `sending` = no poke-ack yet, `acked` = host accepted but no response-update yet, `nacked` = host crashed (a terminal `error` body would normally have followed; if you see this, the timeout beat the nack delivery).

## Other responses

- `400` — Missing or malformed body
- `405` — Method not allowed

## Changes

- **2026-07-09** `4c08b6aefdbb` — 1 warning
  - changed the pattern of the request property `action/oneOf[#/components/schemas/ActionNotebookEnvelope]/flag` from `^~[a-z-]+/[a-z][a-z0-9-]*$` to `^~[a-z-]+/[a-z0-9-]+$`
- **2026-07-08** `8e349b18043e` — 1 warning
  - changed the pattern of the request property `action/oneOf[#/components/schemas/ActionNotebookEnvelope]/flag` from `^~[a-z-]+/[a-z0-9-]+$` to `^~[a-z-]+/[a-z][a-z0-9-]*$`

[Change history](https://skmtc.dev/tloncorp/apis/notes-v1-http-api/changes/notes/~/v1/post.md)

---

[API](https://skmtc.dev/tloncorp/apis/notes-v1-http-api.md) · [All operations](https://skmtc.dev/tloncorp/apis/notes-v1-http-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/tloncorp/notes-v1-http-api/revisions/9beef8e14823/schema)
