Channel that produced this link. See the type-level doc above.
Optionaltitle?: stringTitle for the link and its thread container. Must be the real entity title (e.g. issue title, message subject), never a placeholder or ID. This value overwrites the existing title on upsert. Omit to preserve the existing title (e.g. for cancelled events where the title may not be available in the webhook payload).
Optionalnotes?: Omit<NewNote, "thread">[]Notes to attach to the thread
Optionalschedules?: Omit<NewSchedule, "threadId">[]Schedules to create for the link
OptionalscheduleOccurrences?: NewScheduleOccurrence[]Schedule occurrence overrides
OptionaloriginatingNote?: { key?: string; externalContent?: string; deliveryError?: DeliveryError | null }For onCreateLink only: binds the thread's opening note (the message the
user composed in Plot, which this hook just posted to the external system)
to its external counterpart. Mirrors the NoteWriteBackResult a reply
returns from onNoteCreated — key is the external message id and
externalContent is the post-write content baseline. Without this the
opening note stays keyless, so reactions and edits on it can't be routed
back to the external system. Ignored outside onCreateLink.
Optionalkey?: stringExternal message id; set as the opening note's key.
OptionalexternalContent?: stringContent as the external system stored it post-write, for the sync
baseline. Must equal what your sync-in path emits as this note's
content on re-ingest (same contract as NoteWriteBackResult.externalContent).
OptionaldeliveryError?: DeliveryError | nullReports that sending the composed message FAILED (the onCreateLink
send could not be delivered). The runtime records it on the opening
note — surfacing a "Failed to send" affordance (Retry / Discard) — and
marks the thread unread. Same contract as
NoteWriteBackResult.deliveryError: object records, null clears,
omitted leaves untouched. Return the link anyway (so the user's composed
content is preserved in Plot) with this set, rather than returning
null, when a compose send fails.
A new link with notes to save via integrations.saveLink()/saveLinks(). Creates a thread+link pair, with notes attached to the thread.
channelIdis required (passnullif the item genuinely has none): every sync/backfill/webhook builder already knows its channel before constructing the link (it's how it fetched the data), and there is no fallback if it's missing here. The platform persists this field to the link'schannelIdcolumn and later reads it back — NOT frommeta— to populatethread.meta.channelId/link.meta.channelIdfor connector callbacks likeonNoteCreated. Omitting it (or only setting a duplicate insidemeta) silently breaks those callbacks with no error anywhere. If you're implementingonCreateLink, return CreateLinkResult instead — that hook'schannelIdis genuinely optional, since the platform auto-fills it from the compose draft.