Creating Plot Twists
    Preparing search index...

    Type Alias CreateLinkDraft

    Fields captured in Plot when a user initiates creation of a new external item via a connector's onCreateLink hook.

    Thread-agnostic on purpose — connectors do not receive the Plot thread. The platform attaches the returned CreateLinkResult to the originating thread once onCreateLink resolves.

    type CreateLinkDraft = {
        channelId: string;
        type: string;
        status: string | null;
        title: string;
        noteContent: string | null;
        contacts: Actor[];
        recipients?: ResolvedRecipient[];
        inviteEmails?: string[];
        attachments?: {
            fileId: string;
            fileName: string;
            mimeType: string;
            fileSize: number | null;
        }[];
        forward?: { key: string };
    }
    Index

    Properties

    channelId: string

    The channel (account + resource) the new item belongs to.

    type: string

    Link type identifier, matches a LinkTypeConfig.type.

    status: string | null

    Status the user selected. Matches a statuses[].status for type, or null for status-less link types (the parent linkType declares no statuses and no compose.status).

    title: string

    Title of the originating Plot thread (post AI title generation).

    noteContent: string | null

    Markdown content of the thread's first note, or null if none.

    contacts: Actor[]

    Contacts attached to the originating Plot thread, excluding the creating user. Use these as recipients (email, chat DM members, etc.) when the external item is a message or invite. An empty list means the user did not add anyone to the thread.

    For link types with compose.targets: "contacts", prefer recipients over re-resolving contacts yourself: the runtime pre-resolves each contact to its platform account ID (externalAccountId) and populates recipients before onCreateLink is called.

    recipients?: ResolvedRecipient[]

    Pre-resolved recipients for link types whose compose.targets is "contacts" or "addresses".

    Only populated for those link types; otherwise undefined. Each entry contains the Plot contact UUID, the platform-specific account ID (externalAccountId) the connector should use to address the recipient without performing its own lookup, and the contact's role on the thread (e.g. "to" / "cc" / "bcc") resolved from thread.contact_meta. For "addresses" link types, contacts without a connection-scoped row fall back to contact.email.

    inviteEmails?: string[]

    Free-form addresses the user typed into the picker (no Plot contact row). Only populated for link types with compose.targets: "addresses"; otherwise undefined. Connectors should append these alongside recipients when constructing the recipient list (e.g. To: header for Gmail).

    attachments?: {
        fileId: string;
        fileName: string;
        mimeType: string;
        fileSize: number | null;
    }[]

    File actions on the composed thread's first note, for link types whose compose creates media (e.g. a LinkedIn post with an image). Empty/undefined when the composer attached no files. Read the bytes via the Files tool.

    forward?: { key: string }

    When present, this create-link is a FORWARD of an existing upstream item. key is the source note's connector key (e.g. the Gmail message id). The connector should reconstruct a native forward of that item — carrying its original body and attachments — addressed to the draft's recipients, with noteContent as the forwarder's own message on top. Only populated for link types that declare supportsForward: true; otherwise the runtime uses the blockquote fallback and never sets this.