Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.duvo.ai/llms.txt

Use this file to discover all available pages before exploring further.

Status-change triggers let your assignments start a Job automatically when a record in a connected tool — a CRM deal, a project task, a support ticket — reaches a particular state. Use them to chain Duvo workflows to the milestones that matter in your business: a deal closes, a project moves to review, a ticket is resolved.

Key Capabilities

  • CRM stage monitoring — React when a HubSpot deal or Salesforce opportunity moves to a target pipeline stage
  • Project status monitoring — Start a Job when a Notion page status or Jira issue status changes to a configured value
  • Flexible polling cadence — Run checks every few minutes for near-real-time response, or hourly for batch workflows
  • State memory — Assignment Memory stores the last-seen status of each record so the assignment only fires once per genuine change, not on every poll
  • Multi-record support — Process all records that changed state since the last check in a single Job, or trigger one Job per record

How Status-Change Triggers Work

Duvo does not receive native push webhooks from CRM or project management tools (with the exception of Linear, which is already covered in Event-Driven Triggers). Status-change monitoring is implemented by scheduling an assignment to run on a regular interval and having the SOP:
  1. Query the connected tool for records that have recently moved to the target state.
  2. Compare results against the last-seen state stored in Assignment Memory.
  3. Process only the records that genuinely changed since the last Job ran.
  4. Update Assignment Memory with the new state before finishing.
ServiceMechanismTypical latency
HubSpotPollingEqual to schedule interval
SalesforcePollingEqual to schedule interval
NotionPollingEqual to schedule interval
Jira (via Computer Use)PollingEqual to schedule interval
LinearNative webhook (push)Seconds — see Event-Driven Triggers

When to Use Status-Change Triggers

  • Sales onboarding — When a HubSpot or Salesforce deal moves to “Closed Won”, start an onboarding assignment that creates workspace accounts, sends a welcome email, and schedules a kickoff call
  • Contract review routing — When a Notion page moves to “Ready for Legal Review”, route the document to the legal team and post a Slack notification
  • Support escalation — When a Zendesk ticket moves to “Escalated”, create a Linear issue and assign it to the on-call engineer
  • Content publishing — When a Notion page status changes to “Approved”, export the content to your CMS and notify the author
  • Procurement follow-up — When a Salesforce opportunity enters “Procurement Review”, send a follow-up email and attach the latest price list

How to Set It Up

Step 1: Create the assignment

  1. Click + Create Assignment from your dashboard.
  2. Select Use Assignment Builder.

Step 2: Write your SOP

The SOP pattern for status-change triggers has three phases: query, compare, act. Here is a template adapted for a HubSpot deal stage change:
Check HubSpot for deals that have moved to the stage "[Target Stage Name]" in the last
[polling interval, e.g. 30 minutes].

Compare the list of deal IDs to the "processed_deal_ids" list stored in memory.
Only process deals whose IDs are NOT already in that list.

For each new deal in the target stage:
1. Retrieve the full deal record: company name, contact name, email, deal value, owner.
2. [Describe your downstream action — examples below]
3. Add the deal ID to "processed_deal_ids" in memory.

At the end, save the updated "processed_deal_ids" list to memory.
Replace [Target Stage Name] with your pipeline stage (for example, “Closed Won”, “Contract Sent”, or “Procurement Review”). Replace the downstream action with your specific workflow.

Step 3: Add connections

Under Connections, enable the connection for the tool you are monitoring:
  • HubSpot — for deal or contact status changes
  • Salesforce — for opportunity or case status changes
  • Notion — for page or database entry status changes
  • Human-in-the-Loop — if the workflow includes an approval step
Add any connections required for the downstream action (email, Slack, Google Sheets, etc.).

Step 4: Enable Assignment Memory

Go to Setup and enable Assignment Memory. The SOP will use it to store the IDs of records already processed.

Step 5: Set a schedule

  1. Click Schedule in the assignment header.
  2. Choose an interval: every 15 minutes for near-real-time response, or every hour for batch workflows.
  3. Click Add schedule to save.

Worked Example — “Closed Won” Deal Triggers Onboarding

Outcome: When a HubSpot deal moves to “Closed Won”, Duvo starts an onboarding Job that creates accounts for the new customer, sends a welcome email, and notifies the customer success team in Slack. Connections used:
  • HubSpot — query deals by stage
  • Gmail — send the welcome email
  • Slack — notify the customer success channel
  • Human-in-the-Loop — optional approval step before sending the email

SOP

Check HubSpot for deals that moved to the stage "Closed Won" in the last 30 minutes.

Compare the deal IDs to the "onboarded_deal_ids" list in memory. Skip any deal already in the list.

For each new "Closed Won" deal:
1. Retrieve the deal record: company name, primary contact name and email, deal value, account owner.

2. Request human approval before sending any external communications:
   Title: "Onboarding ready — [Company Name] — [Deal Value]"
   Body: "Deal closed. About to send welcome email to [Contact Name] at [Contact Email].
          Account owner: [Owner]. Approve to proceed or reject to pause."

3. After approval, send a welcome email to the primary contact:
   Subject: "Welcome to [Your Company] — let's get you started"
   Body: Personalized welcome including their name, company, and a link to the onboarding calendar.

4. Post a message to the #customer-success Slack channel:
   "New customer: [Company Name] ([Deal Value]) — welcome email sent to [Contact Name].
    Owner: [Owner]. Kickoff link: [link]."

5. Add the deal ID to "onboarded_deal_ids" in memory.

Save the updated "onboarded_deal_ids" list to memory.

Connections to enable

  • HubSpot
  • Gmail (the account sending the welcome email)
  • Slack (for the #customer-success channel notification)
  • Human-in-the-Loop (for the approval step before external communications)

Expected results

When the assignment runs every 15 minutes:
  • Deals that moved to “Closed Won” since the last Job ran are identified.
  • A Human-in-the-Loop approval appears in your Activity Inbox for each new deal.
  • After approval, a personalized welcome email is sent and #customer-success is notified.
  • The deal ID is added to Assignment Memory so the next Job does not re-process it.

Adapting for Other Services

Salesforce — Opportunity stage change

The pattern is the same. Replace the HubSpot query with a Salesforce SOQL query:
Query Salesforce for opportunities where StageName = '[Target Stage]'
and LastModifiedDate > [current time minus polling interval].

For each opportunity not already in "processed_opportunity_ids" in memory:
[your downstream action]
Add the opportunity ID to "processed_opportunity_ids" in memory.
Example target stages: Closed Won, Proposal/Price Quote, Negotiation/Review.

Notion — Page status change

Notion databases support a “Status” property. Query for pages where the Status equals your target value:
Search the Notion database "[Database Name]" for pages where Status = "[Target Status]".

For each page not already in "processed_notion_ids" in memory:
[your downstream action — for example, export content, send notification, create ticket]
Add the page ID to "processed_notion_ids" in memory.
Example target statuses: Ready for Review, Approved, Published.

Jira — Issue status change

Jira does not have a native Duvo connection. To monitor Jira status changes, use Computer Use to navigate the Jira web interface and read the issue list:
Open [your Jira project URL] and filter for issues with status "[Target Status]"
that were last updated in the past [polling interval].

For each issue not already in "processed_jira_ids" in memory:
[your downstream action]
Add the issue key to "processed_jira_ids" in memory.
For teams using Jira alongside Linear, note that Linear has a native webhook-based trigger that fires in real time — consider whether Linear can serve as the trigger source instead.

Troubleshooting

The same record is processed more than once

  • The Assignment Memory key must be written at the end of each successful Job. If the Job fails partway through, the memory update may not have been saved. Check the session log to see where the failure occurred.
  • Make sure the SOP adds the ID to memory before the Job ends, even if the downstream action fails. Adjust the SOP: “Add the ID to memory regardless of whether the downstream action succeeds.”

Records that changed state are not detected

  • Time window too narrow: The SOP queries for records changed “in the last X minutes”. If the schedule interval is 15 minutes but the query window is 10 minutes, changes in the gap are missed. Set the query window to match or slightly exceed your polling interval.
  • Timezone mismatch: The query compares Duvo’s time against the timestamp in the CRM. Confirm both are in the same timezone, or use UTC for the comparison.
  • API pagination: If many records changed state at once (for example, after a bulk import), the query may return only the first page. Add to your SOP: “Retrieve all pages of results, not just the first.”

Memory grows very large over time

Assignment Memory is designed for moderate-size tracking lists. If your workflow processes hundreds of records per day, the processed_ids list can become large over time. Limit memory growth by expiring old entries:
When adding a new ID to "processed_deal_ids", also remove any IDs older than 30 days from the list.

Take It Further

Chain to a second assignment After completing the onboarding Job, schedule a follow-up check 7 days later:
At the end of the Job, schedule this assignment to run once in 7 days
with the deal ID as context, to check whether the onboarding tasks were completed.
See Scheduling Assignments for self-scheduling patterns. Notify via multiple channels Combine email and Slack in the same Job, or add a Human-in-the-Loop request for high-value deals:
If the deal value exceeds $100,000, request human approval before sending the welcome email.
Multi-stage chaining Create separate assignments for each key pipeline stage. When a deal enters “Contract Sent”, fire one Job; when it enters “Closed Won”, fire another. Each assignment handles the actions appropriate to that stage.