Use this file to discover all available pages before exploring further.
Triggers define the event that starts your workflow. Each trigger is tied to an integration and fires when a specific event occurs. Your onTrigger handler receives a typed event object with the payload.In TypeScript, terse generate writes a single Triggers object in src/terse.generated.ts. Import it and call the nested helper for your event (for example Triggers.github.onPROpened(...)). Each integration and system trigger has its own section below.
Connect Attio under Integrations, configure which Attio events start each workflow in the Terse app, then run terse generate. When Attio input triggers are enabled for your workspace, Triggers.attio appears in src/terse.generated.ts.
Trigger
Event type
Description
Triggers.attio.onRecordCreated()
AttioRecordCreatedTrigger
A record is created
Triggers.attio.onRecordUpdated()
AttioRecordUpdatedTrigger
A record is updated
Triggers.attio.onRecordMerged()
AttioRecordMergedTrigger
Two records are merged
Triggers.attio.onRecordDeleted()
AttioRecordDeletedTrigger
A record is deleted
Triggers.attio.onObjectAttributeCreated()
AttioObjectAttributeCreatedTrigger
An object attribute is created
Triggers.attio.onObjectAttributeUpdated()
AttioObjectAttributeUpdatedTrigger
An object attribute is updated
Triggers.attio.onListCreated()
AttioListCreatedTrigger
A list is created
Triggers.attio.onListUpdated()
AttioListUpdatedTrigger
A list is updated
Triggers.attio.onListDeleted()
AttioListDeletedTrigger
A list is deleted
Triggers.attio.onListAttributeCreated()
AttioListAttributeCreatedTrigger
A list attribute is created
Triggers.attio.onListAttributeUpdated()
AttioListAttributeUpdatedTrigger
A list attribute is updated
Triggers.attio.onListEntryCreated()
AttioListEntryCreatedTrigger
A list entry is created
Triggers.attio.onListEntryUpdated()
AttioListEntryUpdatedTrigger
A list entry is updated
Triggers.attio.onListEntryDeleted()
AttioListEntryDeletedTrigger
A list entry is deleted
Triggers.attio.onNoteCreated()
AttioNoteCreatedTrigger
A note is created
Triggers.attio.onNoteContentUpdated()
AttioNoteContentUpdatedTrigger
A note’s content is updated
Triggers.attio.onNoteUpdated()
AttioNoteUpdatedTrigger
A note is updated
Triggers.attio.onNoteDeleted()
AttioNoteDeletedTrigger
A note is deleted
Triggers.attio.onCommentCreated()
AttioCommentCreatedTrigger
A comment is created
Triggers.attio.onCommentResolved()
AttioCommentResolvedTrigger
A comment is resolved
Triggers.attio.onCommentUnresolved()
AttioCommentUnresolvedTrigger
A resolved comment is reopened
Triggers.attio.onCommentDeleted()
AttioCommentDeletedTrigger
A comment is deleted
Triggers.attio.onTaskCreated()
AttioTaskCreatedTrigger
A task is created
Triggers.attio.onTaskUpdated()
AttioTaskUpdatedTrigger
A task is updated
Triggers.attio.onTaskDeleted()
AttioTaskDeletedTrigger
A task is deleted
Triggers.attio.onWorkspaceMemberCreated()
AttioWorkspaceMemberCreatedTrigger
A workspace member is added
Triggers.attio.onCallRecordingCreated()
AttioCallRecordingCreatedTrigger
A call recording is created
Triggers.attio.trigger()
AttioTrigger (union)
Any Attio events you select with eventTypes
Config: Pass object: AttioObject.YourObject on the record helpers (onRecordCreated, onRecordUpdated, onRecordMerged, onRecordDeleted) to scope deliveries to a single CRM object. Omit object when you want the union of every generated object’s attribute shape.
import { Triggers } from "./terse.generated"triggers: [Triggers.attio.onRecordCreated({ object: AttioObject.People })]
Show Event payload
Record triggers include a record object with Attio ids/slugs plus values (and related fields) shaped from your workspace’s Attio object metadata—flattened for use in onTrigger and filter. Other Attio triggers carry event-specific payloads (lists, notes, tasks, and so on). Every event still exposes formatForAgentRunner() and debugLog() from terse-sdk.
HeyReach fires when LinkedIn outreach events occur (messages, connection requests, campaign milestones, and more). Connect HeyReach under Integrations in the Terse app, then run terse generate so Triggers.heyReach and typed HeyReachCampaign constants appear in src/terse.generated.ts.Each helper maps to one HeyReachEventType value (also exported from terse-sdk). Use Triggers.heyReach.trigger({ eventType: HeyReachEventType.MESSAGE_REPLY_RECEIVED }) when you want to pick the event type dynamically.
Trigger
Event type
Triggers.heyReach.onConnectionRequestSent()
HeyReachConnectionRequestSentTrigger
Triggers.heyReach.onConnectionRequestAccepted()
HeyReachConnectionRequestAcceptedTrigger
Triggers.heyReach.onMessageSent()
HeyReachMessageSentTrigger
Triggers.heyReach.onMessageReplyReceived()
HeyReachMessageReplyReceivedTrigger
Triggers.heyReach.onInmailSent()
HeyReachInmailSentTrigger
Triggers.heyReach.onInmailReplyReceived()
HeyReachInmailReplyReceivedTrigger
Triggers.heyReach.onFollowSent()
HeyReachFollowSentTrigger
Triggers.heyReach.onLikedPost()
HeyReachLikedPostTrigger
Triggers.heyReach.onViewedProfile()
HeyReachViewedProfileTrigger
Triggers.heyReach.onCampaignCompleted()
HeyReachCampaignCompletedTrigger
Triggers.heyReach.onLeadTagUpdated()
HeyReachLeadTagUpdatedTrigger
Config: Pass campaigns with generated HeyReachCampaign instances to handle only those campaigns; omit it to receive events from all campaigns.
import { Triggers } from "./terse.generated"triggers: [Triggers.heyReach.onMessageReplyReceived()]
Show Event payload
Shared fields on HeyReach triggers:
eventId, createdAt — event metadata
lead — optional lead profile (profile_url, names, company, tags, and related fields)
Track web changes continuously and get notified when there are updates.You can add multiple Triggers.webMonitor.onEvent(...) triggers to the same workflow. Terse runs each monitor independently and calls the same onTrigger handler for every matching event.
Trigger
Event type
Description
Triggers.webMonitor.onEvent()
WebMonitorTrigger
Fires when scheduled web monitoring detects relevant changes
import { createJob, generateText } from "terse-sdk"import * as z from "zod"import { Skills, SlackChannel, Triggers } from "./terse.generated"const outputSchema = z.object({ summary: z.string(), sentiment: z.enum(["positive", "negative", "neutral"])})createJob({ name: "Web monitor trigger", triggers: [ Triggers.webMonitor.onEvent({ query: "What are a16z's latest investments?", frequency: { number: 1, unit: "day" }, outputSchema }) ], onTrigger: async event => { const summary = event.payload.summary const sentiment = event.payload.sentiment const sources = event.sourceUrls.join(", ") await generateText({ prompt: "You are alerted when the web monitor finds new material. Read the event below (query, payload, and structured fields), decide what matters, and post a concise summary to Slack.\n\n" + `${event.formatForAgentRunner()}\n\nSummary: ${summary}\nSentiment: ${sentiment}\nSources: ${sources}`, skills: [Skills.slack({ channel: SlackChannel.AllTerseInc })] }) }})
If you need to annotate monitor events manually, import WebMonitorTriggerFor from terse-sdk and bind it to your Zod schema:
import type { WebMonitorTriggerFor } from "terse-sdk";import * as z from "zod";const outputSchema = z.object({ summary: z.string(), sentiment: z.enum(["positive", "negative", "neutral"]),});type MonitorEvent = WebMonitorTriggerFor<typeof outputSchema>
Fires when an HTTP request hits the generated webhook URL
Webhook URLs are auto-generated on deploy and remain stable across redeploys. After terse deploy, the CLI prints that URL for each affected workflow so you can copy it straight into your caller or load test.Pass a type argument to Triggers.webhook.onRequest<YourPayload>() so onTrigger and filter see your JSON body shape on event.body (defaults to unknown when omitted).
triggers: [Triggers.webhook.onRequest()]
Show Event payload
body - parsed JSON request body (typed when you use Triggers.webhook.onRequest<...>())