Reference to the parent thread (required)
Optionalauthor?: NewActor | nullThe person who wrote this note in the external system.
Connectors MUST set this to the note's real author (the comment
author, the message sender, the description's creator). Leaving it unset
credits the note to the connector itself, so it surfaces as authored by
the integration's name instead of a person — the most common connector
attribution bug. Prefer authoredBySelf for the connection owner's own
messages (see below). Set an explicit null only for a genuinely
authorless/system note (it documents the intent and suppresses the
development-time "missing author" warning).
Twists may leave this unset to author the note as the twist itself.
OptionalauthoredBySelf?: booleanMark this note as authored by the connection owner (the person whose account the connector is syncing) — e.g. a message you sent in a chat.
When true, the runtime attributes the note to your own contact for this
connection, ignoring author. Use this instead of trying to resolve your
own identity from the external service: for many providers a message you
sent carries no usable sender id (and 1:1 chats omit you from the
participant roster), so author cannot identify you reliably. The owner
is already known from the connection, so this is deterministic and needs
no extra API call. If the owner has no resolvable contact, the note falls
back to author.
OptionaldeferUntilThread?: booleanKeep this note until its thread exists, instead of dropping it.
A note addressed by { source } normally resolves immediately, and
saveNote returns null when no thread carries that source — which for
a connector usually means the item this note belongs to has not synced
yet. Set this to have the platform hold the note and attach it as soon
as a thread with that source appears, rather than making you store and
retry it yourself.
Recommended for any { source }-addressed note whose target is synced
by a different product or connector and may therefore lag. Leave it
unset when a miss means the note is genuinely undeliverable: null is
then the signal you want, and holding the note would accumulate payloads
for a thread that will never arrive.
Held notes are dropped after a bounded retry window. Ordering is not
guaranteed relative to notes that attached immediately, so set created
(as connectors already should) rather than relying on arrival order.
At most one UNKEYED held note survives per { source }: two deferred
notes without a key addressed to the same still-unresolved source
collapse onto a single held slot, and the second one you save silently
replaces the first — it does not queue as a second note. If you may
defer more than one note to the same unresolved source, give each a
distinct key so they are held separately.
OptionalcontentType?: ContentTypeFormat of the note content. Determines how the note is processed:
Optionaltags?: NewTagsTags to change on the thread. Use an empty array of NewActor to remove a tag. Use twistTags to add/remove the twist from tags to avoid clearing other actors' tags.
Optionalreactions?: NewReactionsEmoji reactions to set on the note. Pass an empty NewActor[] to
remove a reaction entirely; omit an emoji to leave it untouched.
OptionalaccessContacts?: (ActorId | NewContact)[] | nullContacts who can see this note, or null/undefined to inherit thread visibility. Accepts resolved ActorId UUIDs or email-based NewContact objects (resolved server-side). Include all participants who should see the note (sender + recipients). The note author is NOT implicitly included — add them explicitly. When set (even to []), the note is private to the listed contacts plus the creator.
Optionalmentions?: NewActor[]Twist/connector IDs to mention for dispatch routing. Does not include user contacts — use accessContacts for visibility.
Optionalunread?: booleanWhether this note should change the parent thread's read state.
false if a note should NOT create unread (e.g. a
low-signal annotation, or a response that says nothing the thread
doesn't already show).true: mark the thread unread, except for the user who authored the
note — they have necessarily seen it. Redundant with the default
behavior above; pass it when you want to be explicit at the call site.false: mark the thread read for the connection owner. Use when the
external system reports the item as already read, so a two-way sync
converges.A note carrying accessContacts is scoped to those contacts. Scoping
marks the thread unread for every visible non-author when the note
lands, whatever this field says — so true is redundant on a scoped
note, and false clears it again for the connection owner.
OptionalcheckForTasks?: booleanWhen true, the server will use AI to detect tasks in this note's content and create separate Plot-authored reply notes for each detected task. Use for messaging connectors (email, chat) where tasks are implicit in conversation rather than explicitly structured.
OptionalreNote?: { id: Uuid } | { key: string } | nullReference to a parent note this note is a reply to.
{ id }: reply by UUID{ key }: reply by key, resolved after creation (for batch ops)null: explicitly not a replyundefined (omitted): not a replyOptionallink?: NewLinkA link carried by this note (note-attached, NOT a thread-level canonical
link). Use for augmenter content (e.g. Granola meeting notes) that should
attach to an existing canonical thread without becoming its primary link.
The runtime creates the link note-scoped, binds note.link_id to it, and
— when thread: { source } resolves to no existing thread — find-or-creates
the thread by that source so a later canonical sync can fill the primary.
Type for creating new notes.
Requires the thread reference, with all other fields optional. Can provide id, key, or neither for note identification: