Creating Plot Twists
    Preparing search index...

    Type Alias NewLink

    NewLink: Partial<Omit<Link, "author" | "assignee" | "threadId">> & {
        source?: string;
        sources?: string[];
        facets?: ThreadFacets;
        signals?: LinkSignals;
        author?: NewActor | null;
        assignee?: NewActor | null;
        access?: ThreadAccessLevel;
        accessContacts?: NewContact[];
        unread?: boolean;
        archived?: boolean;
        todo?: boolean;
        todoDate?: Date | string;
        focus?: Pick<Focus, "id">;
        priority?: number;
        autoThread?: AutoThreadConfig | null;
        updateOnly?: boolean;
    }

    Type for creating new links.

    Links are created by sources to represent external entities. Requires a source identifier for dedup/upsert.

    Type Declaration

    • Optionalsource?: string

      Canonical ID for the item in an external system. When set, uniquely identifies the link for the user. This performs an upsert.

      Pass sources: [...] instead. Both fields can be set during the transition; the runtime will normalize.

    • Optionalsources?: string[]

      Canonical identifiers for this item. Any element shared with another link's sources bundles the two links into the same thread. Used for cross-connector bundling — e.g. a meeting-notes connector setting ["granola:<id>", "icaluid:<uid>"] to attach onto a calendar event thread that includes icaluid:<uid> in its own sources.

    • Optionalfacets?: ThreadFacets

      Heuristic facets describing this item (format / automation / reach), used as internal classifier signal. Omit a dimension (or set null) when no heuristic is confident. See @plotday/twister/facets.

    • Optionalsignals?: LinkSignals

      Raw signals this item was derived from (email headers, provider categories). The platform derives classification from these. Prefer this over facets: emitting signals lets classification improve without a connector redeploy. See @plotday/twister/signals.

      When both are set, signals wins.

    • Optionalauthor?: NewActor | null

      The person who created this item in the external system.

      Connectors MUST set this to the real external author (the message sender, the card/issue creator, the document owner, the meeting owner — whatever your API exposes). If you leave it unset, the item is credited to the connector itself, so the thread surfaces as authored by the integration's name ("Trello", "Slack") instead of a person. That is almost always wrong and is the single most common connector attribution bug — set the author on the link AND on its primary/description note AND on every comment/message note (see the Authorship section of the connector guide). Use Note.authoredBySelf for the connection owner's own messages when the provider gives no usable sender id.

      Set an explicit null only when the item genuinely has no human author (e.g. a system-generated record) — that documents the intent and suppresses the development-time "missing author" warning.

      Twists may leave this unset: an item a twist creates is authored by the twist, which is the intended default for twist-generated content.

    • Optionalassignee?: NewActor | null

      The person assigned to the item.

    • Optionalaccess?: ThreadAccessLevel

      Thread access level: "public", "members" (default), or "private". When "private", thread visibility is limited to the creator and contacts in accessContacts.

    • OptionalaccessContacts?: NewContact[]

      Contacts who can see a private thread. Pass email-based NewContact objects; they are resolved to contact IDs by the API. If omitted for a private thread, defaults to the connection owner.

    • Optionalunread?: boolean

      Whether the thread should be marked as unread for users.

      • undefined/omitted (default): Thread is unread for users, except auto-marked as read for the author if they are the twist owner (user)
      • false: Thread is marked as read for all users in the focus at creation time
    • Optionalarchived?: boolean

      Whether the thread is archived.

      • true: Archive the thread
      • false: Unarchive the thread
      • undefined (default): Preserve current archive state
    • Optionaltodo?: boolean

      Mark the thread as the connection owner's to-do at create time.

      • true: the thread is added to the owner's to-do (active) bucket and their per-user archive is lifted, atomically with the save — no separate integrations.setThreadToDo() round-trip needed.
      • false: the owner's thread_state is marked read (cleared from to-do).
      • undefined (omitted, default): leave to-do state untouched.

      Use for messaging-style "saved for later" flags (e.g. a starred Slack thread). This is the first-class replacement for overloading a statuses[] entry with active: true.

    • OptionaltodoDate?: Date | string

      The to-do date used when todo is true. Defaults to the "Now" sentinel (today's bucket) when omitted. Ignored when todo is not true.

    • Optionalfocus?: Pick<Focus, "id">

      Explicit focus (disables automatic focus matching). Only used when the link creates a new thread. When omitted, the server classifies the thread using the user's focus rules.

    • Optionalpriority?: number

      Primary-link ranking for this canonical link (default 0). Set higher on the connection that "owns" the external item (e.g. the calendar that owns an event vs a subscribed copy) so clients display it as the primary.

    • OptionalautoThread?: AutoThreadConfig | null

      Opt this message into the platform's sequential auto-threading. When a connection has auto-threading enabled, the runtime decides — once, globally, at ingest — whether this message starts a new thread or folds (as a note) into the thread of the conversation it continues. Set it on every message of a conversational surface (a chat channel, a DM); the runtime keys the sequential chain on AutoThreadConfig.key.

      Marking a link is a no-op unless the connection opted in, so connectors can set it unconditionally on eligible links. Leave undefined/null for non-conversational items (issues, events, files). See Connector.autoThreading.

    • OptionalupdateOnly?: boolean

      Apply this link only as an UPDATE to a thread that already exists for its source/sources; never CREATE a new thread. When no matching thread is found, saveLink()/saveLinks() skip the link entirely and return null for it.

      Use for signals that are only meaningful as an update to an item the user already has — most notably a calendar cancellation, which should annotate an event that was imported, never materialize a standalone "cancelled" thread for an occurrence the user never saw. Leave undefined/false for normal links, which create the thread when absent.