# Create Agent Folder Source: https://docs.duvo.ai/api-reference/agent-folders/create-agent-folder /api-reference/openapi.json post /v2/teams/{teamId}/agent-folders Create a new agent folder. # Delete Agent Folder Source: https://docs.duvo.ai/api-reference/agent-folders/delete-agent-folder /api-reference/openapi.json delete /v2/agent-folders/{folder_id} Delete an agent folder. If the folder contains assignments or subfolders, pass `force=true` to delete it and move the contained assignments to the root level. # List Agent Folders Source: https://docs.duvo.ai/api-reference/agent-folders/list-agent-folders /api-reference/openapi.json get /v2/teams/{teamId}/agent-folders List all agent folders for the authenticated team. # Move Agents To Folder Source: https://docs.duvo.ai/api-reference/agent-folders/move-agents-to-folder /api-reference/openapi.json post /v2/teams/{teamId}/agent-folders/move-agents Move one or more agents (assignments) into a folder, or to the root level. # Update Agent Folder Source: https://docs.duvo.ai/api-reference/agent-folders/update-agent-folder /api-reference/openapi.json patch /v2/agent-folders/{folder_id} Rename an agent folder or move it to a new parent. # Get Agent Memory File Source: https://docs.duvo.ai/api-reference/agent-memory/get-agent-memory-file /api-reference/openapi.json get /v2/agents/{agent_id}/memory/files/{path} Get the contents of a single memory file for an agent. # List Agent Memory Files Source: https://docs.duvo.ai/api-reference/agent-memory/list-agent-memory-files /api-reference/openapi.json get /v2/agents/{agent_id}/memory/files List the memory files stored for an agent. # Create Agent Source: https://docs.duvo.ai/api-reference/agents/create-agent /api-reference/openapi.json post /v2/teams/{teamId}/agents Create a new agent. Optionally include a build configuration to create the first build in the same request. # Create Eval Rubric Source: https://docs.duvo.ai/api-reference/agents/create-eval-rubric /api-reference/openapi.json post /v2/agents/{agentId}/eval-rubrics Add one Agent-specific evaluation rubric to a build. A build may hold at most 5 custom rubrics; this fails with 409 once that ceiling is reached. Defaults to the Agent's live build; pass build_id to target a specific revision. # Delete Agent Source: https://docs.duvo.ai/api-reference/agents/delete-agent /api-reference/openapi.json delete /v2/agents/{agent_id} Delete an agent and cascade-clean its schedules, case triggers, builder runs, and handover targets. Any active jobs are interrupted and their sandboxes paused. # Delete Eval Rubric Source: https://docs.duvo.ai/api-reference/agents/delete-eval-rubric /api-reference/openapi.json delete /v2/agents/{agentId}/eval-rubrics/{rubricId} Remove a single Agent-specific evaluation rubric. Future Runs on the build are no longer scored against it. # Get Agent Source: https://docs.duvo.ai/api-reference/agents/get-agent /api-reference/openapi.json get /v2/agents/{agent_id} Get an agent by ID. # Get Eval Rubrics Source: https://docs.duvo.ai/api-reference/agents/get-eval-rubrics /api-reference/openapi.json get /v2/agents/{agentId}/eval-rubrics List the evaluation rubrics a Run is scored against: the platform default rubrics plus the Agent-specific rubrics for a build. Defaults to the Agent's live build; pass build_id to target the revision a specific Run ran against. # Get Eval Scores Source: https://docs.duvo.ai/api-reference/agents/get-eval-scores /api-reference/openapi.json get /v2/agent/{agentId}/eval-scores Aggregate evaluation counts and flag distribution for an Assignment's Jobs since the given timestamp. # List Agents Source: https://docs.duvo.ai/api-reference/agents/list-agents /api-reference/openapi.json get /v2/teams/{teamId}/agents List agents for your team. # Move Agent Source: https://docs.duvo.ai/api-reference/agents/move-agent /api-reference/openapi.json post /v2/agents/{agent_id}/move Move an agent (and its connected workspace) to a different team. Pass dry_run=true to preview the closure without applying changes. # Replace Eval Rubrics Source: https://docs.duvo.ai/api-reference/agents/replace-eval-rubrics /api-reference/openapi.json put /v2/agents/{agentId}/eval-rubrics Replace a build's entire Agent-specific evaluation rubric set in one call (at most 5 rubrics). Existing custom rubrics are removed and the supplied list becomes the new set; pass an empty array to clear them. Defaults to the Agent's live build; pass build_id to target a specific revision. # Update Agent Source: https://docs.duvo.ai/api-reference/agents/update-agent /api-reference/openapi.json patch /v2/agents/{agent_id} Update an agent's display name or delivery settings. # Update Eval Rubric Source: https://docs.duvo.ai/api-reference/agents/update-eval-rubric /api-reference/openapi.json patch /v2/agents/{agentId}/eval-rubrics/{rubricId} Edit a single Agent-specific evaluation rubric's title and/or description. The edit produces a NEW rubric (with a new id and slug) so previously scored Runs stay attributed to the original criterion; the response contains the new rubric. # Create Agent Case Trigger Source: https://docs.duvo.ai/api-reference/case-triggers/create-agent-case-trigger /api-reference/openapi.json post /v2/agents/{agent_id}/case-triggers Create a case trigger for an agent. An agent may have at most one case trigger; this returns 409 if one already exists. # Delete Agent Case Trigger Source: https://docs.duvo.ai/api-reference/case-triggers/delete-agent-case-trigger /api-reference/openapi.json delete /v2/agents/{agent_id}/case-triggers/{trigger_id} Delete a case trigger. Only the trigger creator or a builder/admin can delete it. # Get Agent Case Trigger Source: https://docs.duvo.ai/api-reference/case-triggers/get-agent-case-trigger /api-reference/openapi.json get /v2/agents/{agent_id}/case-triggers/{trigger_id} Retrieve a single case trigger by id. # List Agent Case Triggers Source: https://docs.duvo.ai/api-reference/case-triggers/list-agent-case-triggers /api-reference/openapi.json get /v2/agents/{agent_id}/case-triggers List the case triggers configured for an agent. Each trigger automatically dispatches the agent to run cases added to a queue. # Preview Agent Case Trigger Conflicts Source: https://docs.duvo.ai/api-reference/case-triggers/preview-agent-case-trigger-conflicts /api-reference/openapi.json get /v2/agents/{agent_id}/case-triggers/conflict-preview Preview which other agents would conflict with this agent's case trigger if it pointed at the given queue. Does not modify the trigger. # Update Agent Case Trigger Source: https://docs.duvo.ai/api-reference/case-triggers/update-agent-case-trigger /api-reference/openapi.json patch /v2/agents/{agent_id}/case-triggers/{trigger_id} Update fields on a case trigger. Only the trigger creator or a builder/admin can disable an enabled trigger or change its queue. # Assign Case Labels Source: https://docs.duvo.ai/api-reference/cases/assign-case-labels /api-reference/openapi.json post /v2/queues/{queue_id}/cases/{case_id}/labels Assign one or more labels to a case. Creates the labels on the queue if they don't already exist. # Bulk Delete Cases Source: https://docs.duvo.ai/api-reference/cases/bulk-delete-cases /api-reference/openapi.json post /v2/queues/{queue_id}/cases/bulk-delete Delete multiple cases from a queue. Any active runs are interrupted first. # Bulk Reprocess Cases Source: https://docs.duvo.ai/api-reference/cases/bulk-reprocess-cases /api-reference/openapi.json post /v2/queues/{queue_id}/cases/bulk-reprocess Re-process multiple cases on a chosen agent. Any active runs on the selected cases are interrupted first; the cases are then reset to pending and assigned to the chosen agent for the next dispatcher tick. The chosen agent must already be connected to the queue as a case-queue-consumer (with the trigger enabled or disabled). # Bulk Update Case Priority Source: https://docs.duvo.ai/api-reference/cases/bulk-update-case-priority /api-reference/openapi.json post /v2/queues/{queue_id}/cases/bulk-update-priority Set the priority of multiple cases. Priority only affects the order pending cases are picked up in: due postponed cases are handled first, then higher priority. It never interrupts runs or changes case status. Set `none` to clear priority back to the default. # Bulk Update Case Status Source: https://docs.duvo.ai/api-reference/cases/bulk-update-case-status /api-reference/openapi.json post /v2/queues/{queue_id}/cases/bulk-update-status Update the status of multiple cases to pending, completed, or failed. Interrupts any active runs and releases their case ownership, but never cancels their human-in-the-loop state — pending requests and open approval batches stay answerable/resolvable from the run view. Resetting to pending re-dispatches cases to the queue's trigger consumer. # Clear Queue Cases Source: https://docs.duvo.ai/api-reference/cases/clear-queue-cases /api-reference/openapi.json delete /v2/queues/{queue_id}/cases Delete every case in a queue. Interrupts any associated active runs first. Destructive — not exposed via MCP. # Create Cases Source: https://docs.duvo.ai/api-reference/cases/create-cases /api-reference/openapi.json post /v2/queues/{queue_id}/cases Create one or more cases in a queue. Provide either a single `case` object or a `cases` array (1-100); providing both returns 400. Each case accepts a title (max 500 chars), optional free-form `data`, optional labels that will be assigned to the case on creation (missing labels are created on the queue), and an optional priority (`none`, `medium`, or `high`; `medium`/`high` raise it above the default in the queue, `none` is the default). Priority only affects the order pending cases are picked up in: due postponed cases are handled first, then higher priority. # Create Queue Label Source: https://docs.duvo.ai/api-reference/cases/create-queue-label /api-reference/openapi.json post /v2/queues/{queue_id}/labels Create a label on a queue without assigning it to a case. # Delete Case Source: https://docs.duvo.ai/api-reference/cases/delete-case /api-reference/openapi.json delete /v2/cases/{case_id} Delete a case. Interrupts any associated active runs first. # Delete Queue Label Source: https://docs.duvo.ai/api-reference/cases/delete-queue-label /api-reference/openapi.json delete /v2/queues/{queue_id}/labels/{label_id} Delete a label from a queue. Cascade-deletes all assignments of this label on existing cases. # Get Case Source: https://docs.duvo.ai/api-reference/cases/get-case /api-reference/openapi.json get /v2/cases/{case_id} Get a case by ID. Returns the case, its event history, and every case-approval batch ever created on the case (newest first). # List Case Labels Source: https://docs.duvo.ai/api-reference/cases/list-case-labels /api-reference/openapi.json get /v2/queues/{queue_id}/cases/{case_id}/labels List all labels assigned to a case. # List Case Run Recent Messages Source: https://docs.duvo.ai/api-reference/cases/list-case-run-recent-messages /api-reference/openapi.json get /v2/cases/{case_id}/runs/{run_id}/recent-messages Return the latest qualifying messages (assistant text + tool calls) for a Run on a case, newest last. Used to populate the live body of an active Run card in the case Activity timeline. # List Case Runs Source: https://docs.duvo.ai/api-reference/cases/list-case-runs /api-reference/openapi.json get /v2/cases/{case_id}/runs List Runs (agent runs) that have claimed or received handover of a case, newest first. Capped at 50 ownership events. # List Cases Source: https://docs.duvo.ai/api-reference/cases/list-cases /api-reference/openapi.json get /v2/queues/{queue_id}/cases List cases in a queue. Supports status, date-range, and free-text filters via query params. For label filters, use POST /v2/teams/:team_id/queues/:queue_id/cases/search. # List Queue Labels Source: https://docs.duvo.ai/api-reference/cases/list-queue-labels /api-reference/openapi.json get /v2/queues/{queue_id}/labels List every label defined on a queue along with the count of cases each label is assigned to. # Search Cases Source: https://docs.duvo.ai/api-reference/cases/search-cases /api-reference/openapi.json post /v2/queues/{queue_id}/cases/search Search cases in a queue with rich filters (multi-status, date ranges, label-based filters). Use this when the simple query-string filters on GET /v2/teams/:team_id/queues/:queue_id/cases aren't enough. # Unlink Case Labels Source: https://docs.duvo.ai/api-reference/cases/unlink-case-labels /api-reference/openapi.json post /v2/queues/{queue_id}/cases/{case_id}/labels/unlink Remove the given labels from a case. # Update Queue Label Source: https://docs.duvo.ai/api-reference/cases/update-queue-label /api-reference/openapi.json patch /v2/queues/{queue_id}/labels/{label_id} Update a label's key, value, or color. Renaming key/value affects every case assigned to this label. # Assign Clarity Process Labels Source: https://docs.duvo.ai/api-reference/clarity/assign-clarity-process-labels /api-reference/openapi.json post /v2/clarity/processes/{id}/labels/assign Assign process tags to a process. # Create Clarity Landscape Node Source: https://docs.duvo.ai/api-reference/clarity/create-clarity-landscape-node /api-reference/openapi.json post /v2/organizations/{orgId}/clarity/hierarchy/nodes Create an area folder in the process tree. An active area (the default) requires organization admin+; a "proposal" area may be added by any organization member. # Create Clarity Process Source: https://docs.duvo.ai/api-reference/clarity/create-clarity-process /api-reference/openapi.json post /v2/teams/{teamId}/clarity/processes Create a new Clarity v2 process for the current team (manager+). Optional `name` defaults server-side when omitted. Response uses camelCase `createdAt` to match existing FE clients. # Create Clarity Process Label Source: https://docs.duvo.ai/api-reference/clarity/create-clarity-process-label /api-reference/openapi.json post /v2/organizations/{orgId}/clarity/process-labels Create process tags for an organization. # Create Clarity Process Link Source: https://docs.duvo.ai/api-reference/clarity/create-clarity-process-link /api-reference/openapi.json post /v2/organizations/{orgId}/clarity/hierarchy/process-links Create a process-to-process link in the organization's Clarity landscape when the caller can manage both endpoint teams. If the same live source, target, and type already exists, the existing link is returned. # Delete Clarity Landscape Node Source: https://docs.duvo.ai/api-reference/clarity/delete-clarity-landscape-node /api-reference/openapi.json delete /v2/organizations/{orgId}/clarity/hierarchy/nodes/{nodeId} Soft-delete a tree node and its descendants. Organization admins may delete any subtree; team managers may delete a childless process node owned by their team. The targeted node's linked clarity process and captures are deleted, while nested processes detach to the Unsorted bag. # Delete Clarity Process Label Source: https://docs.duvo.ai/api-reference/clarity/delete-clarity-process-label /api-reference/openapi.json delete /v2/organizations/{orgId}/clarity/process-labels/{labelId} Delete process tags from an organization. # Delete Clarity Process Link Source: https://docs.duvo.ai/api-reference/clarity/delete-clarity-process-link /api-reference/openapi.json delete /v2/organizations/{orgId}/clarity/hierarchy/process-links/{process_link_id} Delete a process-to-process link from the organization's Clarity landscape when the caller can manage both endpoint teams. # Get Clarity Process Tree Source: https://docs.duvo.ai/api-reference/clarity/get-clarity-process-tree /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/hierarchy/tree Fetch the organization's process tree, or the subtree under rootId # Get Legacy Clarity Process Source: https://docs.duvo.ai/api-reference/clarity/get-legacy-clarity-process /api-reference/openapi.json get /v2/clarity/processes/{id} Get a legacy v1 Clarity process with process metadata, generated analysis, transformation guidance, generation progress, and captures. Use this for rows from listClarityProcesses where version=1; v2 rows should use getClarityProcess and snapshot detail tools. # List Available Clarity Process Labels Source: https://docs.duvo.ai/api-reference/clarity/list-available-clarity-process-labels /api-reference/openapi.json get /v2/clarity/processes/{id}/available-labels List process tags available for a process. # List Clarity Process Assigned Labels Source: https://docs.duvo.ai/api-reference/clarity/list-clarity-process-assigned-labels /api-reference/openapi.json get /v2/clarity/processes/{id}/labels List process tags on a process. # List Clarity Process Labels Source: https://docs.duvo.ai/api-reference/clarity/list-clarity-process-labels /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/process-labels List process tags available in an organization. # List Clarity Process Links Source: https://docs.duvo.ai/api-reference/clarity/list-clarity-process-links /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/hierarchy/process-links List process-to-process links in the organization's Clarity landscape that are visible within the caller's team access scope. Use `node_id` to find links touching a specific process node. # Set Clarity Landscape Node Placement Source: https://docs.duvo.ai/api-reference/clarity/set-clarity-landscape-node-placement /api-reference/openapi.json put /v2/organizations/{orgId}/clarity/hierarchy/nodes/{nodeId}/placement Move a process landscape node (team manager or above for team processes; organization admin for areas) # Set Clarity Landscape Priorities Source: https://docs.duvo.ai/api-reference/clarity/set-clarity-landscape-priorities /api-reference/openapi.json put /v2/organizations/{org_id}/clarity/hierarchy/priorities Set or clear heatmap priorities in one batch (team managers for their processes; organization admin+ across the organization) # Unlink Clarity Process Labels Source: https://docs.duvo.ai/api-reference/clarity/unlink-clarity-process-labels /api-reference/openapi.json post /v2/clarity/processes/{id}/labels/unlink Remove process tags from a process. # Update Clarity Landscape Node Source: https://docs.duvo.ai/api-reference/clarity/update-clarity-landscape-node /api-reference/openapi.json patch /v2/organizations/{orgId}/clarity/hierarchy/nodes/{nodeId} Rename a process landscape node or update its owner label (team manager or above for team processes; organization admin for areas) # Update Clarity Process Label Source: https://docs.duvo.ai/api-reference/clarity/update-clarity-process-label /api-reference/openapi.json patch /v2/organizations/{orgId}/clarity/process-labels/{labelId} Update process tags for an organization. # Update Clarity Process Link Source: https://docs.duvo.ai/api-reference/clarity/update-clarity-process-link /api-reference/openapi.json patch /v2/organizations/{orgId}/clarity/hierarchy/process-links/{process_link_id} Update a process-to-process link in the organization's Clarity landscape when the caller can manage both endpoint teams. # Assign Clarity Extra Capture Request Source: https://docs.duvo.ai/api-reference/clarityv2/assign-clarity-extra-capture-request /api-reference/openapi.json patch /v2/clarity-v2/processes/{process_id}/transformation-proposals/{transformation_proposal_id}/extra-capture-requests/{request_id}/assign Assign (or unassign, with `user_id: null`) a team member to fulfil an extra-capture request. Restricted to admins and managers. # Build Clarity Automation Source: https://docs.duvo.ai/api-reference/clarityv2/build-clarity-automation /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/automation Hand the latest transformation proposal for a v2 clarity process off to the workflow-builder pipeline. Returns 202 with the new run id; the LLM run completes asynchronously. # Complete Clarity Artifact Import Source: https://docs.duvo.ai/api-reference/clarityv2/complete-clarity-artifact-import /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/artifact-imports/{capture_id}/complete Complete a Miro artifact import after uploading to the signed URL. The uploaded bytes are validated before the import becomes a usable Clarity capture. # Create Clarity Artifact Import Upload URL Source: https://docs.duvo.ai/api-reference/clarityv2/create-clarity-artifact-import-upload-url /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/artifact-imports/create-upload-url Create a signed upload URL for importing a Miro export into a Clarity v2 process. Supports SVG, XML, PNG, and JPEG exports. The caller must upload the file to the returned URL, then complete the import. # Create Clarity Invite Link Source: https://docs.duvo.ai/api-reference/clarityv2/create-clarity-invite-link /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/invite-link Create or regenerate a process-scoped Clarity interview invite link. Only the process creator or team managers can create invite links; creating a new link invalidates any prior active link for the process. # Generate Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/generate-clarity-process-snapshot /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/generate Trigger a snapshot generation pipeline for a v2 clarity process, selected by kind. `current_process` runs the generateCurrentProcess pipeline (body fields are proposal-only and rejected); `transformation_proposal` runs the generate or regenerate proposal pipeline. Returns 202 immediately and finalises asynchronously via the cc-server webhook stream. # Get Clarity Artifact Chat Messages Source: https://docs.duvo.ai/api-reference/clarityv2/get-clarity-artifact-chat-messages /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/artifact-chat/conversations/{conversation_id}/messages Load the latest artifact-chat messages for one active conversation, returned oldest-first. # Get Clarity Capture Source: https://docs.duvo.ai/api-reference/clarityv2/get-clarity-capture /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/captures/{capture_id} Get a single Clarity v2 capture including full transcript and video transcript. Use this when the process was loaded with captures=lite, or when only one capture's transcript is needed. # Get Clarity Process Source: https://docs.duvo.ai/api-reference/clarityv2/get-clarity-process /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id} Get the v2 read model for a clarity process: the process row (with operational fields like generation_error, generation_progress, custom_prompt), its captures, and the lightweight version arrays for both snapshot tabs. The full payload of any specific snapshot is fetched lazily via the unified per-snapshot detail endpoint (`GET .../snapshots/:kind/:id`); this read model deliberately doesn't carry it so the response stays small. # Get Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/get-clarity-process-snapshot /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id} Fetch the full payload for a Clarity v2 process snapshot of either kind. # List Clarity Artifact Chat Conversations Source: https://docs.duvo.ai/api-reference/clarityv2/list-clarity-artifact-chat-conversations /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/artifact-chat/conversations List the current user's recent non-deleted artifact-chat conversations for a Clarity v2 process and snapshot kind. # List Clarity Extra Capture Requests Source: https://docs.duvo.ai/api-reference/clarityv2/list-clarity-extra-capture-requests /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/transformation-proposals/{transformation_proposal_id}/extra-capture-requests List active extra-capture requests for a given transformation proposal of a Clarity v2 process. The caller is expected to know the proposal id from the V2 read model and skip the call when no proposal exists yet. # List Clarity Process Snapshots Source: https://docs.duvo.ai/api-reference/clarityv2/list-clarity-process-snapshots /api-reference/openapi.json get /v2/clarity-v2/processes/{process_id}/snapshots/{kind} List lightweight Clarity v2 process snapshots for one kind. # List Clarity Process Summaries Source: https://docs.duvo.ai/api-reference/clarityv2/list-clarity-process-summaries /api-reference/openapi.json get /v2/teams/{teamId}/clarity-v2/processes/summaries Cross-process portfolio digest for every completed Clarity process on the team: per-process summary, SWOT, projected impact, and a step skeleton (role, system, and flow edges) — without step prose or source excerpts. Paginated (default 5, max 10). Use this to answer portfolio-wide questions in one pass; fetch a single process's full detail via getClarityProcessSnapshot only for the few that matter. # List Clarity Processes Source: https://docs.duvo.ai/api-reference/clarityv2/list-clarity-processes /api-reference/openapi.json get /v2/teams/{teamId}/clarity-v2/processes List Clarity processes for the current team, most recently updated first. Returns lightweight metadata (capture counts, contributors, status) suitable for building a picker; the per-process read model is available via `GET /v2/teams/:team_id/clarity-v2/processes/:process_id` for v2 rows and `GET /v2/teams/:team_id/clarity/processes/:id` for legacy v1 rows. Both v1 (legacy) and v2 processes are returned by default; use `search`, `status`, and `version` to narrow discovery. Capped at 100 per page. # Post v2clarity v2processes artifact chatmessages Source: https://docs.duvo.ai/api-reference/clarityv2/post-v2clarity-v2processes-artifact-chatmessages /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/artifact-chat/messages Submit a persisted artifact-chat user message and start a text turn. # Postprocess Clarity Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/postprocess-clarity-snapshot /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/postprocess Re-run postprocessing agents on an existing v2 clarity snapshot. Targets either the current-process snapshot or the transformation-proposal snapshot, identified by id in the body. Flips the process status to `generating` and returns 202 immediately; agents run asynchronously and flip the status back to `review` once they settle. # Promote Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/promote-clarity-process-snapshot /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id}/promote Promote a draft or historic Clarity v2 snapshot to live for its kind. # Put v2clarity v2processes artifact chatmessages Source: https://docs.duvo.ai/api-reference/clarityv2/put-v2clarity-v2processes-artifact-chatmessages /api-reference/openapi.json put /v2/clarity-v2/processes/{process_id}/artifact-chat/messages/{message_id} Accept or decline a persisted artifact-chat patch proposal. # Revert Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/revert-clarity-process-snapshot /api-reference/openapi.json delete /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id} Archive a Clarity v2 snapshot of either kind. If the live row is archived, the repository auto-promotes the latest historic row of the same kind. # Save Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/save-clarity-process-snapshot /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/save Save user edits as the live Clarity v2 snapshot for the selected kind. # Stop Clarity Process Snapshot Source: https://docs.duvo.ai/api-reference/clarityv2/stop-clarity-process-snapshot /api-reference/openapi.json post /v2/clarity-v2/processes/{process_id}/snapshots/{kind}/stop Stop an in-flight snapshot generation for the selected kind. Reads the sandbox id from the process row, kills the sandbox, flips the process back to `review`, and clears the sandbox marker so any late webhook from the killed run is dropped as stale. # Authorize MCP OAuth Source: https://docs.duvo.ai/api-reference/connections/authorize-mcp-oauth /api-reference/openapi.json post /v2/teams/{teamId}/connections/oauth/mcp/start Start an OAuth-based connection with a remote MCP server using Dynamic Client Registration. Returns an authorization URL the user must open in a browser; once they grant consent, Duvo creates the matching connection and redirects the browser to the optional `returnUrl`. # Check MCP OAuth Source: https://docs.duvo.ai/api-reference/connections/check-mcp-oauth /api-reference/openapi.json post /v2/connections/oauth/mcp/check Probe an MCP server URL to discover whether it supports OAuth Dynamic Client Registration. Returns the authorization endpoint and required scopes when supported. Useful as a precursor to `/v2/teams/:team_id/connections/oauth/mcp/start` or `/v2/teams/:team_id/connections`. Performs no writes. # Create Connection Source: https://docs.duvo.ai/api-reference/connections/create-connection /api-reference/openapi.json post /v2/teams/{teamId}/connections Create a new user-provided connection (custom MCP server) for the current team. OAuth-based integrations (native) require an interactive browser flow — start them with the dedicated OAuth endpoints (`/v2/teams/:team_id/connections/oauth/native/:provider/start` or `/v2/teams/:team_id/connections/oauth/mcp/start`) instead of calling this endpoint directly. # Delete Connection Source: https://docs.duvo.ai/api-reference/connections/delete-connection /api-reference/openapi.json delete /v2/connections/{connection_id} Delete a connection (disconnects the user's connection and removes any triggers bound to it). # Get Connection Source: https://docs.duvo.ai/api-reference/connections/get-connection /api-reference/openapi.json get /v2/connections/{connection_id} Get one of your connections by ID. # Get Connection Credentials Source: https://docs.duvo.ai/api-reference/connections/get-connection-credentials /api-reference/openapi.json get /v2/connections/{connection_id}/credentials Get the header keys configured for a connection. Sensitive values (api keys, tokens, passwords) are returned as empty strings — the response only reveals which credential fields are set, never their values. # List Connections Source: https://docs.duvo.ai/api-reference/connections/list-connections /api-reference/openapi.json get /v2/teams/{teamId}/connections List the authenticated user's connections (connected integration instances) for the current team. Includes team-shared instances visible to the caller when the org-level Connections sharing setting is on. Filter by integration type with the `type` query parameter. # Probe an MCP server for available tools Source: https://docs.duvo.ai/api-reference/connections/probe-an-mcp-server-for-available-tools /api-reference/openapi.json post /v2/teams/{teamId}/connections/mcp/probe Probe an MCP server URL and list the tools it exposes. Useful as a dry-run before creating a connection — verifies the URL is reachable, that authentication headers (if any) are correct, and surfaces the tool catalog. Performs no writes; sits alongside `/v2/teams/:team_id/connections/oauth/mcp/check` (which probes the same URL for OAuth support). # Start Native OAuth Source: https://docs.duvo.ai/api-reference/connections/start-native-oauth /api-reference/openapi.json post /v2/teams/{teamId}/connections/oauth/native/{provider}/start Start an OAuth-based connection with a native provider (Gmail, Google Sheets, Outlook, etc.). Returns an authorization URL that must be opened in a browser by a human end-user; once they grant consent, Duvo creates the matching connection and redirects the browser to the optional `return_url` (or the Duvo dashboard if none is provided). Poll `/v2/teams/:team_id/connections` to detect the new connection. # Update Connection Source: https://docs.duvo.ai/api-reference/connections/update-connection /api-reference/openapi.json patch /v2/connections/{connection_id} Update an existing connection. For sensitive header values, sending an empty string keeps the existing value; send a new value to overwrite. Toggling `shared` moves the connection between personal and team-shared. # Attach Revision Login Source: https://docs.duvo.ai/api-reference/credentials/attach-revision-login /api-reference/openapi.json post /v2/agents/{agentId}/revisions/{buildId}/logins Attach a login to a revision so the agent can use it during Runs spawned from that revision. Personal logins can only be attached by their owner; team-shared logins require builder permissions. # Create credential Source: https://docs.duvo.ai/api-reference/credentials/create-credential /api-reference/openapi.json post /v2/teams/{teamId}/browser-agent/credentials/{userId} Create a login. At least one of `password` or `otp_secret` must be provided. Personal by default; pass `shared: true` to create a team-shared login (requires manager role). # Delete credential by id Source: https://docs.duvo.ai/api-reference/credentials/delete-credential-by-id /api-reference/openapi.json delete /v2/teams/{teamId}/browser-agent/credentials/{userId}/{id} Delete a login by id. Deleting a team-shared login requires manager role. # Detach Revision Login Source: https://docs.duvo.ai/api-reference/credentials/detach-revision-login /api-reference/openapi.json delete /v2/agents/{agentId}/revisions/{buildId}/logins/{exposedCredentialId} Detach a login from a revision. Personal logins can only be detached by their owner; team-shared logins require builder permissions. # Get credential by id Source: https://docs.duvo.ai/api-reference/credentials/get-credential-by-id /api-reference/openapi.json get /v2/teams/{teamId}/browser-agent/credentials/{userId}/{id} Get a login by id. Returns the encrypted password/otp_secret blobs — only the owner or team members can access it. # List credentials for user and team Source: https://docs.duvo.ai/api-reference/credentials/list-credentials-for-user-and-team /api-reference/openapi.json get /v2/teams/{teamId}/browser-agent/credentials/{userId} List browser-login credentials visible to the caller for the current team — team-shared (user_id IS NULL) plus the caller's own personal logins. Optionally filter by `domain`. Passwords and OTP secrets are never returned; only metadata flags indicating whether they are set. # List Revision Logins Source: https://docs.duvo.ai/api-reference/credentials/list-revision-logins /api-reference/openapi.json get /v2/agents/{agentId}/revisions/{buildId}/logins List logins attached to a specific revision (build) of an assignment. Returns metadata only — passwords and OTP secrets are never exposed. # Update credential by id Source: https://docs.duvo.ai/api-reference/credentials/update-credential-by-id /api-reference/openapi.json patch /v2/teams/{teamId}/browser-agent/credentials/{userId}/{id} Update a login by id. At least one of password or otp_secret must remain set after the update. Editing a team-shared login or toggling sharing requires manager role. # Answer Pulse Dashboard Question Source: https://docs.duvo.ai/api-reference/duvo-pulse/answer-pulse-dashboard-question /api-reference/openapi.json post /v2/artifacts/{artifactId}/answer Answer a pending question the Duvo Pulse agent asked and resume the paused run (creator or team editors). Use the toolCallId from the dashboard's message transcript. # Attach Pulse Dashboard Connection Source: https://docs.duvo.ai/api-reference/duvo-pulse/attach-pulse-dashboard-connection /api-reference/openapi.json post /v2/artifacts/{artifactId}/connections Attach one of your connections (data sources) to a Duvo Pulse dashboard so the agent can use its tools (creator only). # Create Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/create-pulse-dashboard /api-reference/openapi.json post /v2/artifacts Create a new Duvo Pulse dashboard from a natural-language prompt (e.g. 'open cases by queue this week') and dispatch the first generation turn. Generation is asynchronous — poll GET /artifacts/{artifactId} until status is completed. The dashboard is private to you unless you set visibility to 'team', which shares it with your whole team straight away — with permission 'view' (teammates see the dashboard) or 'edit' (teammates can also iterate on it). # Delete Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/delete-pulse-dashboard /api-reference/openapi.json delete /v2/artifacts/{artifactId} Delete a Duvo Pulse dashboard. Only the creator can delete it. # Detach Pulse Dashboard Connection Source: https://docs.duvo.ai/api-reference/duvo-pulse/detach-pulse-dashboard-connection /api-reference/openapi.json delete /v2/artifacts/{artifactId}/connections/{connectionId} Detach a connection (data source) from a Duvo Pulse dashboard (creator only). # Duplicate Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/duplicate-pulse-dashboard /api-reference/openapi.json post /v2/artifacts/{artifactId}/duplicate Duplicate a Duvo Pulse dashboard, producing an idle clone of the current rendered dashboard. The conversation history, shares, and connections are not copied. # Export Pulse Dashboard Html Source: https://docs.duvo.ai/api-reference/duvo-pulse/export-pulse-dashboard-html /api-reference/openapi.json get /v2/artifacts/{artifactId}/export/html Render a Duvo Pulse dashboard to a self-contained static HTML snapshot (text/html, data baked in). 404 until the first generation turn has produced HTML. # Get Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/get-pulse-dashboard /api-reference/openapi.json get /v2/artifacts/{artifactId} Get a Duvo Pulse dashboard's metadata and generation status. When status is completed and html_code_present is true, fetch the rendered HTML from GET /artifacts/{artifactId}/render; the conversation is served by GET /artifacts/{artifactId}/messages. # Get Pulse Dashboard Html Source: https://docs.duvo.ai/api-reference/duvo-pulse/get-pulse-dashboard-html /api-reference/openapi.json get /v2/artifacts/{artifactId}/render Serve a Duvo Pulse dashboard's rendered HTML document (text/html, not JSON). 404 until the first generation turn has produced HTML. # Get Pulse Dashboard Pdf Source: https://docs.duvo.ai/api-reference/duvo-pulse/get-pulse-dashboard-pdf /api-reference/openapi.json get /v2/artifacts/{artifactId}/export/pdf Render a Duvo Pulse dashboard to a PDF document (application/pdf, not JSON). 404 until the first generation turn has produced HTML. # Get Pulse Dashboard Version Html Source: https://docs.duvo.ai/api-reference/duvo-pulse/get-pulse-dashboard-version-html /api-reference/openapi.json get /v2/artifacts/{artifactId}/revisions/{revisionId}/render Serve a specific version's rendered HTML document for a Duvo Pulse dashboard (text/html, requires edit access). # List Pulse Dashboard Connections Source: https://docs.duvo.ai/api-reference/duvo-pulse/list-pulse-dashboard-connections /api-reference/openapi.json get /v2/artifacts/{artifactId}/connections List the connections (data sources) attached to a Duvo Pulse dashboard (creator only). # List Pulse Dashboard Messages Source: https://docs.duvo.ai/api-reference/duvo-pulse/list-pulse-dashboard-messages /api-reference/openapi.json get /v2/artifacts/{artifactId}/messages List the chat transcript of a Duvo Pulse dashboard's live version (requires edit access). Returns the most recent page by default, oldest first within the page; pass `before` (a message id from a previous page) to walk back through older messages. Messages from other version branches are not included. # List Pulse Dashboard Versions Source: https://docs.duvo.ai/api-reference/duvo-pulse/list-pulse-dashboard-versions /api-reference/openapi.json get /v2/artifacts/{artifactId}/revisions List the version history of a Duvo Pulse dashboard, newest first (requires edit access). Use the version id with the restore and version-render endpoints. # List Pulse Dashboards Source: https://docs.duvo.ai/api-reference/duvo-pulse/list-pulse-dashboards /api-reference/openapi.json get /v2/artifacts List your Duvo Pulse dashboards (live, agent-generated visualizations of your Duvo data), most recently updated first. # Move Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/move-pulse-dashboard /api-reference/openapi.json post /v2/teams/{teamId}/artifacts/{artifactId}/move Move a Pulse dashboard from the team in the URL to another team, keeping only its latest revision (chat history and older revisions are deleted). The caller must be a Manager or above on both teams. Pass dryRun=true to preview which Connections reconnect vs drop without applying changes. # Publish Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/publish-pulse-dashboard /api-reference/openapi.json post /v2/artifacts/{artifactId}/publish Publish (share) a Duvo Pulse dashboard to your whole team or your whole organization, or revert it to private (creator only). When publishing, set permission to 'view' (teammates see the dashboard) or 'edit' (teammates can also iterate on it); organization-wide viewers outside the team always get view-only access. # Refresh Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/refresh-pulse-dashboard /api-reference/openapi.json post /v2/artifacts/{artifactId}/refresh Trigger an on-demand data refresh of a Duvo Pulse dashboard. The dashboard regenerates its connection-sourced values in the background — poll GET /artifacts/{artifactId} for status. # Restore Pulse Dashboard Version Source: https://docs.duvo.ai/api-reference/duvo-pulse/restore-pulse-dashboard-version /api-reference/openapi.json post /v2/artifacts/{artifactId}/revisions/{revisionId}/restore Restore a previous version of a Duvo Pulse dashboard, making it live again (requires edit access). Non-destructive — it moves the head pointer to the chosen version. # Send Pulse Dashboard Message Source: https://docs.duvo.ai/api-reference/duvo-pulse/send-pulse-dashboard-message /api-reference/openapi.json post /v2/artifacts/{artifactId}/messages Send an instruction to iterate on a Duvo Pulse dashboard (e.g. 'make it a bar chart', 'filter to last 14 days'). The creator can always iterate; teammates can too when the Pulse is published to the team with edit access. The agent regenerates asynchronously — poll GET /artifacts/{artifactId} for status. # Stop Pulse Dashboard Message Source: https://docs.duvo.ai/api-reference/duvo-pulse/stop-pulse-dashboard-message /api-reference/openapi.json post /v2/artifacts/{artifactId}/stop Stop an in-flight Duvo Pulse generation turn. Only the creator can stop. Flips the dashboard to 'interrupted' and keeps any streamed-so-far reply; stopping when nothing is generating is a successful no-op. # Update Pulse Dashboard Source: https://docs.duvo.ai/api-reference/duvo-pulse/update-pulse-dashboard /api-reference/openapi.json patch /v2/artifacts/{artifactId} Update a Duvo Pulse dashboard's settings — rename it. Only the creator can update it. # Create File Upload URL Source: https://docs.duvo.ai/api-reference/files/create-file-upload-url /api-reference/openapi.json post /v2/teams/{teamId}/files/create-upload-url Generate a signed URL for uploading a file directly to GCS. # Delete File Source: https://docs.duvo.ai/api-reference/files/delete-file /api-reference/openapi.json delete /v2/teams/{teamId}/files/{path} Delete a file from team storage. # Get File Content Source: https://docs.duvo.ai/api-reference/files/get-file-content /api-reference/openapi.json get /v2/teams/{teamId}/files/content/{path} Get the content of a text file. # Get File Download URL Source: https://docs.duvo.ai/api-reference/files/get-file-download-url /api-reference/openapi.json get /v2/teams/{teamId}/files/download-url/{path} Generate a signed download URL for a file. # List Files Source: https://docs.duvo.ai/api-reference/files/list-files /api-reference/openapi.json get /v2/teams/{teamId}/files List files for the current team. # Rename File Source: https://docs.duvo.ai/api-reference/files/rename-file /api-reference/openapi.json patch /v2/teams/{teamId}/files Rename a file in team storage. # Update File Content Source: https://docs.duvo.ai/api-reference/files/update-file-content /api-reference/openapi.json put /v2/teams/{teamId}/files/content/{path} Update the content of a text file. # Developer Platform API Source: https://docs.duvo.ai/api-reference/index Use the Duvo Developer Platform API to start runs, manage agents, review cases, and integrate Duvo into your own code, scripts, and pipelines. The Duvo Developer Platform API lets you drive Duvo from your own code, scripts, and pipelines. Use it to automate core team workflows and integrate Duvo with the systems your team already runs on. With the API, you can: * Start Runs * Manage Agents * Review Cases * Move Files in and out of Duvo * Manage Connections ## Authentication The API authenticates requests with an API key. 1. Generate a key in the Duvo dashboard at [Your Profile → API keys](https://app.duvo.ai/settings/profile#api-keys). Choose whether the key is scoped to a single team or works across all teams you can access. Users with the Manager role or above can also create keys for a specific team at [Team Settings → API keys](https://app.duvo.ai/settings/api-keys). 2. Send the key as a bearer token on every request: ``` Authorization: Bearer ``` API keys are scoped to a single team or to all teams the owner can access, and inherit the permissions of the user who generated them. ## Base URL and versioning The current version of the API is **v2**. All endpoints are served under: ``` https://api.duvo.ai/v2 ``` The paths in the tables below are shown relative to that prefix. Team-scoped endpoints include your team ID in the path (`/teams/{teamId}/...`); list the teams your key can act on with `GET /teams`. Endpoints exposed as MCP tools are listed in [Available MCP Tools](/mcp/available-tools). **v1 is deprecated** and will be sunset on **15 June 2026** — new integrations should target `/v2`. ## Endpoints ### Agents | Method | Path | Description | | ------ | ------------------------------------------- | ------------------------- | | GET | `/teams/{teamId}/agents` | List Agents for your team | | POST | `/teams/{teamId}/agents` | Create a new Agent | | GET | `/agents/{agent_id}` | Get an Agent by ID | | PATCH | `/agents/{agent_id}` | Update an Agent | | DELETE | `/agents/{agent_id}` | Delete an Agent | | GET | `/teams/{teamId}/agent-folders` | List Agent folders | | POST | `/teams/{teamId}/agent-folders` | Create a folder | | PATCH | `/agent-folders/{folder_id}` | Rename or move a folder | | DELETE | `/agent-folders/{folder_id}` | Delete a folder | | POST | `/teams/{teamId}/agent-folders/move-agents` | Move Agents into a folder | ### Setups | Method | Path | Description | | ------ | ----------------------------------------- | ------------------------ | | GET | `/agents/{agent_id}/revisions` | List Setups for an Agent | | POST | `/agents/{agent_id}/revisions` | Create a new Setup | | GET | `/agents/{agent_id}/revisions/{build_id}` | Get a Setup by ID | | PATCH | `/revisions/{build_id}` | Update a Setup | | POST | `/revisions/{build_id}/promote` | Promote a Setup to live | ### Runs | Method | Path | Description | | ------ | ---------------------------------------------------- | -------------------------------------- | | GET | `/runs` | List Runs for your team | | POST | `/runs` | Start a new Run | | GET | `/runs/{run_id}` | Get a Run's status | | GET | `/runs/{run_id}/messages` | List messages from a Run | | POST | `/runs/{run_id}/messages` | Send a message to an active Run | | POST | `/runs/{run_id}/human-requests/{request_id}/respond` | Respond to a human-in-the-loop request | | POST | `/runs/{run_id}/stop` | Stop an active Run | ### Files | Method | Path | Description | | ------ | ------------------------------------------- | ------------------------------ | | GET | `/teams/{teamId}/files` | List Files for your team | | POST | `/teams/{teamId}/files/create-upload-url` | Generate a signed upload URL | | GET | `/teams/{teamId}/files/content/{path}` | Get a file's text content | | PUT | `/teams/{teamId}/files/content/{path}` | Update a file's text content | | GET | `/teams/{teamId}/files/download-url/{path}` | Generate a signed download URL | | PATCH | `/teams/{teamId}/files` | Rename a file | | DELETE | `/teams/{teamId}/files/{path}` | Delete a file | ### Cases and Queues | Method | Path | Description | | ------ | ------------------------------------------------ | ------------------------------------------ | | GET | `/teams/{teamId}/queues` | List queues | | POST | `/teams/{teamId}/queues` | Create a queue | | GET | `/queues/{queue_id}` | Get a queue | | PATCH | `/queues/{queue_id}` | Update a queue | | DELETE | `/queues/{queue_id}` | Delete a queue | | GET | `/queues/{queue_id}/agents` | List Agents bound to a queue | | GET | `/queues/{queue_id}/cases` | List cases in a queue | | POST | `/queues/{queue_id}/cases/search` | Search cases | | POST | `/queues/{queue_id}/cases` | Create cases | | DELETE | `/queues/{queue_id}/cases` | Delete every case in a queue (destructive) | | POST | `/queues/{queue_id}/cases/bulk-reprocess` | Re-process cases on a queue consumer Agent | | POST | `/queues/{queue_id}/cases/bulk-update-status` | Update the status of multiple cases | | POST | `/queues/{queue_id}/cases/bulk-delete` | Delete a batch of cases | | GET | `/cases/{case_id}` | Get a case | | DELETE | `/cases/{case_id}` | Delete a case | | GET | `/cases/{case_id}/runs` | List Runs for a case | | GET | `/cases/{case_id}/runs/{run_id}/recent-messages` | Get recent messages from a case Run | ### Case Labels | Method | Path | Description | | ------ | -------------------------------------------------- | ------------------------- | | GET | `/queues/{queue_id}/labels` | List labels in a queue | | POST | `/queues/{queue_id}/labels` | Create a label | | PATCH | `/queues/{queue_id}/labels/{label_id}` | Update a label | | DELETE | `/queues/{queue_id}/labels/{label_id}` | Delete a label | | GET | `/queues/{queue_id}/cases/{case_id}/labels` | List labels on a case | | POST | `/queues/{queue_id}/cases/{case_id}/labels` | Assign labels to a case | | POST | `/queues/{queue_id}/cases/{case_id}/labels/unlink` | Remove labels from a case | ### Case Triggers | Method | Path | Description | | ------ | --------------------------------------------------- | ------------------------- | | GET | `/agents/{agent_id}/case-triggers` | List case triggers | | POST | `/agents/{agent_id}/case-triggers` | Create a case trigger | | GET | `/agents/{agent_id}/case-triggers/{trigger_id}` | Get a case trigger | | PATCH | `/agents/{agent_id}/case-triggers/{trigger_id}` | Update a case trigger | | DELETE | `/agents/{agent_id}/case-triggers/{trigger_id}` | Delete a case trigger | | GET | `/agents/{agent_id}/case-triggers/conflict-preview` | Preview trigger conflicts | ### Connections | Method | Path | Description | | ------ | ----------------------------------------------------------- | ---------------------------------------------------------------------- | | GET | `/teams/{teamId}/integrations` | List available connection types | | POST | `/teams/{teamId}/integrations/custom` | Register a custom MCP server | | DELETE | `/integrations/custom/{custom_integration_id}` | Remove a custom MCP server | | GET | `/teams/{teamId}/connections` | List authorized Connections | | POST | `/teams/{teamId}/connections` | Create a Connection | | GET | `/connections/{connection_id}` | Get a Connection | | PATCH | `/connections/{connection_id}` | Update a Connection | | DELETE | `/connections/{connection_id}` | Remove a Connection | | GET | `/connections/{connection_id}/credentials` | Get the header keys configured for a Connection | | POST | `/teams/{teamId}/connections/mcp/probe` | Probe a connection's tool catalog | | POST | `/teams/{teamId}/connections/oauth/native/{provider}/start` | Start a native OAuth flow (Gmail, Google Sheets, Outlook, etc.) | | POST | `/teams/{teamId}/connections/oauth/mcp/start` | Start an OAuth flow for a remote MCP server | | POST | `/connections/oauth/mcp/check` | Check whether an MCP server supports OAuth Dynamic Client Registration | On the probe endpoint, a `success: false` response includes a `code`: `listing_unavailable` means there's nothing to list yet for that connection (not an error — some connections only expose tools once connected), while `probe_failed` means the probe genuinely failed. ### Skills | Method | Path | Description | | ------ | --------------------------------- | -------------------------------------------------------------------- | | GET | `/teams/{teamId}/skills` | List Skills for your team | | GET | `/skills/system` | List system-wide Skills | | POST | `/teams/{teamId}/skills` | Create or update a Skill from JSON | | POST | `/teams/{teamId}/skills/upload` | Create or update a Skill by uploading a SKILL.md file or ZIP archive | | GET | `/skills/{skill_id}/files` | List files in a Skill | | GET | `/skills/{skill_id}/files/{path}` | Get a Skill file's content | | PUT | `/skills/{skill_id}/files/{path}` | Update a Skill file | | GET | `/skills/{skill_id}/download` | Download a Skill archive | | DELETE | `/skills/{skill_id}` | Delete a Skill | | GET | `/skills/{skill_id}/assignments` | List Agents using a Skill | ### Secrets and Logins | Method | Path | Description | | ------ | --------------------------------------------------------- | ------------------- | | GET | `/teams/{teamId}/credentials` | List stored secrets | | POST | `/teams/{teamId}/credentials` | Create a secret | | GET | `/credentials/{id}` | Get a secret | | PATCH | `/credentials/{id}` | Update a secret | | DELETE | `/credentials/{id}` | Delete a secret | | GET | `/teams/{teamId}/browser-agent/credentials/{userId}` | List stored Logins | | POST | `/teams/{teamId}/browser-agent/credentials/{userId}` | Create a Login | | GET | `/teams/{teamId}/browser-agent/credentials/{userId}/{id}` | Get a Login | | PATCH | `/teams/{teamId}/browser-agent/credentials/{userId}/{id}` | Update a Login | | DELETE | `/teams/{teamId}/browser-agent/credentials/{userId}/{id}` | Delete a Login | ### Schedules | Method | Path | Description | | ------ | -------------------------------------------- | -------------------------------------- | | GET | `/agents/{agent_id}/schedules` | List schedules configured for an Agent | | POST | `/agents/{agent_id}/schedules` | Create a schedule for an Agent | | PATCH | `/agents/{agent_id}/schedules/{schedule_id}` | Update a schedule | | DELETE | `/agents/{agent_id}/schedules/{schedule_id}` | Delete a schedule | ### Memory | Method | Path | Description | | ------ | ---------------------------------------- | ---------------------------------- | | GET | `/agents/{agent_id}/memory/files` | List an Agent's memory files | | GET | `/agents/{agent_id}/memory/files/{path}` | Get a single memory file's content | ### Sandboxes | Method | Path | Description | | ------ | ------------------------------------- | ---------------------------------------------------- | | POST | `/sandboxes` | Create a new sandbox environment | | POST | `/sandboxes/{sandbox_id}/upload-urls` | Generate a signed URL to upload files into a sandbox | | GET | `/sandboxes/{sandbox_id}/files` | List files in a sandbox directory | | POST | `/sandboxes/{sandbox_id}/files` | Upload a file directly to a sandbox | ### Setup Configuration These endpoints attach Connections, Logins, and Secrets to a specific Setup (revision). | Method | Path | Description | | ------ | --------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | GET | `/agents/{agent_id}/revisions/{build_id}/integrations` | List Connections attached to a Setup | | POST | `/agents/{agent_id}/revisions/{build_id}/integrations` | Attach one or more Connections to a Setup | | DELETE | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}` | Remove a Connection from a Setup | | GET | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections` | List Connection instances for a Connection slot | | POST | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections` | Pin a specific Connection to a Connection slot | | DELETE | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections/{connection_id}` | Unpin a Connection from a Connection slot | | GET | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/queues` | List queues for a Connection slot | | PUT | `/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/queues` | Replace the queues for a Connection slot | | GET | `/agents/{agentId}/revisions/{buildId}/logins` | List Logins attached to a Setup | | POST | `/agents/{agentId}/revisions/{buildId}/logins` | Attach a Login to a Setup | | DELETE | `/agents/{agentId}/revisions/{buildId}/logins/{exposedCredentialId}` | Remove a Login from a Setup | | GET | `/agents/{agentId}/revisions/{buildId}/credentials` | List Secrets attached to a Setup | | POST | `/agents/{agentId}/revisions/{buildId}/credentials` | Attach a Secret to a Setup | | DELETE | `/agents/{agentId}/revisions/{buildId}/credentials/{credentialId}` | Remove a Secret from a Setup | ### Plugins | Method | Path | Description | | ------ | ------------------ | ------------------------------------------------------- | | GET | `/plugins/catalog` | List built-in plugins that can be referenced in a Setup | ### Team | Method | Path | Description | | ------ | ------------------------- | ---------------------------------- | | GET | `/teams` | List teams your API key can act on | | GET | `/teams/{teamId}` | Get your team's details | | GET | `/teams/{teamId}/members` | List team members | | GET | `/profile` | Get your user profile | ### Process Intelligence | Method | Path | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | | GET | `/teams/{teamId}/clarity-v2/processes` | List process captures for your team | | GET | `/clarity-v2/processes/{process_id}` | Get a process capture by ID | | GET | `/clarity-v2/processes/{process_id}/snapshots/{kind}` | List process snapshots of one kind | | GET | `/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id}` | Get a process snapshot | | POST | `/clarity-v2/processes/{process_id}/snapshots/{kind}/save` | Save user edits as the live snapshot | | POST | `/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id}/promote` | Promote a snapshot to live | | DELETE | `/clarity-v2/processes/{process_id}/snapshots/{kind}/{snapshot_id}` | Archive a snapshot | | POST | `/clarity-v2/processes/{process_id}/snapshots/{kind}/generate` | Generate a snapshot from captures | | POST | `/clarity-v2/processes/{process_id}/snapshots/{kind}/stop` | Stop a running snapshot generation | | POST | `/clarity-v2/processes/{process_id}/automation` | Build an Agent from a transformation proposal | | POST | `/clarity-v2/processes/{process_id}/postprocess` | Re-run postprocessing on an existing snapshot | | POST | `/clarity-v2/processes/{process_id}/invite-link` | Create or regenerate an interview invite link | | POST | `/clarity-v2/processes/{process_id}/artifact-imports/create-upload-url` | Create a signed upload URL for an artifact import | | POST | `/clarity-v2/processes/{process_id}/artifact-imports/{capture_id}/complete` | Complete an artifact import | | POST | `/clarity-v2/processes/{process_id}/artifact-chat/messages` | Send an artifact-chat message and start a turn | | PUT | `/clarity-v2/processes/{process_id}/artifact-chat/messages/{message_id}` | Accept or decline an artifact-chat patch proposal | | GET | `/clarity-v2/processes/{process_id}/transformation-proposals/{transformation_proposal_id}/extra-capture-requests` | List pending extra capture requests for a process | | PATCH | `/clarity-v2/processes/{process_id}/transformation-proposals/{transformation_proposal_id}/extra-capture-requests/{request_id}/assign` | Assign an extra capture request | # Create Custom Integration Source: https://docs.duvo.ai/api-reference/integrations/create-custom-integration /api-reference/openapi.json post /v2/teams/{teamId}/integrations/custom Create a custom integration type (team-level catalog entry) that users can then connect as user-provided MCP connections. Requires manager-or-above role. # Delete Custom Integration Source: https://docs.duvo.ai/api-reference/integrations/delete-custom-integration /api-reference/openapi.json delete /v2/integrations/custom/{custom_integration_id} Delete a custom integration type (team-level catalog entry) and cascade-remove related connections. Requires manager-or-above role. # List Integrations Source: https://docs.duvo.ai/api-reference/integrations/list-integrations /api-reference/openapi.json get /v2/teams/{teamId}/integrations List the team's integration catalog: built-in integration types plus any custom connection types defined for the team. OAuth authorization flows are browser-based and cannot be performed via this API; use the Duvo dashboard to complete OAuth-based connections. # Delete All Notifications Source: https://docs.duvo.ai/api-reference/notifications/delete-all-notifications /api-reference/openapi.json delete /v2/teams/{teamId}/notifications Soft-delete all notifications for the authenticated user's current team, read or unread. Returns the count of notifications that were deleted. Destructive — only call on explicit user request, never bulk-delete unprompted. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Delete Read Notifications Source: https://docs.duvo.ai/api-reference/notifications/delete-read-notifications /api-reference/openapi.json delete /v2/teams/{teamId}/notifications/read Soft-delete all read notifications for the authenticated user's current team. Returns the count of notifications that were deleted. Destructive — only call on explicit user request. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Dismiss Notification Source: https://docs.duvo.ai/api-reference/notifications/dismiss-notification /api-reference/openapi.json patch /v2/notifications/{id}/dismiss Dismiss an important notification for the authenticated user, unpinning their own row from the Important section. Only important notifications (currently: connection_broken) can be dismissed. Idempotent. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Get Notification Source: https://docs.duvo.ai/api-reference/notifications/get-notification /api-reference/openapi.json get /v2/notifications/{id} Get a single notification by id for the authenticated user. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Get Notification Batch Source: https://docs.duvo.ai/api-reference/notifications/get-notification-batch /api-reference/openapi.json get /v2/teams/{teamId}/notifications/batches/{id} Get a single notification batch by id for the authenticated user, with per-type live-member counts, unread count, and worst severity. Serves cold deep links and sidebar retention for batches the caller can no longer see in the feed. Requires the Notification Center feature; returns 404 when it is not enabled for the team, the batch does not exist, or it belongs to another recipient/team. # Get Notification Counts Source: https://docs.duvo.ai/api-reference/notifications/get-notification-counts /api-reference/openapi.json get /v2/teams/{teamId}/notifications/counts Per-type notification counts for the authenticated user's current team (optionally unread only). Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Get Notification Feed Source: https://docs.duvo.ai/api-reference/notifications/get-notification-feed /api-reference/openapi.json get /v2/teams/{teamId}/notifications/feed List the notification feed for the authenticated user's current team, most recent activity first. Each item is either an individual notification or a notification batch (a per-agent group of job_issue/eval_issue/job_done/schedule_issue notifications). Filter with type or unread; paginate with limit/cursor. The feed is eventually consistent — a batch's counts can lag a concurrent write by one page fetch. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Get Unread Notification Count Source: https://docs.duvo.ai/api-reference/notifications/get-unread-notification-count /api-reference/openapi.json get /v2/teams/{teamId}/notifications/unread-count Get the unread notification count for the authenticated user's current team. Each notification batch with unread members counts as 1, regardless of its member count. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # List Notifications Source: https://docs.duvo.ai/api-reference/notifications/list-notifications /api-reference/openapi.json get /v2/teams/{teamId}/notifications List notifications for the authenticated user's current team, most recent first. Filter with type, unread, severity, important, agentRunId, or processId; paginate with limit/cursor. Pass batchId to list only the live members of a notification batch, optionally ordered by sort=importance (only valid together with batchId). Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Mark All Notifications Read Source: https://docs.duvo.ai/api-reference/notifications/mark-all-notifications-read /api-reference/openapi.json post /v2/teams/{teamId}/notifications/mark-all-read Mark all notifications as read for the authenticated user's current team. Returns the count of notifications that were updated. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Mark Notification Batch Read Source: https://docs.duvo.ai/api-reference/notifications/mark-notification-batch-read /api-reference/openapi.json post /v2/teams/{teamId}/notifications/batches/{id}/read Mark every unread live member of a notification batch as read for the authenticated user. Pass `types` to narrow the mark-read to those member types (e.g. the page's active type filter); omit it to mark every live member. Returns the count of members that were updated. Requires the Notification Center feature; returns 404 when it is not enabled for the team or the batch does not exist or belongs to another recipient/team. # Mark Notification Read Source: https://docs.duvo.ai/api-reference/notifications/mark-notification-read /api-reference/openapi.json patch /v2/notifications/{id}/read Mark a notification as read for the authenticated user. Idempotent — calling it again on an already-read notification still returns success. Requires the Notification Center feature; returns 404 when it is not enabled for the team. # Create Org Team Source: https://docs.duvo.ai/api-reference/organizations/create-org-team /api-reference/openapi.json post /v2/organizations/{orgId}/teams Create a new team under an organization you administer. Requires an organization Admin, Executive, or Owner role. # Generate Clarity Process Landscape Source: https://docs.duvo.ai/api-reference/organizations/generate-clarity-process-landscape /api-reference/openapi.json post /v2/organizations/{orgId}/clarity/hierarchy/landscape/generate Start a process-landscape generation run for the organization from its eligible Clarity captures (organization executives and owners) # Get Clarity Hierarchy People Source: https://docs.duvo.ai/api-reference/organizations/get-clarity-hierarchy-people /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/hierarchy/people List the people attached to every authorized linked process node in the organization's Process Landscape. Returns a flat list where each person carries `nodeId` and `processId`, plus their role, invite status, and capture count. `truncated` is true when the node subtree or any single process roster was capped. # Get Clarity Process Landscape Source: https://docs.duvo.ai/api-reference/organizations/get-clarity-process-landscape /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/hierarchy/landscape Fetch the organization's full process landscape with process summaries, team assignments, and page-level stats # Get Org Insights Headline Source: https://docs.duvo.ai/api-reference/organizations/get-org-insights-headline /api-reference/openapi.json get /v2/organizations/{orgId}/insights/headline Get org-wide headline insight KPIs (run totals, success rate, distinct active agents and users) aggregated across every team in the organization. Requires an organization Admin, Executive, or Owner role. # Get Org Insights Metrics Source: https://docs.duvo.ai/api-reference/organizations/get-org-insights-metrics /api-reference/openapi.json get /v2/organizations/{orgId}/insights/metrics Get org-level insights metrics (runs, assignments, schedules) broken down per team across the organization. Requires an organization Admin, Executive, or Owner role. # Get Org Insights Usage Chart Source: https://docs.duvo.ai/api-reference/organizations/get-org-insights-usage-chart /api-reference/openapi.json get /v2/organizations/{orgId}/insights/usage-chart Get org-level run-volume buckets (scheduled vs on-demand) at day/week/month granularity across the organization. Requires an organization Admin, Executive, or Owner role. # Invite Org Member Source: https://docs.duvo.ai/api-reference/organizations/invite-org-member /api-reference/openapi.json post /v2/organizations/{orgId}/members Invite a person to an organization you administer, optionally assigning them to a team in that organization. Requires an organization Admin, Executive, or Owner role. You cannot grant a role higher than your own. # List Clarity Landscape Captures Source: https://docs.duvo.ai/api-reference/organizations/list-clarity-landscape-captures /api-reference/openapi.json get /v2/organizations/{orgId}/clarity/hierarchy/captures List the organization's eligible Process Landscape captures (completed interview/document transcripts not yet tied to a process) so they can seed new process proposals. # List My Organizations Source: https://docs.duvo.ai/api-reference/organizations/list-my-organizations /api-reference/openapi.json get /v2/organizations/mine List the organizations the current user belongs to, with their role (organization:member, organization:admin, organization:owner, or organization:executive) and member count in each. Use this to check whether the user has an admin-or-above role before calling organization-scoped endpoints, which reject lower roles with 403. # List Org Teams Source: https://docs.duvo.ai/api-reference/organizations/list-org-teams /api-reference/openapi.json get /v2/organizations/{orgId}/teams List teams belonging to an organization you are a member of, including your membership and role in each. # Propose Clarity Landscape Process Source: https://docs.duvo.ai/api-reference/organizations/propose-clarity-landscape-process /api-reference/openapi.json post /v2/organizations/{orgId}/clarity/hierarchy/proposed-processes Create a manual process in the organization's Process Landscape, either as an unassigned proposal or atomically assigned to an eligible team. # List Plugin Catalog Source: https://docs.duvo.ai/api-reference/plugins/list-plugin-catalog /api-reference/openapi.json get /v2/plugins/catalog List plugins that can be referenced by name in a build's plugins array. Builds may also reference any public GitHub repository URL (https://github.com/owner/repo) as a plugin; those are not enumerated here. # Create Queue Source: https://docs.duvo.ai/api-reference/queues/create-queue /api-reference/openapi.json post /v2/teams/{teamId}/queues Create a new queue. # Delete Queue Source: https://docs.duvo.ai/api-reference/queues/delete-queue /api-reference/openapi.json delete /v2/queues/{queue_id} Delete a queue. Interrupts all associated active runs first and returns the number of deleted cases plus the IDs of runs that were stopped. # Get Queue Source: https://docs.duvo.ai/api-reference/queues/get-queue /api-reference/openapi.json get /v2/queues/{queue_id} Get a queue by ID. # List Queue Agents Source: https://docs.duvo.ai/api-reference/queues/list-queue-agents /api-reference/openapi.json get /v2/queues/{queue_id}/agents List agents bound to a queue as producers (agents that push cases into the queue) or consumers (agents triggered by cases in the queue). # List Queues Source: https://docs.duvo.ai/api-reference/queues/list-queues /api-reference/openapi.json get /v2/teams/{teamId}/queues List queues for your team. # Update Queue Source: https://docs.duvo.ai/api-reference/queues/update-queue /api-reference/openapi.json patch /v2/queues/{queue_id} Update a queue. # Attach Revision Integrations Source: https://docs.duvo.ai/api-reference/revision-integrations/attach-revision-integrations /api-reference/openapi.json post /v2/agents/{agent_id}/revisions/{build_id}/integrations Attach one or more integrations to an agent revision. To pin specific connections after attachment, use pinRevisionIntegrationConnection. IMPORTANT for the case-queue-producer and case-queue-consumer integrations: attaching the integration alone is NOT enough — the slot points at no queue and will fail at runtime until you link at least one queue with replaceRevisionIntegrationQueues. After wiring up, call getRevisionCaseQueueSetup to confirm every case-queue slot has linked_queue_count > 0 before starting work. # Get Revision Case Queue Setup Source: https://docs.duvo.ai/api-reference/revision-integrations/get-revision-case-queue-setup /api-reference/openapi.json get /v2/agents/{agent_id}/revisions/{build_id}/case-queue-validation Check that this build's case-queue integration slots are wired up correctly. Returns, per case-queue-producer/consumer slot, how many queues are linked, plus whether your team owns any case queues. A slot with linked_queue_count of 0 is attached but points at no queue and will fail at runtime — link a queue with replaceRevisionIntegrationQueues before starting work. # List Revision Integration Connections Source: https://docs.duvo.ai/api-reference/revision-integrations/list-revision-integration-connections /api-reference/openapi.json get /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections List the connections you have pinned to this build's integration slot. Multi-pin is supported: you can pin multiple connections to the same slot. # List Revision Integration Queues Source: https://docs.duvo.ai/api-reference/revision-integrations/list-revision-integration-queues /api-reference/openapi.json get /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/queues List the queues linked to this build's case-queue integration slot. Only meaningful for case-queue-producer and case-queue-consumer integrations. # List Revision Integrations Source: https://docs.duvo.ai/api-reference/revision-integrations/list-revision-integrations /api-reference/openapi.json get /v2/agents/{agent_id}/revisions/{build_id}/integrations List integrations attached to an agent revision. # Pin Revision Integration Connection Source: https://docs.duvo.ai/api-reference/revision-integrations/pin-revision-integration-connection /api-reference/openapi.json post /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections Pin one of your connections (from GET /v2/teams/:team_id/connections) to this build's integration slot. Multi-pin is supported: a single user can pin multiple connections to the same slot. # Remove Revision Integration Source: https://docs.duvo.ai/api-reference/revision-integrations/remove-revision-integration /api-reference/openapi.json delete /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id} Remove an integration from an agent revision. Removes the slot for everyone on the revision, including all per-user connection pins. Requires edit permission on the agent. # Replace Revision Integration Queues Source: https://docs.duvo.ai/api-reference/revision-integrations/replace-revision-integration-queues /api-reference/openapi.json put /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/queues Replace the set of queues linked to this build's case-queue integration slot. Send the full desired queue list — any queues not in the list will be unlinked. Requires edit permission on the agent. After linking, call getRevisionCaseQueueSetup to confirm the slot now reports linked_queue_count > 0. # Unpin Revision Integration Connection Source: https://docs.duvo.ai/api-reference/revision-integrations/unpin-revision-integration-connection /api-reference/openapi.json delete /v2/agents/{agent_id}/revisions/{build_id}/integrations/{integration_id}/connections/{connection_id} Unpin one of your connections from this build's integration slot. The connection itself is not deleted; only the binding to this slot is removed. # Create Revision Source: https://docs.duvo.ai/api-reference/revisions/create-revision /api-reference/openapi.json post /v2/agents/{agent_id}/revisions Create a new revision for an existing agent. # Get Revision Source: https://docs.duvo.ai/api-reference/revisions/get-revision /api-reference/openapi.json get /v2/agents/{agent_id}/revisions/{build_id} Get a revision by ID. # List Agent Revisions Source: https://docs.duvo.ai/api-reference/revisions/list-agent-revisions /api-reference/openapi.json get /v2/agents/{agent_id}/revisions List revisions for an agent. # Promote Revision Source: https://docs.duvo.ai/api-reference/revisions/promote-revision /api-reference/openapi.json post /v2/revisions/{build_id}/promote Promote a draft or historic revision to the live version. The live revision is the one used by triggers and new runs. Fails if the revision is already live, or if a draft revision still has an active builder run. # Update Revision Source: https://docs.duvo.ai/api-reference/revisions/update-revision /api-reference/openapi.json patch /v2/revisions/{build_id} Update a revision's configuration, name, description, or handover targets. Returns the updated revision. # Get Run Source: https://docs.duvo.ai/api-reference/runs/get-run /api-reference/openapi.json get /v2/runs/{run_id} Get information about an agent run. Can be polled to check status. # Get Run Evaluation Source: https://docs.duvo.ai/api-reference/runs/get-run-evaluation /api-reference/openapi.json get /v2/agent/{agentId}/runs/{runId}/evaluation Get the latest evaluation analysis for a specific agent run (Run). # List Run Messages Source: https://docs.duvo.ai/api-reference/runs/list-run-messages /api-reference/openapi.json get /v2/runs/{run_id}/messages Get paginated messages for an agent run. Messages are returned in chronological order. # List Runs Source: https://docs.duvo.ai/api-reference/runs/list-runs /api-reference/openapi.json get /v2/teams/{teamId}/runs List runs for the current team. Supports filtering by agent, user, queue, status, etc. Messages, evaluation data, and queue metadata are included where available. # Post Run Message Source: https://docs.duvo.ai/api-reference/runs/post-run-message /api-reference/openapi.json post /v2/runs/{run_id}/messages Post a message to an agent run. This will persist the message and resume the agent execution if the run is in a resumable state (waiting, completed, or interrupted). # Respond To Human Request Source: https://docs.duvo.ai/api-reference/runs/respond-to-human-request /api-reference/openapi.json post /v2/runs/{run_id}/human-requests/{request_id}/respond Respond to a human-in-the-loop request. Use 'approved' (true/false) for approval-type requests, or 'answers' ({question: answer}) for question-type requests. Only works when the run is in 'waiting' status. # Start Run Source: https://docs.duvo.ai/api-reference/runs/start-run /api-reference/openapi.json post /v2/teams/{teamId}/runs Start a new agent run. Returns immediately with run info - does not wait for completion. # Stop Run Source: https://docs.duvo.ai/api-reference/runs/stop-run /api-reference/openapi.json post /v2/runs/{run_id}/stop Stop an agent run. No-op if the run is not currently running. # Create Sandbox Source: https://docs.duvo.ai/api-reference/sandboxes/create-sandbox /api-reference/openapi.json post /v2/sandboxes Create a new sandbox for file uploads. The returned sandbox_id can be passed to POST /v2/teams/:team_id/runs to stage data for a run. # Create Sandbox Upload URL Source: https://docs.duvo.ai/api-reference/sandboxes/create-sandbox-upload-url /api-reference/openapi.json post /v2/sandboxes/{sandbox_id}/upload-urls Get a presigned URL for uploading a file into a sandbox. Use for files larger than 10MB; smaller files can be uploaded directly via POST /v2/sandboxes/:sandbox_id/files. # List Sandbox Files Source: https://docs.duvo.ai/api-reference/sandboxes/list-sandbox-files /api-reference/openapi.json get /v2/sandboxes/{sandbox_id}/files List files in a sandbox directory. # Upload Sandbox File Source: https://docs.duvo.ai/api-reference/sandboxes/upload-sandbox-file /api-reference/openapi.json post /v2/sandboxes/{sandbox_id}/files Upload a file directly to the sandbox. Maximum file size is 10MB. For larger files, use POST /v2/sandboxes/:sandbox_id/upload-urls. # Create Schedule Source: https://docs.duvo.ai/api-reference/schedules/create-schedule /api-reference/openapi.json post /v2/agents/{agent_id}/schedules Create a schedule for an agent. The schedule fires against the agent's live build. The authenticated user owns the schedule. # Delete Schedule Source: https://docs.duvo.ai/api-reference/schedules/delete-schedule /api-reference/openapi.json delete /v2/agents/{agent_id}/schedules/{schedule_id} Delete a schedule. Owners may delete their own schedules; team superadmins may delete any schedule on agents in the current team. # List Agent Schedules Source: https://docs.duvo.ai/api-reference/schedules/list-agent-schedules /api-reference/openapi.json get /v2/agents/{agent_id}/schedules List all schedules configured for an agent. Returns the schedules you own on this agent. # Update Schedule Source: https://docs.duvo.ai/api-reference/schedules/update-schedule /api-reference/openapi.json patch /v2/agents/{agent_id}/schedules/{schedule_id} Update fields on an existing schedule. Only supplied fields are changed; omitted fields retain their current values. Owners may update their own schedules; team superadmins may update any schedule on agents in the current team. # Attach Revision Secret Source: https://docs.duvo.ai/api-reference/secrets/attach-revision-secret /api-reference/openapi.json post /v2/agents/{agentId}/revisions/{buildId}/credentials Attach an env-var secret to a revision so its keys are injected into Runs spawned from that revision. Personal secrets can only be attached by their owner; team-shared secrets require builder permissions. # Create Secret Source: https://docs.duvo.ai/api-reference/secrets/create-secret /api-reference/openapi.json post /v2/teams/{teamId}/credentials Create an env-var secret. Personal by default; pass `shared: true` to create a team-shared secret (requires manager role). # Delete Secret Source: https://docs.duvo.ai/api-reference/secrets/delete-secret /api-reference/openapi.json delete /v2/credentials/{id} Soft-delete an env-var secret. Deleting a team-shared secret requires manager role. # Detach Revision Secret Source: https://docs.duvo.ai/api-reference/secrets/detach-revision-secret /api-reference/openapi.json delete /v2/agents/{agentId}/revisions/{buildId}/credentials/{credentialId} Detach an env-var secret from a revision. Personal secrets can only be detached by their owner; team-shared secrets require builder permissions. # Get Secret Source: https://docs.duvo.ai/api-reference/secrets/get-secret /api-reference/openapi.json get /v2/credentials/{id} Get an env-var secret by id. Returns metadata and env var keys; secret values are never exposed. # List Revision Secrets Source: https://docs.duvo.ai/api-reference/secrets/list-revision-secrets /api-reference/openapi.json get /v2/agents/{agentId}/revisions/{buildId}/credentials List env-var secrets attached to a specific revision (build) of an assignment. Returns metadata and env-var keys only — secret values are never exposed. # List Secrets Source: https://docs.duvo.ai/api-reference/secrets/list-secrets /api-reference/openapi.json get /v2/teams/{teamId}/credentials List env-var secrets visible to the caller — team-shared (user_id IS NULL) plus the caller's own personal entries. Returns metadata and env-var keys only; secret values are never exposed. # Update Secret Source: https://docs.duvo.ai/api-reference/secrets/update-secret /api-reference/openapi.json patch /v2/credentials/{id} Update an env-var secret. Send `values` to replace all entries, or any of `rename_keys`, `remove_keys`, `add_values` for a non-destructive patch. Editing a team-shared secret or toggling sharing requires manager role. # Create Skill Source: https://docs.duvo.ai/api-reference/skills/create-skill /api-reference/openapi.json post /v2/teams/{teamId}/skills Create or update a skill from a JSON body. The server constructs SKILL.md from the provided fields and stores it. If a skill with the same name already exists in the team, it is updated. # Delete Skill Source: https://docs.duvo.ai/api-reference/skills/delete-skill /api-reference/openapi.json delete /v2/skills/{skill_id} Delete a skill for the current team. # Download Skill Source: https://docs.duvo.ai/api-reference/skills/download-skill /api-reference/openapi.json get /v2/skills/{skill_id}/download Download a custom skill as a ZIP archive. Only custom (team-owned) skills can be downloaded. # Get Skill File Content Source: https://docs.duvo.ai/api-reference/skills/get-skill-file-content /api-reference/openapi.json get /v2/skills/{skill_id}/files/{path} Get the content of a file in a skill. # List Skill Assignments Source: https://docs.duvo.ai/api-reference/skills/list-skill-assignments /api-reference/openapi.json get /v2/skills/{skill_id}/assignments List the agents in the current team whose live build references the given skill. Used to warn users that editing a skill will affect every agent that uses it. # List Skill Files Source: https://docs.duvo.ai/api-reference/skills/list-skill-files /api-reference/openapi.json get /v2/skills/{skill_id}/files List all files in a skill. # List Skills Source: https://docs.duvo.ai/api-reference/skills/list-skills /api-reference/openapi.json get /v2/teams/{teamId}/skills List all skills for the current team, including system skills. # List System Skills Source: https://docs.duvo.ai/api-reference/skills/list-system-skills /api-reference/openapi.json get /v2/skills/system List all system skills (skills available to all teams). # Update Skill File Source: https://docs.duvo.ai/api-reference/skills/update-skill-file /api-reference/openapi.json put /v2/skills/{skill_id}/files/{path} Update the content of a file in a skill. Only team skills can be edited. # Upload Skill Source: https://docs.duvo.ai/api-reference/skills/upload-skill /api-reference/openapi.json post /v2/teams/{teamId}/skills/upload Create or update a skill by uploading a SKILL.md file or a ZIP archive containing SKILL.md at the root. If a skill with the same name exists in the team, it will be updated. # Consume Agent Suggestion Source: https://docs.duvo.ai/api-reference/suggestions/consume-agent-suggestion /api-reference/openapi.json post /v2/agents/suggestions/{id}/consume Apply a suggestion: stage its change into the Agent's draft revision, then auto-clear any pending suggestions it makes moot. # Get Agent Suggestion Source: https://docs.duvo.ai/api-reference/suggestions/get-agent-suggestion /api-reference/openapi.json get /v2/agents/suggestions/{id} Fetch a single suggestion. Poll this after a 202 from consume: an AOP apply in flight reports payload.apply.state (running/failed); once consumed, applied_revision_id carries the draft revision the change was staged onto. # List Agent Suggestions Source: https://docs.duvo.ai/api-reference/suggestions/list-agent-suggestions /api-reference/openapi.json get /v2/agents/{agent_id}/suggestions List an Agent's suggestions. status=pending is the inbox; status=history is consumed/dismissed/auto-cleared. Reads lazily auto-clear stale pending items. # Reject Agent Suggestion Source: https://docs.duvo.ai/api-reference/suggestions/reject-agent-suggestion /api-reference/openapi.json post /v2/agents/suggestions/{id}/reject Dismiss a pending suggestion. # Get Profile Source: https://docs.duvo.ai/api-reference/team/get-profile /api-reference/openapi.json get /v2/profile Get the profile of the authenticated user (the owner of the API key). # Get Team Source: https://docs.duvo.ai/api-reference/team/get-team /api-reference/openapi.json get /v2/teams/{teamId} Get a team by ID. The caller must be scoped to the requested team. # List My Teams Source: https://docs.duvo.ai/api-reference/team/list-my-teams /api-reference/openapi.json get /v2/teams List teams the authenticated caller can act on. Team-scoped API keys see only the key's team; user-scoped API keys and OAuth callers see every team they're a member of. # List Team Members Source: https://docs.duvo.ai/api-reference/team/list-team-members /api-reference/openapi.json get /v2/teams/{teamId}/members List members of a team. The authenticated session or API key must be scoped to the requested team. # List Agent Trigger Types Source: https://docs.duvo.ai/api-reference/triggers/list-agent-trigger-types /api-reference/openapi.json get /v2/trigger-config/{agentId} List the trigger types available for an agent, grouped by integration. Use the returned `integration_slug` and `trigger_type` values when creating a trigger. # List Agent Triggers Source: https://docs.duvo.ai/api-reference/triggers/list-agent-triggers /api-reference/openapi.json get /v2/triggers/{agentId} List the trigger definitions the authenticated user owns on an agent (Agent in the Duvo UI). Triggers start a Run automatically when an external event fires (e.g. an email arrives or a Linear issue is created). # Upsert Agent Trigger Source: https://docs.duvo.ai/api-reference/triggers/upsert-agent-trigger /api-reference/openapi.json put /v2/triggers/{agentId} Create or update the authenticated user's trigger for an integration on an agent. The integration must already be connected to the agent (its OAuth connection set up in the Duvo dashboard). Set `enabled: false` to pause a trigger without deleting it. # Choosing How Your Agent Starts Source: https://docs.duvo.ai/best-practices/choosing-how-runs-start Manual Start Work, schedules, triggers, and Queues each fit a different shape of work. The start mechanism decides latency, retries, and what happens when Runs overlap. How an Agent starts is a design decision, not an afterthought. The start mechanism determines how fast the Agent reacts, what it receives as input, what happens when two Runs would overlap, and whether a missed event gets a second chance. This page helps you pick deliberately. ## The Decision in One Pass ```mermaid theme={"dark"} flowchart TD A[How does this work arrive?] --> B{Reacting to an event in
a connected service?} B -->|Yes| C[Event trigger] B -->|No| D{A stream of discrete items
that each need tracking?} D -->|Yes| E[Queue + consumer Agent] D -->|No| F{On a clock?} F -->|Yes| G[Schedule] F -->|No| H[Manual Start Work
or API] ``` | Mechanism | Fires | Best for | Watch out for | | -------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------- | | **Manual Start Work** | When a person clicks | Building, testing, one-off jobs | Everything downstream of a person remembering | | **[Schedule](/user-guide/assignment-features/scheduling-assignments)** | On a clock, in your timezone | Recurring reports, syncs, checks | Overlapping ticks are skipped; missed ticks aren't backfilled | | **[Event trigger](/user-guide/assignment-features/event-driven-triggers)** | New email, Slack message, Linear event, file drop, status change | Reacting to things as they happen | Polling triggers react on an interval, not instantly; set up per user | | **[Queue](/user-guide/assignment-features/case-queue)** | A Case arrives or comes back | Streams of items needing per-item tracking and retries | One consuming Agent per Queue | | **[API](/user-guide/running-assignments/running-assignments-via-api)** | Your system calls Duvo | Embedding Duvo in existing software | The caller owns retries and deduplication | ## Schedules Skip, They Don't Stack Two facts about schedules shape how you should design for them: * **If the previous Run is still going when the next tick fires, the tick is skipped** — Runs never stack up behind each other. A schedule whose work regularly outlasts its interval doesn't run more often; it runs less predictably. * **Missed ticks are not backfilled.** A tick that doesn't fire is gone; the next one fires on its own time. The design that survives both: make every scheduled Run self-healing. Instead of "process the last hour of orders", write the AOP as "process everything new since the last successful Run", tracking the last-seen state in [Agent Memory](/user-guide/assignment-features/assignment-memory). Then a skipped or missed tick costs latency, not data. Also worth knowing: each schedule has its own timezone, and schedules created through the [API](/user-guide/running-assignments/running-assignments-via-api) can carry an optional task prompt that is added to the Run when they fire — useful when several schedules on one Agent should emphasize different work. ## Triggers: Expect Once, Design for Twice Duvo tracks which items a trigger has already fired for, so a matching email or message normally starts exactly one Run. Still, write the AOP as if an occasional duplicate can happen — have it check whether the record it is about to create already exists before creating it. Cheap insurance, and it also makes manual re-runs safe. Things trigger authors regularly trip over: * **Enabling a trigger does not process the backlog.** On first activation, existing items in the inbox or folder are marked as seen without firing — only new items from that point on start Runs. If the backlog matters, have someone Start Work once manually to work through it. * **The event arrives as the Run's opening message.** The triggering email, message, or file lands as input on top of the AOP — so the AOP should say what to do with "the item in this Run" rather than instructing the Agent to go find work. * **Triggers are personal.** Each trigger watches its creator's account and its Runs use that person's access — see [Connections and Logins That Don't Break](/best-practices/reliable-connections). ## Queues When Items Matter Individually If each item needs its own record, its own retry story, and its own outcome someone can review, a trigger that just starts a Run isn't enough — put the items in a Queue as Cases and give the Queue a consumer Agent. You get per-Case status, postponing, and parallel processing for free. The design rules for that live in [Designing Work Around Queues and Cases](/best-practices/queues-and-cases). One rule to repeat here because it fails confusingly: **a Queue should have exactly one consuming Agent**. When two Agents both have triggers on the same Queue, Duvo refuses to pick a winner and conflicted Cases don't run at all. The setup flow warns you when you're about to create this situation. ## When a Start Fails A Run that starts and fails is not automatically retried — for schedules the next tick simply fires on time, and for Cases you can reprocess from the Queue. Design recovery into the mechanism you chose (self-healing schedules, reprocessable Cases) rather than assuming the platform replays failures. There is one automatic guard: a schedule or trigger that keeps skipping because a required Connection is missing gets auto-paused, and its owner is emailed. Reconnect the account and switch it back on. ## Related Frequency presets, cron expressions, and timezone setup. Every trigger type with latency, dedup, and retry behavior. Producer/consumer design and the rules that keep a Queue healthy. Why the schedule's creator determines what a Run can access. # Best Practices Source: https://docs.duvo.ai/best-practices/index Recommendations and proven patterns for getting the most out of Duvo Agents. This section collects recommendations and proven patterns for building reliable Agents, designing effective workflows, and scaling automation across your team. Start here: The highest-leverage thing you control when building an Agent. Manual Starts, schedules, triggers, and Queues each fit a different shape of work. Producer/consumer design so every Case ends somewhere definite. Set up access that survives teammates, departures, and expired credentials. A cross-referenced index of practical guidance from across the docs. We're actively expanding this section. Check back for more detailed guidance. # Designing Work Around Queues and Cases Source: https://docs.duvo.ai/best-practices/queues-and-cases Structure producer and consumer Agents so every Case ends somewhere definite, waiting periods work with the platform, and nothing silently disappears. When work arrives as a stream of items — orders, tickets, invoices, requests — put it in a [Queue](/user-guide/assignment-features/case-queue) and let your Agents process it as Cases. This page covers the design rules that keep a Queue healthy once real volume flows through it. For what Queues and Cases are and how to set them up, start with the [Queue](/user-guide/assignment-features/case-queue) guide. ## One Case per Run A consumer Agent processes exactly one Case from start to finish, and the platform handles everything around it: picking up the next Case, running several in parallel, and re-dispatching postponed ones. Write the AOP for a single item and let Duvo iterate — a batch loop in the AOP hides per-item failures inside one Run and breaks per-Case tracking. This is the same rule as [Writing Effective AOPs](/best-practices/writing-effective-aops), applied to Queues. ## Split Producers from Consumers A healthy Queue has two distinct roles, and usually two distinct Agents: * The **producer** finds work and adds Cases to the Queue. Its job ends when the Cases are added — it never claims or processes them. * The **consumer** claims one Case, works it, and settles it. Duvo does not deduplicate Cases. If a producer adds the same item twice, the Queue holds two Cases and the consumer will process both. Deduplication is the producer's job: have it check the Queue for an existing Case before adding a new one, especially when it runs on a frequent schedule. ## Close Every Case, Every Time Every Case a consumer claims must end in exactly one of four ways: **completed**, **failed** (with a reason), **postponed** for a later retry, or **handed over** to another Agent. If a Run ends without settling its Case, Duvo marks the Case as Failed automatically — with no reason attached. In practice this is the most common failure mode for Queue-driven Agents: the AOP covered the happy path, an odd Case took an uncovered branch, and the Case shows up Failed with nothing to explain why. The fix is in the AOP: give every branch an explicit ending. ```mermaid theme={"dark"} flowchart TD A[Consumer claims one Case] --> B{How does this branch end?} B -->|Work is done| C[Complete the Case] B -->|Cannot be done at all| D[Fail the Case
with the reason] B -->|Cannot be done yet| E[Postpone the Case
to retry later] B -->|Another Agent should take it| F[Hand the Case over] ``` ## Postpone or Fail: Choose Deliberately Postpone and fail look similar in the moment ("I can't finish this Case now") but mean opposite things: | Situation | Right ending | | ------------------------------------------------------------ | ------------ | | Waiting on a reply, an external process, or a scheduled date | Postpone | | Rate-limited by an external system | Postpone | | Required data is missing or invalid and won't fix itself | Fail | | A credential or Connection the work depends on isn't working | Fail | Postponing a permanent problem is the trap to avoid: the Case comes back, hits the same wall, gets postponed again, and loops forever without anyone noticing. If retrying won't change the outcome, fail the Case with a clear reason so a person can step in. Postpones have a minimum wait — very short postpone times are rounded up to your workspace's minimum. Don't design flows that depend on retrying within a few minutes. ## The Waiting Pattern For any step that means "wait N days, then act" — follow-ups, reminders, escalation timers — use postpone with a marker on the Case: 1. On the first pickup, record a marker in the Case data (for example `reminder_sent: true`), then postpone the Case for the waiting period. 2. On the next pickup, the marker is there, so the AOP skips ahead and does the real work. Use a different marker for each waiting phase if the flow has several. This keeps a multi-day process inside one Agent, instead of spawning a separate Agent per stage. ## Update the Case as You Go Anything you record on a Case — progress notes, intermediate results, markers — survives postpones and handovers. The next Run picks up where the last one left off, and a teammate looking at the Queue can see where each Case stands. Update the Case at meaningful milestones, not just at the end; a Case that fails halfway through with no notes is as opaque as one that never updated at all. ## Handing Over Is Its Own Ending Handover passes the Case to a different Agent after the current Run finishes — use it when a specialist Agent is better placed to continue. It is one of the four endings, not something you combine with the others: a branch that hands the Case over must not also complete, fail, or postpone it, or the receiving Agent never gets the Case. ## Watch the Throughput, Not Just the Cases Cases process in parallel up to the consuming Agent's concurrency limit. When the Agent is at capacity, new Cases simply wait as Pending until a Run finishes — nothing is lost, but a slow AOP quietly turns into a growing backlog. If Pending keeps climbing, make each Case's work shorter, or split the process into stages with [Multi-Agent Process Decomposition](/user-guide/building-assignments/process-decomposition). To see exactly which Cases are holding the slots, open **Active cases** — click the **At capacity** badge, or choose **Show active cases** from the Queue's actions menu. It lists the Cases currently occupying a concurrency slot, so you can inspect or act on them (Cases waiting for input still hold their slot, so resolving them frees capacity). And give each Queue exactly one consuming Agent. If two Agents both have triggers on the same Queue, Duvo won't pick a winner — conflicted Cases don't run at all. The trigger setup warns you about this; take the warning seriously. ## Related What Queues and Cases are, statuses, and how to set them up. The principles behind AOPs that close every branch. Schedules, triggers, Queues, and manual Runs — picking the right one. When one Agent is doing too much, split it into stages. # Giving Recurring Runs a Memory Source: https://docs.duvo.ai/best-practices/recurring-runs-memory Recurring Agents that pick from a pool will repeat themselves unless you design where their memory lives. Externalize state between Runs, exclude at the source, and validate before writing. A scheduled Agent that selects items from a pool each cycle — promo products, outreach targets, audit samples, content topics — has a failure mode unique to recurring work: every Run starts fresh, so nothing stops this cycle from picking exactly what the last cycle picked. The same applies to any recurring workflow whose next Run depends on what previous Runs already did. This page covers the design principles that give recurring Runs a working memory and keep their output trustworthy. For a full worked example that applies all of them, see the [Promo Product Selection playbook](/user-guide/playbooks/merchandising/promo-product-selection). ## Each Run Starts Fresh — Decide Where State Lives Runs do not share context with each other. Whatever the next Run needs to know, the current Run has to record somewhere durable, and the AOP has to say where to look for it. Duvo gives you three places to keep state, each for a different purpose: | Where | What it's for | What it's not | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | [Agent Memory](/user-guide/assignment-features/assignment-memory) | Per-user preferences and thresholds, applied to every Run that user starts | A record of what past Runs did — it personalizes behavior, it doesn't log history | | An external system of record (a tracker sheet, an archive folder, a database) | Workflow state: what was already selected, sent, or processed | Automatic — the AOP must say where it lives and when to read and write it | | [Case](/user-guide/assignment-features/case-queue) data | Progress on one work item as it moves through a Queue, surviving postpones and handovers | State shared across the whole workflow — it's scoped to that Case | For "don't repeat what previous Runs did," the middle row is the one that matters: put the workflow's history in a system of record your team can open, audit, and correct — a Google Sheet, a Drive folder, a database table. If a person can't see the state, they can't fix it when it's wrong. ## Make the Archive the Memory The strongest version of externalized state is when the workflow's own output is its memory. In the [promo selection playbook](/user-guide/playbooks/merchandising/promo-product-selection), each cycle writes its shortlist to an archived sheet, and the next cycle builds its exclusion list by reading the last N archived sheets. There is no separate "already used" list to maintain, because the archive is the list. This closes the loop by construction: * **Self-maintaining** — producing output and updating memory are the same action, so the memory can't silently go stale * **Auditable** — anyone can open the archive and see exactly why an item was excluded * **Correctable** — a human can delete a row to make an item eligible again, without touching the Agent Keep an index (a tracker sheet listing the archived outputs in order) so the Agent knows where the last N outputs are without scanning a whole folder. Deriving state from the archive also survives missed cycles. A scheduled tick that can't run — the previous Run is still active, or a Connection is missing — is skipped, never backfilled. Memory based on what the calendar says should have happened drifts the first time a cycle is skipped; memory derived from archived outputs always reflects what actually ran. ## Exclude at the Source, Not After Apply non-repetition filters inside the source query — a `NOT IN` clause in the `WHERE` — rather than fetching results and filtering them afterward: ```sql theme={"dark"} AND sku NOT IN ('SKU-001', 'SKU-042', 'SKU-107') ``` Filtering at the source means ranking and limits operate on the already-eligible pool, so you always get a full result set, and excluded items never appear in intermediate output the Agent might act on. Post-filtering has the opposite properties: the limit fills up with items you're about to throw away, and one missed filter step leaks an excluded item into the output. An exclusion filter that matches nothing fails silently — the query succeeds and the output looks normal, but nothing was excluded. The two usual causes: an empty list (`NOT IN ()` is invalid SQL — omit the clause instead) and identifier format drift between the archive and the source (`SKU-001` vs `001` — normalize before comparing). Test both cases explicitly before going live. ## Validate Before You Write Recurring workflows drift. The exclusion window grows, the eligible pool shrinks, an upstream table changes — and one cycle, the query quietly returns less than the workflow needs. Add a validation gate between reading and writing: if the result doesn't match expectations (too few rows, missing fields, out-of-range values), stop and request human review instead of writing output. Partial output is worse than no output, because downstream consumers can't tell partial from complete — a pricing Agent fed half a shortlist prices half a promotion with no warning. A hard stop with a clear question ("\[actual] of \[expected] returned — shrink the shortlist, narrow the exclusion window, or widen the scope?") turns silent drift into a decision someone actually makes. ## Keep the Selection Logic in the AOP Ranking expressions, thresholds, and exclusion windows belong in the AOP — not in a spreadsheet formula, a saved query, or the head of whoever ran the process last. In the AOP, the logic is versioned with the Agent, visible to anyone who opens it, and changed by deliberate edit rather than drift. When the reviewer asks "why did it pick these?", the answer is readable in one place. ## Let Reviewers Adjust, Not Redo An approval gate that only offers approve or deny forces the reviewer to reject a whole batch over one bad item — so they stop rejecting, and the gate stops working. Instead, design the approval to accept small corrections in the response. Responses to requests are free text, so the AOP can define simple commands: ``` Support these commands in the reviewer's response: - "Remove: [ID]" — take that item out of the result and confirm what changed. - "Add: [ID]" — look the item up, add it, and confirm. Process all commands before treating the response as a final approval. ``` Have the Agent confirm each command back before treating the response as final, and make sure whatever happens after approval reads the post-command result — not the originally proposed one. And if the post-approval step creates Cases in a [Queue](/user-guide/assignment-features/case-queue), make it idempotent: Queues do not deduplicate Cases, so a retried Run or a twice-processed approval creates duplicates unless the AOP checks for an existing Case first. For choosing the right approval shape and escalation behavior, see [Designing Human-in-the-Loop Workflows](/user-guide/assignment-features/hitl-design). ## Do and Don't | Do | Don't | | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- | | Write workflow state to a system of record the team can open and correct | Assume a Run knows what previous Runs did | | Derive "already done" lists from archived outputs | Maintain a separate exclusion list someone has to remember to update | | Apply exclusions in the source query, before ranking and limits | Fetch everything and filter afterward | | Stop and ask when results don't match expectations | Write partial output and let downstream Runs discover it | | Keep ranking logic and thresholds in the AOP | Encode selection logic in spreadsheets or saved queries outside the Agent | | Accept reviewer corrections inside the approval response | Force reviewers to approve or reject entire batches | | Check for an existing Case before creating one after approval | Assume the platform deduplicates Cases or backfills skipped schedule ticks | ## Related The full worked example: a promo selection Agent with a non-repetition filter The per-user personalization layer — and why it isn't workflow state Cases, statuses, and handing work between Agents Choosing approval shapes and escalation behavior Running an Agent on a recurring cadence # Connections and Logins That Don't Break Source: https://docs.duvo.ai/best-practices/reliable-connections Most "my agent stopped working" reports trace back to access. Set up Connections, Logins, and Secrets so they survive teammates, departures, and expired credentials. An Agent is only as reliable as its access to the systems it works in. Most "the agent suddenly stopped working" reports have nothing to do with the AOP — they trace back to a Connection nobody authorized, a Login saved as personal, or a token that quietly expired. This page covers the setup habits that prevent them. ## A Run Uses the Access of the Person It Runs As This is the single most important rule on this page. Every Run belongs to a person: a manual Run belongs to whoever clicked Start Work, and a scheduled or triggered Run belongs to **whoever created the schedule or trigger**. The Run resolves its Connections, Logins, and Secrets for that person — not for the Agent's builder, and not for the team as a whole. Two consequences follow: * **"It works for me but not for my teammate" is almost always access.** The Agent is the same; what changed is whose Connections and Logins the Run can see. * **Schedules and triggers inherit their creator's access forever.** If the creator never connected a required service, their scheduled Runs are skipped. If the creator leaves the company, their schedules and triggers keep running as them until their access dies. Before enabling a schedule or trigger, check that its creator has every Connection the Agent needs authorized under their own account. And when someone leaves the team, recreate their schedules and triggers under an active owner as part of offboarding. ## Personal Stays Personal [Logins and Secrets](/user-guide/resources/my-logins) come in two visibilities: **Team** (usable by everyone in the workspace) and **Personal** (usable only by the owner). A Run can only use items that are Team-shared or owned by the person the Run runs as. A Personal Login saved by someone else does not exist as far as the Run is concerned. The classic symptom: a teammate runs an Agent with browsing and the saved Login "isn't loading" or the site asks for credentials. Nine times out of ten, the Login exists — as someone else's Personal item. Moving it to Team fixes it. Two details worth knowing: * If a Team and a Personal item both match (same domain for Logins, same key for Secrets), the personal one wins for that person's Runs. This lets individuals override a shared default without affecting anyone else. * Connections to services like Gmail or Slack are personal by nature — each teammate authorizes their own account, and a Run uses the account of the person it runs as. For any Agent that more than one person will run, put its Logins and Secrets in Team from the start. ## When Access Breaks, Runs Degrade Quietly An expired or revoked credential usually does not stop a Run with a clean "please reconnect" error. What actually happens: the affected tool is unavailable to that Run, and the Agent works with whatever remains — which can mean improvising around the missing system instead of stopping. The Run may even look successful while doing the wrong thing. Two habits protect you: * **Tell the Agent to fail fast in the AOP.** A line like "If you cannot access \[system], stop and report the failure — do not work around it" turns a silent degradation into a clear failure you can act on. For Queue consumers, that means failing the Case with the reason. * **When a Run behaves as if a Connection vanished, believe it.** Check the Connections page, reconnect the affected account, and re-run before debugging anything else. For schedules and triggers, the platform adds a safety net: when Runs keep getting skipped because a required Connection is missing, the schedule or trigger is automatically paused and its owner gets an email. It shows up with an "Auto-paused" badge — reconnect the missing account, then switch it back on to resume. ## Test Custom Connections Before You Trust Them Custom MCP and API-key Connections point at a server you provide, and saving one does not verify it works — a wrong URL or a bad key is stored without complaint. Use the connection test when you add it, and confirm the tools it exposes look right. A dead server surfaces later as tools that silently never appear in Runs, which is much harder to trace back. See [Building Custom Connections](/user-guide/connections/building-custom-connections). ## Secrets: Attach Once, Use Everywhere Secrets are the right way to give an Agent an API key or token — never paste credentials into the AOP or a prompt. A Secret attached to an Agent is available in every Run as environment variables; the Agent sees the variable names, and the values stay inside the Run's sandbox. * Name keys the way code expects them, like `SERVICE_API_KEY` — the AOP can then reference the variable by name. * Rotate by editing the Secret's value; the next Run picks up the new value automatically. * The Team-vs-Personal rule above applies to Secrets too. ## Related Managing website Logins and env-var Secrets, Team vs Personal. Hosted, browser, custom MCP, computer use — which fits your system. Schedules and triggers run as their creator — pick owners deliberately. Include a revoked-Login drill in your pre-production test plan. # Tips and Patterns Source: https://docs.duvo.ai/best-practices/tips-and-patterns A cross-referenced index of the practical guidance across the Duvo docs, grouped by what you're trying to do. A running collection of the highest-value tips from across the docs, grouped by what you're trying to do. Each one links to the page with the full detail. ## Building good Agents * **Write a clear, testable AOP.** It's the highest-leverage thing you control. See [Writing Effective AOPs](/best-practices/writing-effective-aops). * **Match the model to the job.** Harder reasoning and longer procedures benefit from a stronger model; simple, high-volume tasks don't need one. See [Model Selection](/user-guide/advanced/model-selection). * **Decide one Agent or several.** When a single AOP is juggling unrelated jobs, split it. See [Multi-Agent Process Decomposition](/user-guide/building-assignments/process-decomposition). * **Pick how Runs start deliberately.** Schedules, triggers, Queues, and manual Starts each fit a different shape of work. See [Choosing How Your Agent Starts](/best-practices/choosing-how-runs-start). * **Design Queues so Cases always close.** Every claimed Case should end completed, failed, postponed, or handed over. See [Designing Work Around Queues and Cases](/best-practices/queues-and-cases). * **Give the Agent the right tools.** Pick the Connection pattern that fits the system you're integrating. See [Choosing the Right Connection Pattern](/user-guide/connections/integration-patterns). ## Running reliably * **Test in a revision, then promote.** Validate changes safely before they reach production. See [Test Safely Before Going Live](/user-guide/getting-started/test-safely) and [Promote to Production](/user-guide/getting-started/promote-to-production). * **Watch the first week.** A daily review cadence catches problems while they're cheap to fix. See [Monitor the First Week](/user-guide/getting-started/monitor-first-week). * **Plan for retries and failures.** Decide what should happen when a step fails or input is malformed. See [Retries, Failures, and Skipped Steps](/user-guide/reliability/retries-and-failures). * **Use Evaluations to find weak spots.** Duvo scores Runs against criteria derived from the AOP. See the [Runs List](/user-guide/running-assignments/jobs-list). ## Staying safe * **Gate high-risk actions.** Put caps, thresholds, and hard limits in the AOP for anything financial, irreversible, or outbound. See [Guardrails for High-Risk Automations](/user-guide/security/high-risk-guardrails). * **Add human approval where it matters.** Define exactly when the Agent should pause for a person. See [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop) and [Designing Human-in-the-Loop Workflows](/user-guide/assignment-features/hitl-design). * **Share Logins, don't keep them personal.** A Run can use a Login that's shared with the team (or owned by the person the Run runs as); a personal Login saved by someone else won't be available to it. If a sign-in "isn't loading," check that the Login is shared. See [Connections and Logins That Don't Break](/best-practices/reliable-connections). ## Scaling * **Let Agents remember and learn.** Persisted context and feedback make recurring work better over time. See [Agent Memory](/user-guide/assignment-features/assignment-memory) and the [Learning Feature](/user-guide/assignment-features/learning-feature). We're actively expanding this page. If a tip keeps coming up in support or in your own building, it belongs here. # Writing Effective AOPs Source: https://docs.duvo.ai/best-practices/writing-effective-aops The AOP is where most of an Agent's quality lives. Write clear, testable instructions that produce reliable, predictable Runs. Most of an Agent's quality lives in its AOP (Agent Operating Procedure). When an Agent underperforms, the fix is almost never a different model — it's a clearer AOP. Duvo also derives your Agent's evaluation criteria from the AOP, so clarity pays off twice: better Runs, and scores you can actually act on. ## Why the AOP Matters The Agent follows it on every Run. If a step can be read two ways, sooner or later it will be. Duvo scores completed and failed Runs against criteria derived from the AOP, and surfaces the results in the [Runs List](/user-guide/running-assignments/jobs-list). Vague instructions produce vague scores you can't act on. Volume caps, value thresholds, approval rules, and hard "never do this" limits all live in the AOP. ## Write for a Capable New Team Member Your Agent reads the AOP the way a person would; it doesn't execute it like code. Write it the way you'd brief a capable colleague on their first day: they know the tools, they don't know your business. Anything a new hire would have to ask about (which spreadsheet, whose approval, what happens to rejects) needs to be written down. Pseudo-code doesn't. Watch out for words like "promptly", "as appropriate", and "if necessary". Each one is a decision you're quietly handing to the Agent, and it won't make that call the same way twice. ## Use the Canonical Shape: GOAL, STEPS, NOTES Duvo's own AOP tooling generates and rewrites AOPs in one consistent shape. Writing yours the same way keeps Agent Builder edits clean and makes every Run easier to debug. * **`# GOAL`** — one sentence describing what the Agent does on a single Case and the expected outcome. * **`# STEPS`** — a numbered list of imperative actions, one action per step. Inline everything that belongs to a step into that step: decision criteria, data formats, error handling, and escalation. * **`# NOTES`** *(optional)* — only genuinely cross-cutting concerns, such as timezone or naming conventions. Omit it otherwise. Skip the separate ERROR HANDLING or ESCALATION sections at the bottom. A rule that sits far from the step it belongs to tends to get missed exactly when it matters. Put it in the step. ## The Principles 1. **Lead with the goal and the definition of done.** State the outcome and how the Agent knows it succeeded, before the steps. An Agent that knows what "done" looks like makes better decisions along the way. 2. **Describe one Case, not the batch.** Write the AOP around processing a single item from start to finish. The platform handles iteration: [Queues](/user-guide/assignment-features/case-queue) feed Cases to your Agent one at a time, and [schedules](/user-guide/assignment-features/scheduling-assignments) and [triggers](/user-guide/assignment-features/event-driven-triggers) decide when Runs start. Batch loops ("go through all pending reports") hide per-item failures inside a single Run and break per-Case tracking and retries. 3. **Be specific and unambiguous.** Name the exact Connection, sheet, field, label, and recipient. Replace "the relevant data" with the actual source. Most failures trace back to one ambiguous sentence. 4. **Make decisions concrete.** Every decision point needs an explicit condition and an explicit action for each outcome: "If the total exceeds \$5,000, send it to the finance lead. Otherwise, approve it automatically." If you can't put a number on it, it's a decision for a human — make it an approval step. 5. **Put limits and guardrails in the AOP.** State caps and thresholds directly: "never send more than 20 emails in one Run", or "if an invoice exceeds €10,000, stop and request approval." Don't rely on the model to be cautious on its own. See [Guardrails for High-Risk Automations](/user-guide/security/high-risk-guardrails). 6. **Say when to ask a human — the Agent won't decide to on its own.** The Agent never invents its own approval gates. If the AOP doesn't tell it to pause, it won't, even before something hard to undo. The good news: plain language works. "Get the requester's go-ahead before sending" is enough to create a [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop) checkpoint; there's no special syntax to learn. 7. **Close every branch.** Every path through the AOP should end somewhere definite: the output is delivered, the item is escalated to a person, or the work is postponed for a retry. Write down the unhappy paths too — a source system that doesn't respond, a required field that's missing, a lookup with no match. Don't leave those for the Agent to figure out. See [Retries, Failures, and Skipped Steps](/user-guide/reliability/retries-and-failures). 8. **Give context, not just commands.** A short "why" and an example of good versus bad output sharpen the Agent's judgment on the cases you didn't anticipate. If a step sends, deletes, or pays for anything and you want a person to see it first, say so in that step. For help deciding which actions deserve a gate, see [Designing Human-in-the-Loop Workflows](/user-guide/assignment-features/hitl-design). Closed branches are the difference between an AOP you can trust and one you have to babysit: ```mermaid theme={"dark"} flowchart TD A[Step runs on one Case] --> B{Did it succeed?} B -->|Yes| C[Deliver the output
and mark the Case done] B -->|Data missing or ambiguous| D[Escalate to a person
with the reason] B -->|System unavailable| E[Postpone the Case
and retry later] ``` ## Do and Don't | Do | Don't | | ------------------------------------------------- | ---------------------------------------------- | | State the goal and the definition of done | Assume the Agent will infer what success means | | Write the AOP around one Case, end to end | Write batch loops over "all pending items" | | Name exact sources, fields, and recipients | Say "the relevant data" or "the right people" | | Put caps, thresholds, and approvals in the AOP | Rely on the model to be cautious by default | | End every branch in done, escalated, or postponed | Leave edge cases and failures to guesswork | | Iterate in a draft revision, validated by evals | Edit a live Agent's AOP blind | ## A Quick Example **Vague:** "Read incoming invoices and enter them into the system." **Effective:** ``` # GOAL Process one incoming invoice: validate it, get approval where needed, and enter it into NetSuite. # STEPS 1. Extract the supplier, invoice number, date, and total from the invoice PDF. - If any of those four fields is missing or unreadable: add the invoice to the "Needs review" Google Sheet with the reason, and stop. Do not guess. 2. If the total is over €10,000: request approval from the finance lead before entering it. 3. Create the record in NetSuite and reply to the sender via Gmail confirming receipt. ``` Same task, but now the Agent knows what to read, what counts as done, what to do when the data is bad, and when to ask before acting. ## The AOP Is Not the Only Context The AOP is the shared process everyone relies on, but it's not the only thing your Agent sees on a Run. Two other layers ride alongside it: * **[Agent Memory](/user-guide/assignment-features/assignment-memory)** holds personal preferences, like your own approval threshold or how you want output formatted. It applies only to your Runs and never changes the shared AOP. * **[Learnings](/user-guide/assignment-features/learning-feature)** capture what worked in past Runs and carry it forward automatically. If [refining your Agent](/user-guide/building-assignments/refining-your-assignment) turns up a rule the whole team needs, put it in the AOP, where it's versioned and everyone can see it — not in a personal note where only your Runs benefit. A great AOP fits on a screen or two. If yours keeps growing past that, it's usually a sign the process wants to be more than one Agent — see [Multi-Agent Process Decomposition](/user-guide/building-assignments/process-decomposition). ## Test and Improve, Don't Edit Live Treat the AOP like code. Change it in a draft revision, validate it on real cases, and promote it only once it holds. **Never edit a production Agent's AOP blind** — it is the fastest way to break an Agent that was working. Once it's live, let the Evaluations guide refinement instead of intuition. See [Test Safely Before Going Live](/user-guide/getting-started/test-safely), [Promote to Production](/user-guide/getting-started/promote-to-production), and [Monitor the First Week](/user-guide/getting-started/monitor-first-week). ## Related What an AOP is, how it differs from the Agent Builder, and how to create one. Match the model to the difficulty of the AOP. When one AOP is doing too much, split it. The rest of the practical guidance across the docs. # Changelog Source: https://docs.duvo.ai/changelog Weekly highlights of Duvo's user-facing updates. Here's the latest — everything new, improved, and shipping in Duvo, week by week. ## Skill revisions over the API and CLI, Claude Haiku 4.5, and bulk file cleanup Skills can now be updated non-destructively through the public API and the CLI, so you can ship a new revision without overwriting the active one. Claude Haiku 4.5 joins the model picker for fast, lightweight work, bulk file cleanup lands in Agent and Queue memory, and Clarity interviews can now be renamed. ### Highlights * **Skill revisions over the API and CLI** — manage Skill revisions through the public API and the CLI so a Skill can be updated non-destructively instead of overwriting the active revision. [Learn more](/cli/managing-files-and-skills) * **Claude Haiku 4.5** — Haiku 4.5 is now a selectable Agent model for fast, lightweight work. [Learn more](/user-guide/advanced/model-selection) * **Bulk file deletion** — select multiple files in Agent and Queue memory and delete them in one confirmation. [Learn more](/user-guide/assignment-features/assignment-memory) * **Bulk respond for Requests** — answer up to 100 Requests in a single call through the public API. * **Slovak in Clarity** — Slovak joins the Clarity interview languages. [Learn more](/user-guide/assignment-features/clarity) ## Claude Opus 5 is now the Opus-tier model Every Agent on the Opus tier automatically moved to Anthropic's newest Opus model, including Agents pinned to an older Opus version, with no action needed. New members also land on an organization welcome screen when they join, and Mac users can now paste with Cmd+V inside the Computer Use viewer. [Learn more](/user-guide/advanced/model-selection) ## NetSuite goes live, bring-your-own Shopify app, and a pinned title column in Queues NetSuite now connects through a real OAuth flow so Agents can read and manage enterprise data end-to-end, and Shopify can be connected with your own custom app while Duvo's public app is still under review. Queues also keep the case title visible while you scroll across wide tables. ### Highlights * **NetSuite connection** — connect Agents to NetSuite through the AI Connector MCP with a real OAuth flow, letting Agents read and manage financials, orders, inventory, and CRM data directly. [Learn more](/user-guide/connections/available-connections/netsuite) * **Bring-your-own Shopify app** — connect Shopify with a custom app you create in the Shopify Dev Dashboard, so teams can start using Shopify with Agents while Duvo's public app is still in review. [Learn more](/user-guide/connections/available-connections/shopify) * **Pinned title column in Queues** — the case title stays visible while you scroll horizontally through wide queue tables, so you never lose track of the row you're on. [Learn more](/user-guide/assignment-features/case-queue) ## Case priority in Queues, subagent delegation in Agent chat, and a self-updating CLI Queues now let you flag work as high or medium priority so the most important cases get picked up first, and Agent chats surface a live card whenever an Agent delegates work to a subagent. Desktop Logins can also be scoped to a single app, and the CLI keeps itself up to date. ### Highlights * **Case priority in Queues** — mark cases as High or Medium priority and consumer Agents will pick them up ahead of default-priority work, with badges surfacing priority throughout the Cases list. [Learn more](/user-guide/assignment-features/case-queue) * **Subagent delegation cards in Agent chat** — when an Agent delegates a step to a subagent, chat shows a live card with the subagent's progress and final result, so you can follow exactly what was handed off and why. * **App-specific desktop Logins** — scope a saved Login to a single desktop app instead of the whole machine, so Agents pick the right credentials automatically when signing in to different apps on the same Remote Desktop. [Learn more](/user-guide/resources/my-logins) * **Self-updating CLI** — the Duvo CLI now checks for and installs its own updates, so your terminal and CI/CD environments stay on the latest release without manual reinstalls. [Learn more](/cli) ## Duvo Pulse goes GA, Zendesk arrives, and Agent pinning becomes personal Pulse graduates to a standard feature for every team and Zendesk joins as a native Connection. Agent chats now also scroll all the way back through history. ### Highlights * **Duvo Pulse GA** — real-time Run monitoring and analytics dashboards are now standard for every team, and dashboards can be shared across your whole organization with read-only access. [Learn more](/user-guide/analytics/pulse) * **Zendesk connection** — connect Agents to Zendesk to manage tickets, organizations, and customer data with one-click OAuth. [Learn more](/user-guide/connections/available-connections/zendesk) * **Personal Agent pinning** — pinning is now per-user instead of team-wide, so your go-to Agents float to the top of your list without affecting teammates. * **Process tags in Clarity** — organize Clarity processes with custom tags and filter by tag in the process library, also available via the Public API and CLI. [Learn more](/user-guide/assignment-features/clarity) * **Requests** — human-in-the-loop requests from Agents now live in a dedicated Requests section, replacing the Activity Inbox. * **Memory supports any file type** — save JSON, CSV, code, or any other format to Agent memory, not just Markdown. [Learn more](/user-guide/assignment-features/assignment-memory) ## Claude Sonnet 5, MFA logins over Remote Desktop, and user-scoped API keys Agents can now run on Claude Sonnet 5 and complete MFA-gated logins in desktop apps on their own. Ask Duvo suggestions now adapt to the page you're on, and a new skill drafts role profiles grounded in your documented Clarity processes. ### Highlights * **Claude Sonnet 5** — configure Agents to use Anthropic's newest model for improved reasoning and speed on complex tasks. [Learn more](/user-guide/advanced/model-selection) * **MFA support for Remote Desktop** — when an Agent logs in to a desktop app behind two-factor authentication, it can use saved credentials and generate one-time codes to complete the login. [Learn more](/user-guide/connections/computer-use-overview) * **User-scoped API keys** — create a single API key that works across all teams you can access, instead of managing separate team-scoped keys. [Learn more](/user-guide/running-assignments/api-overview) * **Granular Agent duplication** — when duplicating an Agent, choose what to bring along: Connections, Queue, Skills and Files, Logins, Plugins, AOP, and optionally Memory. [Learn more](/user-guide/building-assignments/duplicating-assignments) * **Share Pulse dashboards with individual members** — grant each person view-only or edit access, independent of team-wide publish settings. ## Bulk case actions across every page The Cases "select all" in a Queue now spans the full filtered result set, so a single reprocess or status change can cover hundreds of cases at once. [Learn more](/user-guide/assignment-features/case-queue) ## SAP ECC and team interviews in Clarity SAP ECC joins as a native Connection, guided team and organization interviews land in Clarity, and Slack accounts can now be shared across a team. ### Highlights * **SAP ECC connection** — connect Agents to SAP ECC to read customers, vendors, application logs, change documents, jobs, and ERP tables straight from your system. [Learn more](/user-guide/connections/available-connections/sap-ecc) * **Team and organization interviews** — capture how your teams actually work through guided voice interviews in Clarity, with a dedicated Interviews entry in the team and organization sidebars. ## Clearer names, Queue out of beta, and Windows sandboxes GA A milestone week: the core concepts were renamed to match how teams actually talk — Assignments are now **Agents**, Jobs are **Runs**, Case Queues are **Queues**, and SOPs are **AOPs**. Alongside: a Cmd+K command palette, one-click approvals, and evaluation scores readable via the Public API. ### Highlights * **Clearer names across Duvo** — Agents, Runs, Queues, and AOPs everywhere in the app and docs. Same features, clearer names. * **Queue is out of beta** — the shared workspace where Agents and people work through cases together is now a standard part of Duvo. [Learn more](/user-guide/assignment-features/case-queue) * **Dark mode** — switch the entire app to a dark theme from your profile menu. * **Windows sandboxes (GA)** — Windows-based computer-use sandboxes are out of preview, so Agents can drive Windows desktop apps in production runs. [Learn more](/user-guide/connections/computer-use-overview) * **Apify and Confluence connections** — run Apify scrapers and browser automations, and let Agents read and update Confluence pages and spaces. [Learn more](/user-guide/connections/available-connections/confluence) ## Developer Platform and guardrails for Agent browsing Building on Duvo is now a first-class workflow, and teams get control over where Agents can browse. ### Highlights * **v2 Public API** — consistent versioning across all public endpoints, with event triggers now manageable programmatically. [Learn more](/user-guide/running-assignments/api-overview) * **MCP server** — point any MCP-compatible client (including Claude Code) at Duvo and operate the platform with natural language. [Learn more](/mcp/overview) * **CLI 1.0** — the Duvo CLI is stable, with standalone binaries and a one-line installer. [Learn more](/cli) * **Browsing guardrails** — set soft rules the Agent must respect while navigating and hard-blocked domains it can never visit, per team. [Learn more](/user-guide/security/high-risk-guardrails) ## Record browser skills by demonstration, plus Signavio and BambooHR Teach Agents a browsing routine by showing, not telling. Two Connections join the catalog, approval requests get richer formatting, and Queues warn when they hit capacity. ### Highlights * **Record browser skills** — record yourself walking through a web workflow from the Skills and Files page, and the recording becomes a reusable skill any Agent can follow. [Learn more](/user-guide/skills/recording-browsing-skills) * **SAP Signavio** — pull process models and documentation from Signavio into Duvo workflows. [Learn more](/user-guide/connections/available-connections/signavio) * **BambooHR** — connect Agents to BambooHR to read and update employee records, time off, and HR data. [Learn more](/user-guide/connections/available-connections/bamboohr) * **Formatted approval requests** — human-in-the-loop requests now render full markdown, so Agents can present tables and structured context when asking for a decision. [Learn more](/user-guide/assignment-features/human-in-the-loop) ## The upgraded Clarity experience goes standard, rich-text AOP editing, and the audit log The redesigned Clarity process workspace is now the default for every team: versioned end to end, editable on the canvas, and enriched with AI-generated analysis. ### Highlights * **Upgraded Clarity for everyone** — version history with snapshots you can compare and promote, AI analysis tabs (summaries, SWOT, automation readiness, projected impact), and targeted follow-up capture requests. [Learn more](/user-guide/assignment-features/clarity) * **Rich-text AOP editor** — write your Agent's AOP with headings, lists, and formatting instead of raw text. [Learn more](/user-guide/building-assignments/assignment-sop) * **Audit log** — a reviewable trail of security-relevant activity across your team: sign-ins, setting changes, and sensitive actions. [Learn more](/user-guide/security/audit-log) ## Outlook email triggers and a redesigned Connections page Agents can now start work from incoming Outlook email, the same way Gmail triggers already work, and the Connections page got a cleaner redesign. ### Highlights * **Outlook email triggers** — pick a folder, and matching messages kick off a Run automatically. [Learn more](/user-guide/assignment-features/event-driven-triggers) * **Connections redesign** — a cleaner Connections page and detail view make it easier to see what's connected, what's shared, and what needs attention. [Learn more](/user-guide/connections/connections-overview) * **Teams group-chat triggers** — Agents can now be triggered from Microsoft Teams group chats, not just channels. [Learn more](/user-guide/connections/available-connections/microsoft-teams) ## Multiple accounts per service and deeper Microsoft 365 tools Connect more than one account for the same service — two Gmail inboxes, several Slack workspaces — and choose per Agent which one to use. Also this week: smoother Clarity canvas editing, and the CLI and MCP server now sign in with OAuth instead of API keys. ### Highlights * **Multiple accounts per service** — connect several accounts of one service and pick per Agent which to use; HubSpot also moved to native one-click OAuth. [Learn more](/user-guide/connections/connections-overview) * **Microsoft 365 parity** — Word, SharePoint, Excel, Outlook, Calendar, and OneDrive tools reached feature parity with their Google counterparts. [Learn more](/user-guide/connections/available-connections/microsoft-word) * **Pick a real case for test runs** — choose an actual case from the Queue when test-running an Agent, instead of relying on synthetic input. [Learn more](/user-guide/getting-started/test-safely) * **Logins and Secrets in the Agent Builder** — attach stored Logins and Secrets to an Agent directly while building it. [Learn more](/user-guide/resources/my-logins) ## Run evaluations for every team, phone interviews in Clarity, and a richer Queue Run quality evaluations and the team-wide Runs list are now available to all teams. Queues gained a case activity timeline and direct delegation, and Clarity diagrams now export to BPMN 2.0 XML. ### Highlights * **Run evaluations and the Runs list** — every Run gets automatic evaluation results, and the Runs list shows all activity across your team in one place. [Learn more](/user-guide/running-assignments/jobs-list) * **Phone interviews in Clarity** — capture a process over a regular phone call: no screen, no app, just a conversation. [Learn more](/user-guide/assignment-features/clarity) * **Case activity timeline** — status changes, Runs, handovers, and human responses in one chronological stream per case. [Learn more](/user-guide/assignment-features/case-queue) * **Slack channel triggers** — trigger Agents from messages in a Slack channel, with keyword match rules. [Learn more](/user-guide/assignment-features/slack-channel-triggers) * **Microsoft Calendar** — Agents can read, create, and manage Outlook Calendar events. [Learn more](/user-guide/connections/available-connections/microsoft-calendar) ## Logins and Secrets, NetSuite, and smarter Runs A secure credential store comes to Duvo, NetSuite joins as a Connection, and follow-up Runs pick up where the previous one left off. Schedules and Triggers also got redesigned setup flows, and Queues became manageable via the Public API. ### Highlights * **Logins and Secrets** — save browser logins and secret values once, and reuse them across Agents without pasting credentials into AOPs. [Learn more](/user-guide/resources/my-logins) * **NetSuite connection** — read and update ERP records: customers, transactions, items, and more. [Learn more](/user-guide/connections/available-connections/netsuite) * **Runs resume with context** — when an Agent continues earlier work, the new Run receives the full context of what happened before. * **Evaluations tab on every Agent** — pass and issue counts across recent Runs, so you can assess reliability without opening individual Runs. ## Live Windows desktop view, Claude Opus 4.7, and Clarity versioning Watch Agents work on a live interactive Windows desktop right inside Duvo. Clarity processes became versioned, and Queues gained folders and labels for keeping large teams organized. ### Highlights * **Live Windows Remote Desktop view** — Agents on the Windows Remote Desktop connection stream a live interactive desktop view as they work. [Learn more](/user-guide/connections/available-connections/windows-remote-desktop) * **Claude Opus 4.7** — configure Agents to use Anthropic's flagship model for their most demanding Runs. [Learn more](/user-guide/advanced/model-selection) * **Clarity process versioning** — save named snapshots, compare versions, and restore earlier drafts as documentation evolves. * **Duplicate Agents** — copy any existing Agent as a starting point, carrying over its AOP, Connections, and setup. [Learn more](/user-guide/building-assignments/duplicating-assignments) * **Editable Clarity diagrams** — process flow diagrams support direct in-canvas editing: move nodes, connect steps, and save without leaving the view. ## Four new Connections and a team-wide Runs list Linear, Notion, Granola, and GitHub join the catalog, every Run across the team shows in one list, and Agents can ask for approvals inside Microsoft Teams. ### Highlights * **Four new Connections** — Linear, Notion, Granola, and GitHub: issues, pages, meeting notes, and repositories now within Agents' reach. [Learn more](/user-guide/connections/available-connections/index) * **Team-wide Runs list** — a top-level view of every Run across the entire team, filterable by Agent. * **Human-in-the-Loop in Microsoft Teams** — Agents can request approval and receive the response directly inside a Teams conversation. [Learn more](/user-guide/assignment-features/human-in-the-loop) ## Coupa and Pipedrive connections, plus bulk case status changes Two more Connections for procurement and sales teams, and Queues get bulk actions. ### Highlights * **Coupa** — read and write procurement data including purchase orders, suppliers, and requisitions. [Learn more](/user-guide/connections/available-connections/coupa) * **Pipedrive** — manage deals, contacts, activities, and pipelines in Pipedrive CRM. [Learn more](/user-guide/connections/available-connections/pipedrive) * **Bulk case completion and failure** — mark multiple cases as completed or failed in a single action from the Queue view. ## Clarity process library filtering and Queue description fields The Clarity process library now supports filtering and sorting — narrow by attributes or sort by name and last-updated date to navigate large collections of processes. Queues also gain a description field, so Queue owners can document purpose and context directly in the Queue setup. ## Four enterprise Connections and a smoother start Workday, Business Central, Asana, and Dynamics 365 F\&O join the catalog. New users get a guided welcome and Connections setup during sign-up, and Clarity diagrams moved to a faster rendering engine. ### Highlights * **Four enterprise Connections** — Workday, Microsoft Dynamics 365 Business Central, Asana, and Dynamics 365 Finance & Operations for HR, finance, and operations automation. [Learn more](/user-guide/connections/available-connections/workday) * **Agent list view** — switch between grid and list layouts on the Agents page, with key metadata in compact rows. * **Clarity interview languages** — voice interviews now include a language picker for multilingual process capture. * **Agent Builder follow-up questions** — when the Builder needs more information, respond inline and it continues from your answer. ## Salesforce, Tableau, and forecasting Connections A Connections-heavy week for sales and analytics teams, with Agent creation also arriving in the Public API. ### Highlights * **Salesforce** — read and write records across standard and custom objects: leads, contacts, opportunities, accounts, and more. [Learn more](/user-guide/connections/available-connections/salesforce) * **Tableau** — query workbooks, views, and data sources to pull analytics into automated workflows. [Learn more](/user-guide/connections/available-connections/tableau) * **Nixtla TimeGPT** — generate time-series forecasts from historical data for demand planning and inventory workflows. [Learn more](/user-guide/connections/available-connections/forecasting) * **EU Food Commodity Prices** — pull live EU food commodity price data for cost-monitoring and should-cost workflows. [Learn more](/user-guide/connections/available-connections/eu-food-commodity-prices) # Advanced CLI Commands Source: https://docs.duvo.ai/cli/advanced Lower-level Duvo CLI commands for sandboxes, revision integrations, raw API access, and deprecation notices. These commands cover lower-level operations and edge cases. Most users won't need them day-to-day, but they're invaluable for scripting, integrations, and debugging. ## Sandboxes (`duvo sandboxes`) Sandboxes are isolated file environments where you can stage files before starting a Run. Create a sandbox, upload files into it, then pass the sandbox ID when starting a Run with `duvo runs start --sandbox `. ```bash theme={"dark"} duvo sandboxes create # create a new sandbox duvo sandboxes files # list files in a sandbox duvo sandboxes upload # upload a local file (max 10 MB) duvo sandboxes prepare-upload-url \ --path /workspace/data.csv # get a presigned URL for files over 10 MB ``` `--path` is the destination path inside the sandbox. After getting the URL, upload the file directly via HTTP. ## Revision integrations (`duvo revision-integrations`) Revision integrations control which integrations (Connections) are attached to a specific Revision of an Agent, and let you pin particular Connection accounts to individual integration slots. ```bash theme={"dark"} duvo revision-integrations list \ --agent --revision # list integrations on a Revision duvo revision-integrations attach \ --agent --revision \ --integration # attach an integration (repeat --integration for multiple) duvo revision-integrations remove \ --agent --revision [-y] # remove an integration from a Revision (prompts unless -y) ``` Use `duvo integrations list` to find integration IDs and `duvo connections list` to find Connection IDs. ### Pinned Connections Pin a specific Connection account to an integration slot so the Agent always uses that account, regardless of who runs it. ```bash theme={"dark"} duvo revision-integrations connections list \ --agent --revision \ --integration # list pinned Connections for a slot duvo revision-integrations connections pin \ --agent --revision \ --integration # pin a Connection to a slot duvo revision-integrations connections unpin \ --agent --revision \ --integration [-y] # unpin a Connection from a slot ``` ## Raw API access (`duvo api`) Call any Duvo API endpoint directly. Use this when you need an endpoint that doesn't have a dedicated `duvo` command yet, or when you want to inspect the raw API response. ```bash theme={"dark"} duvo api GET /health duvo api POST /v2/teams/{teamId}/runs --data '{"agent_id":"...","input":"..."}' duvo api GET /v2/teams/{teamId}/agents --query 'limit=10' ``` The CLI authenticates the request using your active profile, so you don't have to handle headers manually. ## Deprecation notices When the CLI detects that an API endpoint is deprecated, it prints a warning to `stderr` before the command output: ``` duvo: ⚠ GET /v1/old-endpoint is deprecated (sunset: 2026-08-01) See: https://docs.duvo.ai/api-reference/migration-guide ``` Notices include the sunset date (when the endpoint will stop working) and a link to the replacement or migration guide when available. Each `(method, path)` pair is only warned once per CLI invocation — repeated calls to the same endpoint won't repeat the notice. If you see a deprecation notice, update your scripts to use the replacement endpoint shown in the linked documentation before the sunset date. ## Related Full schema for every endpoint Pair with `duvo revision-integrations` to control which Connections an Agent uses # Cases and Queues Source: https://docs.duvo.ai/cli/cases-and-queues Inspect Case history, bulk-reprocess Cases on an Agent, and manage labels with the Duvo CLI. A Case is a single piece of work delivered into a Queue for an Agent to pick up. The CLI lets you inspect Case history, re-process Cases in bulk, manage labels, and view the Agents bound to a Queue. For an overview of the Queue system, see [Queue](/user-guide/assignment-features/case-queue). ## Cases (`duvo cases`) ### Inspect a Case's history ```bash theme={"dark"} duvo cases runs # list all Runs that have worked on a Case ``` ### Edit a Case Update a Case's title and/or its free-form data. Provide at least one field. Titles can be up to 500 characters. ```bash theme={"dark"} duvo cases update --title "Refund request #1234" # rename a Case duvo cases update --data "Customer wants a full refund." # replace the Case data duvo cases update --title "New title" --data "New data" # both at once ``` Editing a Case works whether it is pending, in progress, or already settled. Status, priority, and labels have their own commands. ### Bulk-reprocess Cases Re-process 1–100 Cases on a specific Agent in one call. Any active Runs for these Cases are interrupted. ```bash With confirmation theme={"dark"} duvo cases bulk-reprocess --queue \ --agent \ --ids ,, ``` ```bash Skip confirmation theme={"dark"} duvo cases bulk-reprocess --queue \ --agent \ --ids , --yes # skip the confirmation prompt ``` ### Set Case priority Raise or clear the priority of 1–100 Cases so higher-priority work is picked up first among eligible pending Cases. Priority levels are `none` (the default), `medium`, and `high`. Due postponed Cases are still picked up before priority ordering applies. ```bash theme={"dark"} duvo cases bulk-update-priority --queue \ --ids , --priority high # raise priority duvo cases bulk-update-priority --queue \ --ids --priority none --yes # clear priority, skip confirmation ``` You can also set a priority when creating a Case, and filter the list by priority: ```bash theme={"dark"} duvo cases create --queue --title "Urgent refund" --priority high duvo cases list --queue --priority high,medium # comma-separated levels ``` Use creation-time bounds to inspect Cases added during a fixed window: ```bash theme={"dark"} duvo cases list --queue \ --created-at-from 2026-08-01T00:00:00Z \ --created-at-to 2026-08-02T00:00:00Z ``` Use update-time bounds to inspect Cases changed during a fixed window: ```bash theme={"dark"} duvo cases list --queue \ --updated-at-from 2026-08-01T00:00:00Z \ --updated-at-to 2026-08-02T00:00:00Z ``` For both pairs, the lower bound is inclusive and the upper bound is exclusive. Adjacent windows do not count the same Case twice. Add `--count-only` when you need the matching total without Case rows. All Case filters still apply. ```bash theme={"dark"} duvo cases list --queue --status pending --count-only # Total Cases: 42 ``` Setting priority never interrupts a Run or changes a Case's status — it only affects the order pending Cases are picked up in. ### Manage Case labels Attach or remove labels on a Case for filtering and organization. ```bash theme={"dark"} duvo cases labels list --queue # list labels on a Case duvo cases labels assign --queue \ --label "key=value" [--label "key=value" ...] # assign one or more labels duvo cases labels unlink --queue \ --label-id [--label-id ...] # remove labels from a Case ``` `--label` accepts either `key=value` (for keyed labels like `priority=urgent`) or just `value` on its own (for tag-style labels like `urgent`). ## Queues (`duvo queues`) ```bash theme={"dark"} duvo queues agents # list producer and consumer Agents bound to a Queue ``` ## Queue labels (`duvo queue-labels`) Queue labels are reusable label definitions on a Queue. Once defined, a label can be attached to any Case in that Queue. ```bash theme={"dark"} duvo queue-labels list --queue # list all labels for a Queue duvo queue-labels create --queue \ --value "Urgent" [--key "priority"] \ [--color "#FF0000"] # create a new Queue label duvo queue-labels delete --queue [-y] # delete a Queue label ``` ## Scripting examples ### Relabel a Case if it had runs created today ```bash theme={"dark"} TODAY=$(date -u +%Y-%m-%d) duvo cases runs --json \ | jq -r --arg today "$TODAY" \ '.runs[] | select(.created_at | startswith($today)) | .case_id' \ | while read CASE_ID; do duvo cases labels assign "$CASE_ID" \ --queue \ --label "review=$TODAY" done ``` # Clarity CLI Source: https://docs.duvo.ai/cli/clarity Use the Duvo CLI to inspect, update, and manage Clarity processes from your terminal. Use `duvo clarity` to inspect and update Clarity processes from a terminal. The CLI can find processes, inspect generated documentation, compare versions, review evidence, import Miro exports, create interview invite links, and call public Clarity write routes. For an overview of Clarity itself, see [Clarity](/user-guide/assignment-features/clarity). ## Quick start ```bash theme={"dark"} duvo clarity search "invoice" --limit 5 duvo clarity overview duvo clarity versions duvo clarity compare duvo clarity gaps duvo clarity evidence duvo clarity import-artifact miro-export.svg duvo clarity create-invite-link duvo clarity export > clarity-brief.md ``` Most commands print a compact human-readable summary by default. Add `--json` when you want structured output for scripts or an AI assistant. Add `--include-transcripts` only when you need capture transcripts or media URLs in JSON output; compact output omits them by default. ## Important terms * **Process** — a Clarity process created in the Duvo web app. * **Capture** — a source attached to a process, such as an interview, video recording, or uploaded AOP. * **Current process snapshot** — the generated description of how the process works today. * **Transformation proposal snapshot** — the generated proposal for how the process could be improved or automated. * **Proposal anchor** — the current process snapshot that a transformation proposal was generated from. If the anchor does not match the selected current process snapshot, compare output warns you. * **Evidence citation** — a stable citation ID that points from a generated step back to supporting capture evidence. * **Extra capture request** — a request for more source material when Clarity cannot confidently fill a gap. * **Readiness** — Clarity's per-step signal for how ready a proposed step is for automation. * **Facets** — structured cost, risk, lineage, and automation slices built for AI assistants and scripts. ## Find a process ```bash theme={"dark"} duvo clarity list duvo clarity list --status complete --limit 20 duvo clarity list --process-version 2 --csv duvo clarity search "purchase order" --json ``` Use `--status` to filter by lifecycle status and `--process-version` to separate legacy v1 processes from newer v2 processes. Use `--csv` when you want a process inventory in a spreadsheet. ## Inspect the selected context ```bash theme={"dark"} duvo clarity overview duvo clarity status duvo clarity export duvo clarity export --json ``` `overview` is the best first command for a process. It shows process health, selected versions, capture counts, warnings, and recommended next commands. `status` focuses on lifecycle state and generation health. `export` prints a Markdown brief by default. Use it when you want to save or share the compact process context: ```bash theme={"dark"} duvo clarity export > process-brief.md ``` ## Work with versions Clarity v2 stores generated content as snapshots. Most v2 commands select the `live` snapshot by default. ```bash theme={"dark"} duvo clarity versions duvo clarity current duvo clarity proposal duvo clarity compare ``` You can select a different snapshot with: | Selector | Meaning | | -------- | ------------------------------------------------- | | `live` | The snapshot currently shown in the app | | `latest` | The newest snapshot, even if it is not live | | `` | An exact snapshot ID from `duvo clarity versions` | Examples: ```bash theme={"dark"} duvo clarity current --snapshot latest duvo clarity proposal --snapshot duvo clarity compare \ --current \ --proposal ``` Use `compare` when an assistant needs to understand what changed between the current process and the transformation proposal. It also shows whether the proposal anchor matches the selected current process. ## Review captures ```bash theme={"dark"} duvo clarity captures duvo clarity captures --csv duvo clarity captures --json duvo clarity capture --json ``` By default, capture output is compact for routine inspection: it includes metadata and usability signals, but not full transcripts or media URLs. When you need the full capture text in JSON output, add `--include-transcripts`: ```bash theme={"dark"} duvo clarity captures --json --include-transcripts duvo clarity capture --json --include-transcripts ``` ## Trace evidence ```bash theme={"dark"} duvo clarity evidence duvo clarity evidence --json duvo clarity evidence --citation ``` Use `evidence` when you need to verify where a generated step came from. The command prints citation IDs for each step. Resolve one citation ID to see the supporting source: ```bash theme={"dark"} duvo clarity evidence --citation citation:::1 ``` For scripts, use `--json` and require downstream outputs to cite only IDs returned by this command. ## Find gaps and automation candidates ```bash theme={"dark"} duvo clarity gaps duvo clarity readiness duvo clarity facets ``` `gaps` groups missing information, open questions, assumptions, and extra capture requests by proposed step. When Duvo has nominated someone from the process roster to fill a gap in a follow-up interview, the request also shows the suggested interviewee and a short reason. `readiness` summarizes which proposed steps are high, medium, or low readiness for automation. `facets` returns a structured view of: * Cost signals * Risk signals * Current and proposal step lineage * Evidence coverage * Automation readiness * Warnings and next commands Use `duvo clarity facets --json` when an AI assistant needs a compact structured input before deciding which deeper command to call next. ## Update a Process Use write commands when you want to generate, promote, revert, postprocess, or assign follow-up capture work for Clarity v2 snapshots from a script. ```bash theme={"dark"} duvo clarity generate-current-process duvo clarity generate-transformation-proposal \ --current-process-id duvo clarity generate-transformation-proposal \ --regenerate-from duvo clarity save-current-process \ --baseline-snapshot-id \ --steps-file edited-current-steps.json duvo clarity save-transformation-proposal \ --baseline-snapshot-id \ --steps-file edited-proposal-steps.json duvo clarity promote-current-process duvo clarity promote-transformation-proposal duvo clarity revert-current-process duvo clarity revert-transformation-proposal duvo clarity postprocess current_process duvo clarity postprocess transformation_proposal duvo clarity assign-extra-capture-request \ --user-id duvo clarity stop-current-process duvo clarity stop-transformation-proposal duvo clarity build-automation ``` `generate-transformation-proposal` accepts either `--current-process-id` or `--regenerate-from`, not both. Use `--json` on any write command when you need the raw API response. `save-current-process` and `save-transformation-proposal` read edited steps from a JSON file. The file can contain either the step array directly or an object with a `steps` array. `assign-extra-capture-request` assigns a proposal gap to a team member. Omit `--user-id` to unassign the request. ## Manage Process Tags Tag processes with organization-wide labels to group and filter them across the landscape. A tag is a value plus an optional color hue. ```bash theme={"dark"} duvo clarity process-labels list --org duvo clarity process-labels list --org --search "fin" --limit 20 --offset 20 duvo clarity process-labels create --org --value "Finance" --color-hue 215 duvo clarity process-labels update --org --value "Ops" duvo clarity process-labels delete --org --yes duvo clarity process-labels list-process --process duvo clarity process-labels available --process --search "fin" duvo clarity process-labels assign --process --label duvo clarity process-labels unlink --process --label ``` Set `DUVO_ORG_ID` to skip `--org` on palette commands. Repeat `--label` to assign or unlink several tags at once, and use `--json` on any command for the raw API response. `list` and `available` return one page at a time (default 50 tags, maximum 100) and print how many of the total matched. Use `--limit` and `--offset` to page through larger palettes, and `--search` to filter tags by value on the server. Creating, updating, and deleting tags requires a manager role on a team in the organization (or an organization admin role); assigning or unlinking tags requires a manager role on the process's own team (or an organization admin role). Listing tags is open to all organization members. ## Import Miro Exports Import SVG, XML, PNG, or JPEG exports from Miro into a Clarity process: ```bash theme={"dark"} duvo clarity import-artifact miro-map.svg duvo clarity import-artifact miro-map.xml \ --extra-capture-request-id ``` `import-artifact` creates a signed upload URL, uploads the local file, and completes the import. For custom upload workflows, use `duvo api` against the public artifact-import endpoints directly. Supported content types are `image/svg+xml`, `application/xml`, `text/xml`, `image/png`, and `image/jpeg`. ## Invite Someone to an Interview Create or regenerate an interview invite link for a process: ```bash theme={"dark"} duvo clarity create-invite-link ``` The command prints the link and creation metadata. Send the URL to the person you want to interview. ## Use Artifact Chat If Artifact Chat is available for your team, use these commands to ask Clarity to modify generated artifacts, answer review questions, and accept or decline proposed patches. ```bash theme={"dark"} duvo clarity artifact-chat-conversations \ --snapshot-kind current_process duvo clarity artifact-chat-messages duvo clarity send-artifact-chat-message \ --snapshot-kind current_process \ --baseline-snapshot-id \ --message "Make the first step more specific." duvo clarity send-artifact-chat-message \ --conversation-id \ --snapshot-kind current_process \ --baseline-snapshot-id \ --answer question-id="Yes, this applies to all regions." duvo clarity decide-artifact-chat-patch --accept duvo clarity decide-artifact-chat-patch --decline ``` ## Check the environment ```bash theme={"dark"} duvo clarity doctor duvo clarity doctor duvo clarity tools ``` `doctor` checks authentication, API reachability, available commands, and optional process-level context health. `tools` lists the Clarity tool map used by the CLI, including each command and the underlying public API endpoint. It is useful when an assistant needs to decide which `duvo clarity` command can answer a question or perform a write. ## Legacy v1 processes The CLI can still read legacy v1 Clarity processes through: ```bash theme={"dark"} duvo clarity overview duvo clarity status duvo clarity captures duvo clarity capture duvo clarity export ``` V2-only commands such as `versions`, `current`, `proposal`, `compare`, `gaps`, `evidence`, `readiness`, and `facets` require a v2 process. If you run them against a v1 process, the CLI explains that the command is unavailable for that process version. ## Common workflows The examples below use a fictional Invoice Approval process with the ID `b3f1c2d4-1a2b-4c3d-8e9f-001122334455`. Swap in a real ID from `duvo clarity list` or `duvo clarity search`. ### Gather context for an AI assistant ```bash theme={"dark"} duvo clarity search "invoice approval" --json duvo clarity overview b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --json duvo clarity facets b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --json duvo clarity evidence b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --json ``` `search` resolves the process ID, `overview` orients the assistant (health, selected snapshots, recommended next commands), `facets` adds structured cost, risk, and automation slices, and `evidence` returns citation IDs the assistant can quote so its reasoning stays grounded in real sources. ### Produce a brief for a stakeholder ```bash theme={"dark"} duvo clarity export b3f1c2d4-1a2b-4c3d-8e9f-001122334455 > invoice-approval-brief.md duvo clarity gaps b3f1c2d4-1a2b-4c3d-8e9f-001122334455 >> invoice-approval-brief.md duvo clarity readiness b3f1c2d4-1a2b-4c3d-8e9f-001122334455 >> invoice-approval-brief.md ``` `export` writes the process overview as Markdown; appending `gaps` and `readiness` rounds the brief out with what is still missing and how automation-ready each proposed step is. ### Audit source coverage ```bash theme={"dark"} duvo clarity captures b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --csv > captures.csv duvo clarity evidence b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --json > evidence.json duvo clarity gaps b3f1c2d4-1a2b-4c3d-8e9f-001122334455 --json > gaps.json ``` Cross-reference the three files to see which captures were usable, which steps have citations, and where Clarity requested more evidence before you trust or automate the process. # Duvo CLI Source: https://docs.duvo.ai/cli/index Install and use the Duvo CLI to manage Agents, start Runs, move Files, and drive the Duvo API from your terminal or CI/CD pipelines. ## Agent Skills for the CLI The best way to use the Duvo CLI is alongside the public [Duvo Agent Skills repository](https://github.com/duvoai/skills). It's a free, open repository of skills you can download and combine with the CLI to get far more out of it — they teach Claude Code, Codex, Cursor, and other coding agents to operate Duvo directly: manage Agents, debug failed Runs, and write the AOPs that drive them, all without leaving your editor or terminal. It packages three ready-made skills: * **`duvo-cli`** — drive the full CLI (Agents, Runs, Cases, Queues, Files, Connections) through your agent * **`sop-writer`** — draft, rewrite, or critique Agent AOPs * **`job-debugger`** — analyze failed Runs, find the root cause, and propose fixes Download the skills, then install the CLI they drive: ```bash theme={"dark"} npx skills add duvoai/skills # download the Duvo agent skills ``` ```bash curl (macOS / Linux) theme={"dark"} curl -fsSL https://duvo.ai/install-cli.sh | bash ``` ```bash npm theme={"dark"} npm install -g @duvoai/cli # requires Node.js 24+ ``` ```bash theme={"dark"} duvo login # sign in ``` ```bash theme={"dark"} duvo whoami # confirm you're connected ``` Once installed, ask your agent things like "investigate why my last Run failed" or "rewrite this AOP to be clearer" and it will use the CLI for you. ## Use with Claude Code If you'd rather prime an agent by hand instead of installing the skills above, paste the prompt below into [Claude Code](https://www.anthropic.com/claude-code) (or any other coding agent) to teach it how to drive the Duvo CLI on your behalf. It primes the agent to install `duvo`, sign in, and use the right commands for the task you ask for next. ```text Claude Code prompt [expandable] theme={"dark"} You are pairing with me on a project that uses the Duvo CLI (`duvo`) to manage AI Agents, Runs, Connections, Files, and Cases. Follow these rules whenever I ask you to do anything Duvo-related. # Setup 1. Check if the CLI is installed: `duvo --version`. If it is missing, install it with `curl -fsSL https://duvo.ai/install-cli.sh | bash` (macOS/Linux), or `npm install -g @duvoai/cli` (requires Node.js 24+). 2. Check authentication with `duvo whoami`. If I am not signed in, run `duvo login` (interactive OAuth) or `duvo login --api-key ` for non-interactive shells. Ask me which to use if it is unclear. 3. If I mention multiple teams or environments, use named profiles: `duvo login --name ` and `--profile ` on individual commands. Never change my default profile without asking. # How to work - Always pass `--json` and pipe through `jq` when you need to parse output. Never scrape the human-friendly tables. - Before running a command, run `duvo --help` if you are not 100% sure of the flags. - Prefer the dedicated command groups over `duvo api`. Fall back to `duvo api ` only when no dedicated command exists. - For destructive actions (delete, stop, replace, bulk delegate), show me the exact command and wait for confirmation before executing. - Surface IDs (Agent ID, Run ID, Connection ID, Case ID, Queue ID) in your responses so I can reuse them. # Command map - Agents / workflows: `duvo agents`, `duvo agent-folders`, `duvo revisions` - Starting Runs automatically: `duvo agents schedules`, `duvo agents triggers`, `duvo agents case-triggers` - Starting Runs (incl. human-in-the-loop): `duvo runs` - Connections and integrations: `duvo connections`, `duvo integrations`, `duvo oauth` - Secrets and logins: `duvo secrets`, `duvo credentials`, `duvo revision-secrets`, `duvo revision-logins` - Files, Skills, and Plugins: `duvo files`, `duvo skills`, `duvo plugins` - Cases and Queues: `duvo cases`, `duvo queues`, `duvo queue-labels` - Clarity (read-only): `duvo clarity` - Profiles and teams: `duvo profiles`, `duvo team`, `duvo teams` - Escape hatches: `duvo api`, `duvo sandboxes` # Output When you finish a task, give me: (1) the commands you ran, (2) the key IDs or results, (3) a suggested next step. Docs: https://docs.duvo.ai/cli ``` The rest of this page is the human-readable reference for the same commands. ## Overview The Duvo CLI (`duvo`) brings Duvo to your terminal. Use it from scripts, CI/CD pipelines, and developer workflows to manage Agents, Connections, Files, Runs, and more — without leaving the command line. The CLI is a wrapper around the [Public API](../api-reference), so anything you can do via the API you can do with `duvo`. JSON output is built in for scripting, and named profiles let you switch between teams or environments instantly. ## What you can do * **Start Runs and respond to humans-in-the-loop** — Start Runs, stream messages live, approve or deny requests, send mid-run instructions. * **Manage Agents** — List, create, update, delete, and organize Agents into folders. * **Start Runs automatically** — Set up schedules, event triggers, and Case triggers. * **Manage Connections, secrets, and logins** — Authorize OAuth Connections, store env-var secrets and logins, and attach them to a Revision. * **Move Files and build Skills** — Upload documents to the team file library, and create, install, and edit Skills. * **Work with Cases and Queues** — Inspect Case history, delegate Cases in bulk, manage labels. * **Hit the raw API** — Call any Duvo endpoint via `duvo api` when you need something a dedicated command doesn't cover yet. ## Installation ```bash curl (macOS / Linux) theme={"dark"} curl -fsSL https://duvo.ai/install-cli.sh | bash ``` ```bash npm theme={"dark"} npm install -g @duvoai/cli ``` The curl script installs a standalone binary — no Node.js required. It supports macOS and Linux on x86\_64 and arm64. Override the install directory with `DUVO_INSTALL_DIR=$HOME/.local/bin` or pin a version with `DUVO_VERSION=`. The npm install requires Node.js 24 or newer. On Windows, use npm. Or install the standalone binary (no Node.js required): ```bash theme={"dark"} curl -fsSL https://duvo.ai/install-cli.sh | sh ``` Run `duvo --version` to confirm the install, and `duvo --help` to see every available command. ### Updating Run `duvo update` to update the CLI in place. It detects how the CLI was installed and picks the right method automatically — npm installs run `npm install -g @duvoai/cli@latest`, while the standalone binary downloads the latest release, verifies its checksum, and replaces itself. Use `duvo update --check` to see whether a newer version is available without installing anything. If the standalone binary lives in a directory you cannot write to (such as `/usr/local/bin`), `duvo update` stops with an error instead of updating. Rerun the installer, which requests sudo when needed: `curl -fsSL https://duvo.ai/install-cli.sh | sh` ## Quick start ```bash curl (macOS / Linux) theme={"dark"} # 1. Install curl -fsSL https://duvo.ai/install-cli.sh | bash # 2. Sign in (opens your browser) duvo login # 3. List your Agents duvo agents list # 4. Start a Run duvo runs start --agent # 5. Check Run status duvo runs get ``` ```bash npm theme={"dark"} # 1. Install (requires Node.js 24+) npm install -g @duvoai/cli # 2. Sign in (opens your browser) duvo login # 3. List your Agents duvo agents list # 4. Start a Run duvo runs start --agent # 5. Check Run status duvo runs get ``` ## Sign in The CLI stores credentials as **named profiles**. Each profile holds either an OAuth session or an API key, so you can switch between teams or workspaces without re-entering credentials each time. ```bash theme={"dark"} duvo login ``` The CLI first prompts you for a profile name (for example, `acme` or `personal`), then opens your browser so you can sign in to Duvo. Once you approve, the CLI stores the OAuth session under that profile name. The first profile you add becomes the default. Pass `--name ` to skip the prompt: ```bash theme={"dark"} duvo login --name acme ``` Generate a key at [Your Profile → API keys](https://app.duvo.ai/settings/profile#api-keys) — pick **All teams I can access** for a key that works across your teams, or scope it to a single team. Users with the Manager role or above can also create and view a team's keys at [Team Settings → API keys](https://app.duvo.ai/settings/api-keys). Then: ```bash theme={"dark"} duvo login --api-key ``` Use API keys for service accounts, CI pipelines, and any non-interactive environment. ### Add another profile Run `duvo login` again to repeat the browser sign-in and prompt for a new profile name. Pass `--api-key ` if you want the new profile to use an API key instead. ### Switch the default profile ```bash theme={"dark"} duvo profiles use personal ``` If you omit the profile name, an interactive picker opens so you can arrow-key through your saved profiles: ```bash theme={"dark"} duvo profiles use ``` ### Use a different profile for a single command ```bash theme={"dark"} duvo agents list --profile staging ``` `--profile ` works on every command and doesn't change your default. ### See who you're signed in as ```bash theme={"dark"} duvo whoami ``` ### Sign out ```bash theme={"dark"} duvo logout # sign out of the active profile duvo logout --name # sign out of a specific profile duvo logout --all # sign out of every stored profile ``` `duvo logout` revokes the OAuth tokens server-side and removes the profile locally. ### Environment variables For non-interactive use (CI, scripts), the CLI also reads: | Variable | Description | | -------------- | ---------------------------------------------- | | `DUVO_API_KEY` | API key — bypasses the stored profile entirely | | `DUVO_PROFILE` | Profile name to use instead of the default | ## Output formats By default every command prints a human-friendly table or summary. Add `--json` to any command for machine-readable output suitable for piping into `jq` or scripting: ```bash theme={"dark"} duvo agents list --json | jq '.agents[] | {id, name}' ``` ## Command groups The CLI is organized by resource. Use these guides to dig into each area: `duvo profiles`, `duvo team`, `duvo teams` `duvo agents`, `duvo agent-folders`, `duvo revisions` `duvo runs`, including live streaming and human-in-the-loop responses `duvo agents schedules`, `duvo agents triggers`, `duvo agents case-triggers` `duvo connections`, `duvo integrations`, `duvo oauth` `duvo files`, `duvo skills`, `duvo plugins` `duvo secrets`, `duvo credentials`, `duvo revision-secrets`, `duvo revision-logins` `duvo cases`, `duvo queues`, `duvo queue-labels` `duvo clarity` automation scripts, GitHub Actions, worked examples `duvo api`, `duvo sandboxes`, `duvo revision-integrations` Each guide includes the exact commands, flags, and a few realistic examples. ## Tips * Run `duvo --help` to see every available flag for any command. * Combine `--json` with `jq` to script complex workflows — for example, list all Runs that are waiting for human approval. * Set `DUVO_PROFILE` in your shell config to default to a non-default profile per project. * The CLI follows your Duvo team's permissions — if you can't see something in the UI, you can't see it via the CLI either. # Managing Agents Source: https://docs.duvo.ai/cli/managing-assignments List, create, update, and delete Agents, organize them into folders, and manage their Revisions and memory with the Duvo CLI. Agents are the workflows your team has built in Duvo. The CLI lets you list, inspect, create, and update Agents, organize them into folders, and manage their Revisions (versioned Setup snapshots). ## Listing and inspecting Agents ```bash theme={"dark"} duvo agents list # list all Agents duvo agents get # get a specific Agent ``` Add `--json` to any command for machine-readable output. ## Creating, updating, and deleting Agents ```bash theme={"dark"} duvo agents create \ --name "Invoice Processor" \ --input "Process incoming invoices…" \ --config path/to/config.json # --input is optional (AOP text); --config is optional (full Setup) duvo agents update \ --name "New Name" \ --enable-slack \ --enable-microsoft-teams \ --enable-agentic-memory # --name renames the Agent # --enable-slack / --enable-microsoft-teams toggle delivery (--disable-* to turn off) # --enable-agentic-memory toggles agentic memory (--disable-agentic-memory to turn off) duvo agents delete # delete an Agent (prompts for confirmation) duvo agents delete --yes # delete without prompting ``` ## Starting Runs automatically Agents can start Runs on their own — on a schedule, when an external event fires, or when a Case lands on a Queue. These live on their own page: see [Scheduling and Triggers](/cli/scheduling-and-triggers) for `duvo agents schedules`, `duvo agents triggers`, and `duvo agents case-triggers`. ## Organizing with folders Group Agents into folders for easier navigation. ```bash theme={"dark"} duvo agent-folders list # list all folders duvo agent-folders create --name "Finance" # create a top-level folder duvo agent-folders create --name "EMEA" \ --parent # create a nested folder duvo agent-folders update --name "New Name" # rename a folder duvo agent-folders update --parent # move folder under a parent duvo agent-folders update --move-to-root # move folder to root level duvo agent-folders delete # delete a folder (prompts for confirmation) duvo agent-folders delete --yes # delete without prompting duvo agent-folders move-agents \ --agent --agent \ --folder # move Agents into a folder duvo agent-folders move-agents \ --agent \ --to-root # move Agent to root level ``` ## Revisions A Revision is a versioned Setup snapshot of an Agent. Each time you publish changes, a new Revision is created. Most workflows don't need to manage Revisions directly — Runs always use the latest Revision automatically. Use these commands when you need to roll back, compare versions, or update a specific Revision in place. ```bash theme={"dark"} duvo revisions list --agent # list all Revisions duvo revisions get --agent # get a specific Revision duvo revisions create \ --agent \ --name "v2" \ --config-file path/to/config.json # use `-` to read Setup from stdin duvo revisions update \ --config-file path/to/config.json # update an existing Revision's Setup ``` ## Memory When an Agent has agentic memory enabled, it persists notes across Runs as memory files. Use these read-only commands to see what an Agent has remembered. ```bash theme={"dark"} duvo agents memory files # list the memory files stored for an Agent duvo agents memory file-get # print the contents of one memory file ``` Toggle agentic memory itself with `duvo agents update --enable-agentic-memory` / `--disable-agentic-memory`. ## Evaluation rubrics Every Run is scored against evaluation rubrics: the platform default rubrics plus up to five custom, Agent-specific rubrics per Revision. Custom rubrics are Pass/Fail checks written as a short title and a Pass condition. Use these commands to read and manage the custom set. ```bash theme={"dark"} duvo agents eval-rubrics # list active rubrics (platform + custom) duvo agents eval-rubrics add \ --title "Cited every source" \ --description "The reply links a source URL for each claim" # add one custom rubric — fails once the Revision already holds 5 duvo agents eval-rubrics update \ --title "New title" # edit a rubric's title and/or description (pass at least one) duvo agents eval-rubrics remove # remove a rubric (prompts for confirmation) duvo agents eval-rubrics remove --yes # remove without prompting # Replace the whole custom set from a JSON array of { "title", "description" } objects # (use "-" to read from stdin); an empty array clears the set. # This replaces every existing rubric, so it prompts for confirmation: duvo agents eval-rubrics replace --input rubrics.json duvo agents eval-rubrics replace --input rubrics.json --yes # replace without prompting ``` Add `--json` to any command for machine-readable output. These default to the Agent's live Revision; pass `--build ` to read or edit the set on a specific Revision. ## Scripting examples ### Create an Agent from a JSON config ```bash theme={"dark"} AGENT_ID=$(duvo agents create \ --name "Invoice Processor" \ --config-file ./invoice-processor.json \ --json | jq -r '.agent.id') echo "Created Agent: $AGENT_ID" ``` ### Roll out a config change across multiple Agents ```bash theme={"dark"} for AGENT in agent-1 agent-2 agent-3; do duvo revisions create \ --agent "$AGENT" \ --name "memory-enabled-$(date +%Y%m%d)" \ --config-file ./shared-config.json done ``` For commands that bind specific Connections or integrations to a Revision, see [Advanced commands](/cli/advanced). # Managing Connections Source: https://docs.duvo.ai/cli/managing-connections List and inspect your authorized Connections, browse your team's enabled Connection types, and start OAuth flows with the Duvo CLI. Connections in Duvo are your personal authorized accounts linked to integrations — for example, your Gmail or Slack account. The CLI lets you list and inspect Connections from the terminal, and discover which Connection types your team has enabled. For an overview of what Connections are and how to add new ones, see [Connections Overview](/user-guide/connections/connections-overview) and [How to Add a Connection](/user-guide/connections/how-to-add-connection). ## Available Connection types `duvo integrations` is the catalog of services your team has enabled in Duvo. Use it to find Connection-type IDs that you can pass to other commands. ```bash theme={"dark"} duvo integrations list # list the team's integration catalog duvo integrations list --json # raw JSON for scripting ``` Each entry shows the Connection type's `id`, `name`, `type`, `provider`, and `auth_method` (none, OAuth, API key, custom headers, etc.). ### Custom integrations If your team uses a custom MCP server, register it as a custom integration so Connections can be created against it: ```bash theme={"dark"} duvo integrations custom create \ --name "Internal Tools" \ --server-url https://mcp.internal.acme.com \ --auth-method url # register a custom MCP integration duvo integrations custom delete # remove it (prompts unless -y) ``` `--auth-method` is required and must be one of `url` (no auth), `apikey`, `headers`, or `oauth`. For `oauth`, pair it with `--oauth-client-id` and `--oauth-client-secret` if your server isn't DCR-capable. ## Listing your Connections `duvo connections` shows the Connections you've personally authorized. ```bash theme={"dark"} duvo connections list # list every Connection you own duvo connections list --type gmail # filter to one integration type duvo connections list --json # raw JSON for scripting ``` The table includes the Connection ID, name, Connection type, provider, and creation date. Use the ID with `duvo connections get` or to pin a Connection to a Revision (see [Advanced commands](/cli/advanced#pinned-connections)). ## Inspecting a single Connection ```bash theme={"dark"} duvo connections get # full details for one Connection duvo connections get --json ``` The output includes the integration metadata and which credential fields are configured. **Secret values (API keys, tokens, passwords) are never returned** — the response only tells you which fields are set, not their values. ## Probing a connection's tool catalog `duvo connections probe` tests connectivity and lists the tools a connection exposes — a dry run before wiring a connection into an Agent. ```bash Catalog connection theme={"dark"} duvo connections probe --slug hubspot # backend resolves the server URL and auth headers ``` ```bash Custom MCP server theme={"dark"} duvo connections probe --url https://mcp.internal.acme.com \ --header "Authorization=Bearer " # repeatable --header for custom auth ``` Provide exactly one of `--slug` or `--url`. On success it prints the tool list; add `--json` for raw output. For connections whose tool listing isn't available yet (for example, one that only exposes tools once connected), it prints a short notice and exits `0` — that's expected, not a failure. A genuine probe failure (unreachable server, rejected credentials) exits non-zero. ## Common workflows ### Find the Connection ID for a specific account When you have multiple Gmail Connections (different mailboxes, for example) and need to reference a specific one in a Revision: ```bash theme={"dark"} duvo connections list --type gmail --json | jq '.connections[] | {id, name, created_at}' ``` ### Pin a Connection to an Agent Revision Once you have the Connection ID, pin it so the Agent always uses that account: ```bash theme={"dark"} duvo revision-integrations connections pin \ --agent \ --revision \ --integration ``` See [Advanced commands → Pinned Connections](/cli/advanced#pinned-connections) for the full reference. ## Authorizing a Connection from the CLI OAuth-based Connections require a browser consent step, so `duvo oauth` starts the flow and hands you the authorization URL to open. Once you approve in the browser, the Connection is created on your account. ```bash Native OAuth theme={"dark"} duvo oauth native start # start a native OAuth flow (Gmail, Google Sheets, Outlook, ...) ``` ```bash MCP server theme={"dark"} duvo oauth mcp probe # inspect an MCP server's auth requirements duvo oauth mcp check --url # check whether an MCP server needs OAuth duvo oauth mcp authorize --url \ --integration-type # authorize an OAuth-protected MCP server ``` These commands kick off interactive OAuth flows. For the full setup experience — including which providers your team has enabled — the [Connections page](https://app.duvo.ai/integrations) in the dashboard remains the simplest path. For credential-based Connections (username/API key) rather than OAuth, see [Secrets and Logins](/cli/secrets-and-logins), or call the [Public API](../api-reference) directly. # Managing Files, Skills, and Plugins Source: https://docs.duvo.ai/cli/managing-files-and-skills Move documents in and out of your team's file library, create and manage Skills, and browse Plugins from the Duvo CLI. The CLI lets you move documents in and out of your team's shared file library, create and manage the Skills your Agents use, and browse the Plugins available to reference in a Setup. ## Files Files are documents stored in your team's shared file library. Agents can read, write, and update them as part of their work. ```bash theme={"dark"} duvo files list # list all team Files duvo files content # print the text content of a file to stdout duvo files content-set \ --content "updated text" # update the text content of a file duvo files content-set \ --content-file ./updated.txt # replace content from a local file duvo files rename \ --path \ --new-name new-name.csv # rename a file duvo files delete # delete a file (prompts for confirmation) duvo files delete --yes # delete without prompting ``` ### Uploading and downloading large files For files larger than a few megabytes, use presigned URLs to upload or download directly via HTTP: ```bash theme={"dark"} # Upload: get a presigned URL, then PUT the file to it duvo files upload-url \ --file-name data.csv \ --content-type text/csv # Download: get a presigned URL, then GET the file from it duvo files download-url ``` The CLI prints the presigned URL plus the HTTP method and headers to use. Pipe to `jq` and `curl` to script the actual upload or download. ### Scripting examples ```bash Sync a local directory to the Duvo Files library theme={"dark"} for FILE in ./reports/*.pdf; do URL=$(duvo files upload-url \ --file-name "$(basename "$FILE")" \ --content-type application/pdf \ --json | jq -r '.upload_url') curl -X PUT --data-binary "@$FILE" "$URL" done ``` ```bash Backfill a text file from local content theme={"dark"} duvo files content-set reports/notes.md \ --content-file ./local-notes.md ``` ## Skills Skills are reusable capabilities your Agents can call (for example, PDF parsing or Google Sheets editing). The CLI lets you browse, install, create, and manage your team's Skills. ### Browse and install ```bash theme={"dark"} duvo skills list # list Skills available to your team duvo skills list --system # restrict the list to system Skills duvo skills system # list global system Skills available to all teams duvo skills install # copy a system (or any accessible) Skill into your team's library duvo skills agents # list Agents whose live Setup references a Skill ``` ### Create and edit custom Skills ```bash theme={"dark"} duvo skills create \ --name "Invoice Parser" \ --description "Extract totals and line items from invoice PDFs" \ --content-file ./SKILL.md # create a Skill from a Markdown SKILL.md body duvo skills upload ./my-skill.zip # create or update a Skill from a SKILL.md file or ZIP archive duvo skills download # download a custom Skill as a ZIP archive duvo skills delete # delete a custom Skill (prompts unless -y) ``` `create` reads the SKILL.md body from `--content-file` (use `-` for stdin) or inline with `--content`. A ZIP passed to `upload` must contain `SKILL.md` at its root. If a Skill with the same name already exists, `upload` replaces its **active** content in place — a ZIP upload also removes the existing files first. No new version is created, so the previous content is not recoverable. Use the draft workflow below when you need to keep the version history. ### Manage Skill files ```bash theme={"dark"} duvo skills files # list the files in a Skill duvo skills file-get # print one file's contents duvo skills file-update \ --content "updated text" # update a file in a Skill ``` `skills file-update` edits the **active** version of a Skill in place — the change takes effect immediately and the previous content is gone. To keep a version history, edit a draft instead (see below). ### Work with Skill versions Every Skill keeps a version history. Open a draft, edit the draft's files, then activate it. The version that was active stays intact and can be re-activated at any time. ```bash theme={"dark"} duvo skills revisions list # version history (active, drafts, past versions) duvo skills revisions create # open (or resume) a draft copied from the active version duvo skills revisions create \ --from # start the draft from a specific past version duvo skills revisions files # list the files in a version duvo skills revisions file-get # print one file's contents duvo skills revisions file-update \ --content-file ./SKILL.md # write a file into the draft duvo skills revisions promote \ --name "Tighter prompts" # make the version active (and name it) duvo skills revisions update --name "…" # rename a version afterwards duvo skills revisions delete # delete a draft or past version (prompts unless -y) ``` To roll back, run `duvo skills revisions promote` on an older version — no draft needed. To draft a `SKILL.md` from a plain-English description without saving it, use `duvo skills generate --prompt "..."`. For details on individual Skills and what they do, see [Available Skills](/user-guide/skills/available-skills). ## Plugins Plugins are capability packs (browsing, default Skills, and the knowledge-work packs) that you can reference in an Agent's Setup. ```bash theme={"dark"} duvo plugins list # browse every plugin you can reference in a Setup duvo plugins list --json ``` # Profiles and Teams Source: https://docs.duvo.ai/cli/profiles-and-teams Manage stored CLI profiles, switch between teams, and inspect team membership with the Duvo CLI. The CLI stores credentials as **named profiles** — each holds either an OAuth session or an API key, so you can switch between teams or workspaces without re-entering credentials. This page is the reference for managing those profiles and the teams they act on. For first-time sign-in, see [Sign in](/cli/index#sign-in). ## Profiles ```bash theme={"dark"} duvo whoami # show the active profile, its key prefix, and team duvo profiles list # list all stored profiles (the default is marked) duvo profiles use [name] # switch the default profile (interactive picker if name omitted) duvo profiles rename # rename a profile, preserving its credentials duvo profiles remove # remove a profile locally ``` ### Use a different profile for a single command ```bash theme={"dark"} duvo agents list --profile staging ``` `--profile ` works on every command and doesn't change your default. ### Sign out ```bash theme={"dark"} duvo logout # sign out of the active profile duvo logout --name # sign out of a specific profile duvo logout --all # sign out of every stored profile ``` `duvo logout` revokes the OAuth tokens server-side and removes the profile locally. ### Environment variables For non-interactive use (CI, scripts), the CLI also reads: | Variable | Description | | -------------- | ---------------------------------------------- | | `DUVO_API_KEY` | API key — bypasses the stored profile entirely | | `DUVO_PROFILE` | Profile name to use instead of the default | ## Teams A profile's credentials are scoped to a team. Use these commands to confirm which team you're acting on and inspect its members before running commands that change data. ```bash theme={"dark"} duvo team current # the team scoped to your active credentials duvo team get # full details for that team duvo team use # set the team for the active profile duvo team members [--team ] [--limit ] [--offset ] # list team members duvo teams list # list every team your credentials can act on duvo teams orgs # list the organizations you belong to and your role in each duvo teams org # list all teams in an organization you belong to duvo teams create-org-team --name # create a new team in an organization you administer (org Admin, Executive, or Owner) duvo teams invite-org-member --email [--role] [--team-id] [--frontend-url] # invite a person to an org, optionally onto a team (org Admin, Executive, or Owner) duvo teams org-insights [--start-date] [--end-date] # org-wide run KPIs across all teams (org admins and above) duvo teams org-metrics [--start-date] [--end-date] # per-team run metrics across the org (org admins and above) duvo teams org-usage [--granularity day|week|month] # org-wide run volume over time (org admins and above) ``` If `--team` is omitted, member listing uses the team scoped to your API key or active profile. Add `--json` to any command for machine-readable output. ### Confirm your team before a destructive command ```bash theme={"dark"} duvo team current --json | jq -r '.team.name' ``` Running this first is a cheap way to make sure a bulk delete or delegate lands on the team you intend. ## Related installation and first sign-in authenticating with API keys in pipelines # Starting Runs (CLI) Source: https://docs.duvo.ai/cli/running-jobs Start Runs, check status, stream messages, respond to human-in-the-loop requests, and stop active Runs with the Duvo CLI. A Run is one execution of an Agent. Use `duvo runs` to start Runs, check status, stream messages, respond to human-in-the-loop requests, and stop active Runs. ## Starting and inspecting Runs ```bash theme={"dark"} duvo runs start --agent # start a Run duvo runs list --agent # list Runs for an Agent duvo runs get # get Run status duvo runs messages # list conversation messages duvo runs stop # stop a running Run ``` Use `--since` and `--until` to list Runs that completed in a fixed window. The `--since` bound is inclusive, and the `--until` bound is exclusive. ```bash theme={"dark"} duvo runs list --agent \ --since 2026-08-01T00:00:00Z \ --until 2026-08-02T00:00:00Z ``` Add `--json` to any command for machine-readable output suitable for scripting. Add `--count-only` when you need the matching total without Run rows. All Run filters still apply. ```bash theme={"dark"} duvo runs list --agent --status completed --count-only # Total Runs: 42 ``` ## Streaming a Run live Add `--follow` to watch messages stream in real time instead of polling `duvo runs get`. It works two ways: ```bash theme={"dark"} duvo runs start --agent --follow # start a Run and stream its messages duvo runs messages --follow # attach to a running Run and follow new messages ``` `--follow` keeps printing new messages until the Run completes, then exits. ## Mid-run interaction Send a message to a Run in progress (for example, to add clarifying instructions): ```bash theme={"dark"} duvo runs send-message \ --message "Please also check the backup." ``` ## Responding to human-in-the-loop requests When an Agent pauses to ask a human a question or request approval, you can respond from the CLI: ```bash theme={"dark"} duvo runs respond --approve # approve a human request duvo runs respond --deny # deny a human request duvo runs respond \ --answer "=" # answer a pending question ``` The `--answer` flag takes a `=` pair. Find the `` by running `duvo runs messages ` and looking at the pending human request. ## Scripting examples ### Start a Run and wait for it to finish ```bash theme={"dark"} RUN_ID=$(duvo runs start --agent "$AGENT_ID" --json | jq -r '.run.id') while true; do STATUS=$(duvo runs get "$RUN_ID" --json | jq -r '.run.status') case "$STATUS" in completed|failed|stopped) break ;; esac sleep 5 done echo "Run $RUN_ID finished with status: $STATUS" ``` ### Auto-approve any pending human requests on a Run Useful in trusted batch pipelines where every approval is expected to pass: ```bash theme={"dark"} duvo runs messages "$RUN_ID" --json \ | jq -r '.messages[] | select(.type=="human_request" and .status=="pending") | .id' \ | xargs -I {} duvo runs respond "$RUN_ID" --approve ``` ### Forward Run output to a script ```bash theme={"dark"} duvo runs messages "$RUN_ID" --json \ | jq -r '.messages[] | select(.role=="assistant") | .content' \ > run-output.log ``` ## Related List and configure the Agents you can start When Runs are kicked off by Cases on a Queue # Scheduling and Triggers Source: https://docs.duvo.ai/cli/scheduling-and-triggers Start Runs automatically on a schedule or in response to events and Cases, using the Duvo CLI. A Run doesn't have to be started by hand. The CLI lets you set up three ways for an Agent to start work on its own: on a recurring **schedule**, when an external **event** fires, or when a new **Case** lands on a Queue. ## Schedules A schedule fires against an Agent's live Setup on a recurring cadence — daily, on workdays, weekly, monthly, or a custom cron expression. ```bash theme={"dark"} duvo agents schedules list # list schedules for an Agent ``` ### Create a schedule ```bash Daily theme={"dark"} duvo agents schedules create \ --frequency daily \ --timezone America/New_York \ --time 09:00 # every day at 9am New York time ``` ```bash Weekly theme={"dark"} duvo agents schedules create \ --frequency weekly \ --timezone Europe/London \ --day monday \ --time 08:30 # every Monday at 8:30am London time ``` ```bash Monthly theme={"dark"} duvo agents schedules create \ --frequency monthly \ --timezone UTC \ --day-of-month 1 \ --time 06:00 # the 1st of every month at 6am UTC ``` ```bash Custom cron theme={"dark"} duvo agents schedules create \ --frequency custom \ --timezone UTC \ --cron "0 */4 * * *" # custom cron: every 4 hours ``` | Flag | Description | | -------------------- | --------------------------------------------------------------------- | | `--frequency` | Required. One of `daily`, `workday`, `weekly`, `monthly`, or `custom` | | `--timezone` | Required. IANA timezone (e.g. `America/New_York`) | | `--time ` | Time of day, 24-hour. Required for daily, workday, weekly, monthly | | `--day ` | Day of week for weekly schedules | | `--day-of-month ` | Day of month (1–31) for monthly schedules | | `--cron ` | Cron expression. Required for custom schedules | | `--disabled` | Create the schedule paused (default: enabled and running) | | `--no-recurring` | Retire the schedule after its first run (default: recurring) | ### Update or delete a schedule ```bash theme={"dark"} duvo agents schedules update --time 10:00 # change the time duvo agents schedules update --disable # pause the schedule duvo agents schedules update --enable # resume it duvo agents schedules update --one-shot # run once, then retire duvo agents schedules delete # delete (prompts unless -y) duvo agents schedules delete --yes # delete without prompting ``` `update` also accepts `--timezone`, `--day`, `--day-of-month`, `--cron`, and matching `--clear-*` flags to remove a field. Run `duvo agents schedules update --help` for the full set. ## Case triggers A Case Trigger connects an Agent to a Queue so it automatically picks up new Cases as they arrive. For background on the Queue system, see [Queue](/user-guide/assignment-features/case-queue). ```bash theme={"dark"} duvo agents case-triggers list # list triggers and their IDs duvo agents case-triggers get # show details for one trigger duvo agents case-triggers create --queue --enabled # create a trigger (omit --enabled to create it disabled) duvo agents case-triggers update --enable # enable an existing trigger duvo agents case-triggers update --disable # disable an existing trigger duvo agents case-triggers update \ --queue # switch the queue the trigger listens to duvo agents case-triggers update --concurrency 1 # run Cases one at a time (sequential) duvo agents case-triggers update --clear-concurrency # use the platform default (parallel) again duvo agents case-triggers delete # delete the trigger duvo agents case-triggers preview --queue # check whether a queue already has an active trigger ``` Only the person who set up a trigger or a team Builder or admin can disable it or change its queue. Disabled triggers stay attached to the Agent but stop dispatching new Runs until re-enabled. `--concurrency` only accepts `1` (run Cases one at a time). Use `--clear-concurrency` to fall back to the platform default, which runs Cases in parallel. Raising a Queue's parallel limit above the platform default is configured by Duvo and can't be set from the CLI or API. ## Event triggers An event trigger starts a Run automatically when an external event fires — an email arrives, a Linear issue is created, a file changes in Google Drive, and so on. The Connection must already be set up for the Agent before you can add a trigger for it. ```bash theme={"dark"} duvo agents triggers list # list your triggers for an Agent duvo agents triggers types # list available trigger types per Connection duvo agents triggers set \ --integration gmail --trigger-type email_received # create or update a trigger (enabled by default) duvo agents triggers set \ --integration gmail --trigger-type email_received \ --filter-config '{"from":"boss@acme.com"}' # add an integration-specific filter duvo agents triggers set \ --integration gmail --trigger-type email_received --disabled # pause a trigger without removing it ``` Each Connection has at most one event trigger per Agent, so `set` creates the trigger the first time and updates it after that. Use `triggers types` to discover the `--integration` and `--trigger-type` values a Connection supports. ## Related Create and configure the Agents these triggers and schedules fire Start and monitor Runs by hand Inspect the Cases a Case Trigger picks up # Scripting and CI/CD Patterns Source: https://docs.duvo.ai/cli/scripting-and-ci Run the Duvo CLI in scripts and CI/CD pipelines with non-interactive authentication, JSON output, and worked automation examples. The Duvo CLI is designed to run in scripts and automation pipelines, not just interactively. This page covers how to authenticate in non-interactive environments, common automation patterns, and three complete worked examples. ## Authentication in CI/CD and scripts ### Use an API key, not OAuth OAuth sessions require a browser login and are bound to a user's session. For CI/CD pipelines and server-side scripts, use an API key instead. Generate a key at [Your Profile → API keys](https://app.duvo.ai/settings/profile#api-keys) — scoped to a single team or to all teams you can access — and store it as a secret environment variable in your CI system (GitHub Actions secrets, GitLab CI variables, AWS Secrets Manager, etc.). Users with the Manager role or above can also create and view a team's keys at [Team Settings → API keys](https://app.duvo.ai/settings/api-keys). ### Pass the key as an environment variable The CLI reads `DUVO_API_KEY` automatically, so you never need to touch a config file or run `duvo login` in a pipeline: ```bash Inline theme={"dark"} DUVO_API_KEY="dv_..." duvo agents list --json ``` ```bash Exported theme={"dark"} export DUVO_API_KEY="${DUVO_API_KEY}" # sourced from environment duvo agents list --json duvo runs start --agent "$AGENT_ID" --json ``` ### Rotating API keys API keys do not expire by default. Rotate them by: Create a new key at [Your Profile → API keys](https://app.duvo.ai/settings/profile#api-keys). Update the key in your CI secret store. Delete the old key from the dashboard. There is a brief window between steps where both keys are valid — this ensures zero-downtime rotation. If a key is compromised, delete it immediately and treat any Runs that ran under it as potentially untrusted. ### GitHub Actions example ```yaml theme={"dark"} jobs: duvo-sync: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm install -g @duvoai/cli - run: duvo agents list --json env: DUVO_API_KEY: ${{ secrets.DUVO_API_KEY }} ``` *** ## Common scripting patterns ### Start a Run and wait for it to finish `duvo runs start` returns immediately. Poll `duvo runs get` until the Run reaches a terminal status: ```bash theme={"dark"} RUN_ID=$(duvo runs start \ --agent "$AGENT_ID" \ --message "Process the daily batch." \ --json | jq -r '.run.id') while true; do STATUS=$(duvo runs get "$RUN_ID" --json | jq -r '.run.status') case "$STATUS" in completed|failed|stopped) break ;; esac sleep 10 done if [ "$STATUS" != "completed" ]; then echo "Run failed with status: $STATUS" >&2 exit 1 fi echo "Run $RUN_ID completed." ``` ### Upload files before starting a Run When your Agent needs to process files, create a sandbox, upload the files, and pass the sandbox ID to the run: ```bash theme={"dark"} SANDBOX_ID=$(duvo sandboxes create --json | jq -r '.sandbox.id') duvo sandboxes upload "$SANDBOX_ID" ./input-data.csv RUN_ID=$(duvo runs start \ --agent "$AGENT_ID" \ --sandbox-id "$SANDBOX_ID" \ --json | jq -r '.run.id') ``` For files larger than 10 MB, get a presigned URL and upload directly: ```bash theme={"dark"} UPLOAD=$(duvo sandboxes prepare-upload-url "$SANDBOX_ID" \ --path /workspace/data.csv --json) URL=$(echo "$UPLOAD" | jq -r '.upload_url') curl -X PUT --data-binary "@./data.csv" "$URL" ``` ### Bulk-reprocess Cases on an Agent When you need to route a set of Cases to a specific Agent — for example, assigning a backlog of items after a new Agent is deployed. Any active Runs for the specified Cases are interrupted. ```bash theme={"dark"} duvo cases bulk-reprocess \ --queue "$QUEUE_ID" \ --agent "$AGENT_ID" \ --ids "case-1,case-2,case-3,case-4,case-5" \ --yes ``` `--ids` accepts a comma-separated list of up to 100 Case IDs. The `--yes` flag skips the confirmation prompt, which is required in non-interactive scripts. ### Collect Run output from a completed run After a Run finishes, pull the assistant's messages to feed the output into downstream systems: ```bash theme={"dark"} duvo runs messages "$RUN_ID" --json \ | jq -r '[.messages[] | select(.role=="assistant") | .content] | join("\n")' ``` ### Roll out an Agent config change to multiple Agents When a shared config file is updated (for example, a common AOP or tool set), push it as a new Revision across every affected Agent: ```bash theme={"dark"} REVISION_NAME="config-update-$(date +%Y%m%d)" for AGENT_ID in agent-id-1 agent-id-2 agent-id-3; do duvo revisions create \ --agent "$AGENT_ID" \ --name "$REVISION_NAME" \ --config-file ./shared-config.json echo "Updated $AGENT_ID" done ``` *** ## Worked examples ### Example 1: One-shot Run trigger Trigger a Run from any shell or pipeline and print the final output. Exit non-zero if the Run fails. ```bash theme={"dark"} #!/usr/bin/env bash set -euo pipefail AGENT_ID="$1" # pass as argument: ./trigger-job.sh MESSAGE="${2:-}" # optional message RUN_ID=$(duvo runs start \ --agent "$AGENT_ID" \ ${MESSAGE:+--message "$MESSAGE"} \ --json | jq -r '.run.id') echo "Started Run: $RUN_ID" while true; do STATUS=$(duvo runs get "$RUN_ID" --json | jq -r '.run.status') case "$STATUS" in completed|failed|stopped) break ;; esac sleep 10 done echo "Run finished: $STATUS" # Print the last assistant message duvo runs messages "$RUN_ID" --json \ | jq -r '.messages[] | select(.role=="assistant") | .content' \ | tail -1 [ "$STATUS" = "completed" ] || exit 1 ``` ### Example 2: Nightly Agent config sync from Git Store Agent configs as JSON files in a Git repository and push any changed configs to Duvo on every merge to `main`. This lets you version-control your Agent Setups alongside your application code. **Repository layout:** ``` assignments/ invoice-processor.json order-tracker.json supplier-follow-up.json agent-ids.env # INVOICE_PROCESSOR_ID=abc123 ... ``` **Sync script (`.github/workflows/sync-assignments.yml`):** ```yaml theme={"dark"} name: Sync Agents on: push: branches: [main] paths: - "assignments/**" jobs: sync: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 2 # need HEAD and HEAD^ to diff - run: npm install -g @duvoai/cli - name: Push changed configs env: DUVO_API_KEY: ${{ secrets.DUVO_API_KEY }} run: | source agent-ids.env CHANGED=$(git diff --name-only HEAD^ HEAD -- assignments/) for FILE in $CHANGED; do NAME=$(basename "$FILE" .json) VAR_NAME=$(echo "$NAME" | tr '[:lower:]-' '[:upper:]_')_ID AGENT_ID="${!VAR_NAME:-}" if [ -z "$AGENT_ID" ]; then echo "No Agent ID for $NAME — skipping." continue fi duvo revisions create \ --agent "$AGENT_ID" \ --name "git-$(git rev-parse --short HEAD)" \ --config-file "$FILE" echo "Synced $NAME ($AGENT_ID)" done ``` Only files changed in the push are synced, so the workflow is fast even with many Agent files in the repo. ### Example 3: Weekly Run-status report Run weekly in CI to summarize how many Runs completed, failed, or are still running across your key Agents. Post the summary wherever your team receives reports. ```bash theme={"dark"} #!/usr/bin/env bash set -euo pipefail # Space-separated list of Agent IDs to include in the report AGENTS="agent-id-1 agent-id-2 agent-id-3" completed=0 failed=0 stopped=0 for AGENT_ID in $AGENTS; do RUNS=$(duvo runs list --agent "$AGENT_ID" --limit 100 --json 2>/dev/null \ || echo '{"runs":[]}') completed=$((completed + $(echo "$RUNS" | jq '[.runs[] | select(.status=="completed")] | length'))) failed=$((failed + $(echo "$RUNS" | jq '[.runs[] | select(.status=="failed")] | length'))) stopped=$((stopped + $(echo "$RUNS" | jq '[.runs[] | select(.status=="stopped")] | length'))) done total=$((completed + failed + stopped)) echo "Weekly Run Summary" echo "==================" echo "Completed : $completed / $total" echo "Failed : $failed / $total" echo "Stopped : $stopped / $total" ``` Pipe the output to `slack-cli`, `mail`, or any notification tool your team uses. *** ## Tips * Always add `--yes` to bulk operations (`bulk-reprocess`, `bulk-update-status`, `cases delete`) in scripts so they don't block waiting for confirmation. * Combine `--json` with `jq` for all scripting — human-readable output can change between CLI versions, but JSON is stable. * Set `DUVO_PROFILE` to target a non-default profile (e.g., staging) without changing your shell's default: `DUVO_PROFILE=staging duvo runs start --agent "$AGENT_ID" --json`. * Run `duvo --help` to see the full flag set for any command. ## Related Full command reference for `duvo runs` Creating Agents and Revisions Bulk Case operations `duvo api`, sandboxes, and raw API access REST alternative if you need more than the CLI offers # Secrets and Logins Source: https://docs.duvo.ai/cli/secrets-and-logins Store env-var secrets and logins, and attach them to an Agent Revision so Runs can use them, with the Duvo CLI. Some Runs need credentials to do their work — an API key passed as an environment variable, or a username and password for a website or application the agent signs into. The CLI lets you store these securely and attach them to a specific Revision of an Agent. Values you store are **encrypted at rest and never echoed back** — listing a secret or login shows you which fields are set, not their values. Secrets and logins are **personal by default**. Pass `--shared` when creating one to make it available to the whole team (requires a manager role). ## Env-var secrets A secret holds one or more environment variables that are injected into a Run at runtime. ```bash theme={"dark"} duvo secrets list # list secrets you can see duvo secrets get # show one secret (which keys are set, not their values) duvo secrets create \ --name "Stripe API" \ --value STRIPE_API_KEY=sk_live_... # create a personal secret (repeat --value for multiple vars) duvo secrets create \ --name "Shared analytics" \ --value SEGMENT_KEY=... \ --shared # create a team-shared secret (requires manager role) duvo secrets update --name "New name" # rename or re-scope a secret duvo secrets delete # delete a secret (prompts unless -y) ``` `--value` takes a `KEY=VALUE` pair and can be repeated to store several variables under one secret. Use `--service-slug ` to tag a secret with the service it belongs to. ## Logins A login holds a website or application credential — domain, username, password, and optional TOTP secret — that the agent uses to sign in during a Run, in the browser or in desktop sessions (Computer Use and Windows Remote Desktop). ```bash theme={"dark"} duvo credentials list # list logins you can see duvo credentials list --domain example.com # filter by domain duvo credentials get # show one login (which fields are set, not their values) duvo credentials create \ --domain example.com \ --username alice@example.com \ --password "" # create a personal login duvo credentials create \ --domain example.com \ --username alice@example.com \ --otp-secret "" \ --shared # create a team-shared login (requires manager role) duvo credentials update --password "" # update a login duvo credentials delete # delete a login (prompts unless -y) ``` At least one of `--password` or `--otp-secret` must be provided when creating a login. The TOTP secret lets the agent generate one-time codes for sites that require two-factor authentication. ## Attaching to a Revision Storing a secret or login doesn't make it available to a Run on its own — you attach it to the specific Revision of an Agent whose Runs should use it. ```bash theme={"dark"} duvo revision-secrets list \ --agent --revision # list secrets attached to a Revision duvo revision-secrets attach \ --agent --revision \ --secret # attach a secret duvo revision-secrets detach \ --agent --revision [-y] # detach a secret (prompts unless -y) ``` ```bash theme={"dark"} duvo revision-logins list \ --agent --revision # list logins attached to a Revision duvo revision-logins attach \ --agent --revision \ --credential # attach a login duvo revision-logins detach \ --agent --revision [-y] # detach a login (prompts unless -y) ``` Use `duvo secrets list` and `duvo credentials list` to find the IDs to attach, and `duvo revisions list --agent ` to find Revision IDs. ## Related Find and create the Revisions you attach secrets and logins to For OAuth-based accounts (Gmail, Slack) rather than raw credentials # Available MCP Tools Source: https://docs.duvo.ai/mcp/available-tools Complete reference for all tools exposed by the Duvo MCP server. This is the catalog of tools the [Duvo MCP server](/mcp/duvo-mcp-server) makes available once your host is connected. It exposes every [Public API](../api-reference) endpoint as a tool. Tool names are the OpenAPI `operationId` values — camelCase, stable identifiers. Renaming a value is a breaking change, so names only change in major releases. New Public API endpoints automatically become MCP tools on the next deploy. There is no separate registration step. | Tool | Description | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `listAgents` | List Agents for your team. | | `createAgent` | Create a new Agent. | | `getAgent` | Get an Agent by ID. | | `updateAgent` | Update an Agent's display name or delivery settings. | | `deleteAgent` | Delete an Agent. Active Runs are interrupted, and its schedules and Case Triggers are removed. | | `moveAgent` | Move an Agent (and its connected workspace, including its Memory) to another team. Refused if the destination team has archived Memory for the Agent or one of its Queues. | | `getEvalScores` | Get aggregate evaluation scores for an Agent's Runs since a given time. | | `getEvalRubrics` | List the platform and Agent-specific evaluation rubrics for a build. | | `createEvalRubric` | Add one custom evaluation rubric to a build (max 5 per revision). | | `replaceEvalRubrics` | Replace a build's entire custom evaluation rubric set (max 5). | | `updateEvalRubric` | Edit a custom evaluation rubric's title or description. | | `deleteEvalRubric` | Remove a custom evaluation rubric. | | Tool | Description | | -------------------- | -------------------------------------- | | `listAgentFolders` | List folders for organizing Agents. | | `createAgentFolder` | Create a new folder. | | `updateAgentFolder` | Rename or update a folder. | | `deleteAgentFolder` | Delete a folder. | | `moveAgentsToFolder` | Move one or more Agents into a folder. | A Setup is a versioned configuration of an Agent — its AOP, Connections, and other settings. | Tool | Description | | -------------------- | --------------------------------------------------------------- | | `listAgentRevisions` | List Setups for an Agent. | | `getRevision` | Get a Setup by ID. | | `createRevision` | Create a new Setup for an existing Agent. | | `updateRevision` | Update a Setup's name or AOP. | | `promoteRevision` | Promote a Setup to active, making it the one used for new Runs. | | Tool | Description | | ----------------------- | ---------------------------------------------------------- | | `listRuns` | List Runs for your team. | | `startRun` | Start a new Run on an Agent. | | `getRun` | Get a Run's current status and details. | | `listRunMessages` | List all messages exchanged during a Run. | | `postRunMessage` | Send a message to an active Run. | | `respondToHumanRequest` | Respond to a human-in-the-loop request from an active Run. | | `stopRun` | Stop an active Run. | | `getRunEvaluation` | Get the latest evaluation for a completed Run. | | Tool | Description | | ---------------------- | ----------------------------------------------- | | `listAgentMemoryFiles` | List the memory files an Agent has saved. | | `getAgentMemoryFile` | Get the contents of a single Agent memory file. | | Tool | Description | | --------------------- | ----------------------------------------------------------- | | `listFiles` | List Files for your team. | | `createFileUploadUrl` | Generate a signed URL to upload a new file to team storage. | | `getFileContent` | Get the text content of a file. | | `updateFileContent` | Update the text content of a file. | | `getFileDownloadUrl` | Generate a signed download URL for a file. | | `renameFile` | Rename a file. | | `deleteFile` | Delete a file from team storage. | Cases are individual work items routed through an Agent. Queues group related cases. | Tool | Description | | --------------------------- | -------------------------------------------------- | | `listQueues` | List queues for your team. | | `createQueue` | Create a new queue. | | `getQueue` | Get a queue by ID. | | `updateQueue` | Update a queue's name or settings. | | `deleteQueue` | Delete a queue. | | `listQueueAgents` | List Agents attached to a queue. | | `listCases` | List cases in a queue. | | `searchCases` | Search for cases across queues. | | `getCase` | Get a case by ID. | | `updateCase` | Edit a case's title or data. | | `createCases` | Create new cases in a queue. | | `deleteCase` | Delete a case. | | `bulkReprocessCases` | Re-process a batch of cases on a chosen Agent. | | `bulkUpdateCaseStatus` | Update the status of multiple cases at once. | | `bulkUpdateCasePriority` | Set the priority of multiple cases at once. | | `listCaseRuns` | List Runs for a specific case. | | `listCaseRunRecentMessages` | Get recent messages from the latest Run on a case. | | Tool | Description | | ------------------ | ----------------------------------------- | | `listQueueLabels` | List labels defined in a queue. | | `createQueueLabel` | Create a new label in a queue. | | `updateQueueLabel` | Update a queue label's name or color. | | `deleteQueueLabel` | Delete a queue label. | | `listCaseLabels` | List labels currently assigned to a case. | | `assignCaseLabels` | Assign one or more labels to a case. | | `unlinkCaseLabels` | Remove labels from a case. | Case triggers automatically route new cases to a queue based on matching rules. | Tool | Description | | ---------------------------------- | ----------------------------------------------- | | `listAgentCaseTriggers` | List case triggers for an Agent. | | `createAgentCaseTrigger` | Create a new case trigger. | | `getAgentCaseTrigger` | Get a case trigger by ID. | | `updateAgentCaseTrigger` | Update a case trigger's rules or settings. | | `deleteAgentCaseTrigger` | Delete a case trigger. | | `previewAgentCaseTriggerConflicts` | Preview conflicts before saving a case trigger. | Event triggers start a Run automatically when an external event fires (for example, an email arrives, a Linear issue is created, or a file changes in Google Drive). | Tool | Description | | ----------------------- | ------------------------------------------------------------ | | `listAgentTriggers` | List the event triggers you own for an Agent. | | `upsertAgentTrigger` | Create or update an event trigger for an Agent. | | `listAgentTriggerTypes` | List the available trigger types for an Agent by Connection. | Duvo proposes improvements to an Agent based on its past Runs — for example, adding, removing, or replacing a Connection. These tools manage the suggestions inbox. | Tool | Description | | ------------------------ | --------------------------------------------------------------------------------- | | `listAgentSuggestions` | List an Agent's pending or historical suggestions. | | `getAgentSuggestion` | Fetch a single suggestion, including the progress of an AOP change being applied. | | `consumeAgentSuggestion` | Apply a suggestion to the Agent's draft Setup. | | `rejectAgentSuggestion` | Dismiss a pending suggestion. | | Tool | Description | | -------------------------- | ---------------------------------------------------------------------------------------------------------------- | | `listIntegrations` | List available connection types for your team. | | `listConnections` | List your team's authorized Connections. | | `getConnection` | Get a Connection by ID. | | `createConnection` | Create a new Connection. | | `updateConnection` | Update a Connection's settings. | | `deleteConnection` | Remove a Connection. | | `getConnectionCredentials` | Get credentials for a Connection. | | `createCustomIntegration` | Register a custom MCP server as a Connection type. | | `deleteCustomIntegration` | Remove a custom MCP server Connection type. | | `probeMcpServer` | Test connectivity to an MCP server URL. | | `startNativeOAuth` | Start an OAuth flow for a native provider (Gmail, Google Sheets, Outlook, etc.) and return an authorization URL. | | `authorizeMcpOAuth` | Start an OAuth flow for a remote MCP server using Dynamic Client Registration and return an authorization URL. | | `checkMcpOAuth` | Probe an MCP server URL to discover whether it supports OAuth Dynamic Client Registration. | | `listPluginCatalog` | List built-in plugins that can be referenced by name in a Setup's plugins array. | | Tool | Description | | ---------------------- | ----------------------------------------------- | | `listSkills` | List Skills for your team. | | `listSystemSkills` | List system-wide Skills available to all teams. | | `createSkill` | Create a new Skill. | | `listSkillFiles` | List files in a Skill. | | `getSkillFileContent` | Get the content of a Skill file. | | `updateSkillFile` | Update the content of a Skill file. | | `downloadSkill` | Download a Skill as an archive. | | `deleteSkill` | Delete a Skill. | | `listSkillAssignments` | List Agents that use a Skill. | Skills keep a version history. Instead of editing the live version in place with `updateSkillFile`, open a draft, edit the draft's files, then activate it — the previous version stays intact and can be re-activated later. | Tool | Description | | ----------------------------- | ------------------------------------------------- | | `listSkillRevisions` | List a Skill's version history. | | `createSkillRevision` | Open (or resume) a draft version of a Skill. | | `listSkillRevisionFiles` | List files in a Skill version. | | `getSkillRevisionFileContent` | Get the content of a file in a Skill version. | | `updateSkillRevisionFile` | Update a file in a draft or active Skill version. | | `promoteSkillRevision` | Make a Skill version the active one. | | `updateSkillRevision` | Rename a Skill version or change its description. | | `deleteSkillRevision` | Delete a draft or past Skill version. | | Tool | Description | | -------------------- | --------------------------------------- | | `listAgentSchedules` | List schedules configured for an Agent. | | `createSchedule` | Create a schedule for an Agent. | | `updateSchedule` | Update an existing schedule. | | `deleteSchedule` | Delete a schedule. | | Tool | Description | | ------------------ | ---------------------------------- | | `listSecrets` | List stored secrets for your team. | | `createSecret` | Create a new stored secret. | | `getSecret` | Get a secret by ID. | | `updateSecret` | Update a secret. | | `deleteSecret` | Delete a secret. | | `listCredentials` | List stored Logins for your team. | | `createCredential` | Create a new Login. | | `getCredential` | Get a Login by ID. | | `updateCredential` | Update a Login. | | `deleteCredential` | Delete a Login. | These tools attach Connections, Logins, and Secrets to a specific Setup. | Tool | Description | | ------------------------------------ | ----------------------------------------------------------------- | | `listRevisionIntegrations` | List Connections attached to a Setup. | | `attachRevisionIntegrations` | Attach one or more Connections to a Setup. | | `removeRevisionIntegration` | Remove a Connection from a Setup. | | `listRevisionIntegrationConnections` | List Connection instances for an integration slot on a Setup. | | `pinRevisionIntegrationConnection` | Pin a specific Connection to an integration slot on a Setup. | | `unpinRevisionIntegrationConnection` | Unpin a Connection from an integration slot on a Setup. | | `listRevisionIntegrationQueues` | List queues configured for an integration slot on a Setup. | | `replaceRevisionIntegrationQueues` | Replace the queues configured for an integration slot on a Setup. | | `getRevisionCaseQueueSetup` | Check that a Setup's case-queue slots each point at a queue. | | `listRevisionLogins` | List Logins attached to a Setup. | | `attachRevisionLogin` | Attach a Login to a Setup. | | `detachRevisionLogin` | Remove a Login from a Setup. | | `listRevisionSecrets` | List Secrets attached to a Setup. | | `attachRevisionSecret` | Attach a Secret to a Setup. | | `detachRevisionSecret` | Remove a Secret from a Setup. | | Tool | Description | | ------------------------ | --------------------------------------------------- | | `createSandbox` | Create a new sandbox environment. | | `createSandboxUploadUrl` | Generate a signed URL to upload files to a sandbox. | | `listSandboxFiles` | List files in a sandbox directory. | | `uploadSandboxFile` | Upload a file directly to a sandbox. | | Tool | Description | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `listMyTeams` | List teams the authenticated caller can act on. | | `getTeam` | Get your team's details. | | `listTeamMembers` | List members of your team. | | `listOrgTeams` | List all teams in an organization you belong to. | | `createOrgTeam` | Create a new team in an organization you administer. Requires an organization Admin, Executive, or Owner role. | | `inviteOrgMember` | Invite a person to an organization you administer, optionally assigning them to one of its teams. Requires an organization Admin, Executive, or Owner role. You cannot grant a role higher than your own. | | `listMyOrganizations` | List the organizations you belong to, with your role and member count in each. Use it to check for an organization admin role before calling org-scoped tools. | | `getOrgInsightsHeadline` | Get org-wide headline run KPIs (totals, success rate, active agents and users) across all teams in an organization. Requires an organization admin role. | | `getOrgInsightsMetrics` | Get per-team run/assignment/schedule metrics across an organization. Requires an organization admin role. | | `getOrgInsightsUsageChart` | Get org-wide run volume over time (scheduled vs on-demand) at day/week/month granularity. Requires an organization admin role. | | `getProfile` | Get your user profile. | Notification tools require the Notification Center feature and return a not-found error when it is not enabled for the team. | Tool | Description | | ---------------------------- | -------------------------------------------------------------------------------------------------- | | `listNotifications` | List notifications for the authenticated user, filterable by type, severity, unread, or important. | | `getNotification` | Get a single notification by ID. | | `getNotificationCounts` | Get notification counts broken down by type. | | `getUnreadNotificationCount` | Get the number of unread notifications. | | `markNotificationRead` | Mark a notification as read. | | `markAllNotificationsRead` | Mark all notifications as read. | | `dismissNotification` | Dismiss an important notification, unpinning it from the Important section. | | `deleteReadNotifications` | Delete all read notifications. Asks for confirmation before it runs. | | `deleteAllNotifications` | Delete all notifications. Asks for confirmation before it runs. | `deleteReadNotifications` and `deleteAllNotifications` permanently delete notifications and cannot be undone. Both are flagged as needing your approval, so a host that supports permission prompts asks you to confirm every call before the tool runs. | Tool | Description | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `listClarityProcesses` | List process captures for your team. | | `listClarityProcessSummaries` | List cross-process portfolio summaries (summary, SWOT, projected impact, steps). | | `createClarityProcess` | Create a Clarity process for the current team. | | `getClarityProcess` | Get a process capture by ID. | | `getClarityCapture` | Get one capture with full transcript. | | `getLegacyClarityProcess` | Get a legacy process capture by ID. | | `getClarityProcessTree` | Get the process landscape tree. | | `getClarityProcessLandscape` | Get the process landscape with nodes and links. Inaccessible folder rows and names are omitted. Restricted-only branches are summarized with a hidden-process count, and an anonymous `Restricted process` bridge row appears only when needed to preserve visible topology. Organization-wide generation status and eligible input counts are included only for organization Owners and Executives. | | `getClarityHierarchyPeople` | Get the people on every process in the landscape in one request, with their role, invitation status, and capture count. | | `generateClarityProcessLandscape` | Generate a process landscape from existing team processes, with optional capture context. | | `listClarityLandscapeCaptures` | List the organization's eligible process landscape captures. | | `createClarityLandscapeNode` | Create an area node in the process landscape. | | `updateClarityLandscapeNode` | Rename a landscape node or update its owner label. | | `deleteClarityLandscapeNode` | Delete a landscape node and its subtree. | | `setClarityLandscapeNodePlacement` | Move a landscape node and confirm its placement. | | `setClarityLandscapePriorities` | Set or clear heatmap priorities on landscape nodes in one batch (organization admin+). | | `proposeClarityLandscapeProcess` | Propose a new process in the process landscape. | | `listClarityExtraCaptureRequests` | List pending extra capture requests for a process. | | `listClarityProcessSnapshots` | List snapshots for a process capture. | | `getClarityProcessSnapshot` | Get a process capture snapshot. | | `listClarityProcessLinks` | List process-to-process links in Clarity. Edges touching inaccessible processes are omitted. | | `createClarityProcessLink` | Create a process-to-process link in Clarity. | | `updateClarityProcessLink` | Update a process-to-process link in Clarity. | | `deleteClarityProcessLink` | Delete a process-to-process link in Clarity. | | `listClarityProcessLabels` | List your organization's process tags with usage counts. | | `createClarityProcessLabel` | Create a process tag in your organization. | | `updateClarityProcessLabel` | Rename or recolor a process tag. | | `deleteClarityProcessLabel` | Delete a process tag from every process using it. | | `listClarityProcessAssignedLabels` | List the tags assigned to a process. | | `assignClarityProcessLabels` | Assign tags to a process (existing or new). | | `unlinkClarityProcessLabels` | Remove tags from a process. | | `listAvailableClarityProcessLabels` | List the organization tags available to a process. | Pulse dashboards are live, agent-generated visualizations of your Duvo data. Generation runs in the background — after creating or iterating on a dashboard, poll `getPulseDashboard` until its status is `completed`, then read its rendered HTML. | Tool | Description | | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `listPulseDashboards` | List your Pulse dashboards (your own, or those shared with you). | | `createPulseDashboard` | Create a dashboard from a natural-language prompt. Generation is asynchronous. | | `getPulseDashboard` | Get a dashboard's metadata and generation status. | | `getPulseDashboardHtml` | Get a dashboard's rendered HTML document. | | `getPulseDashboardPdf` | Render a dashboard to a PDF document (with its live data). | | `exportPulseDashboardHtml` | Render a dashboard to a self-contained static HTML snapshot (data baked in). | | `sendPulseDashboardMessage` | Send an instruction to iterate on a dashboard (creator only). Can carry attachments the agent will read. | | `createPulseDashboardAttachmentUploadUrl` | Get a presigned URL to upload a file (e.g. an HTML dashboard to reproduce, or a screenshot to match) into a dashboard's sandbox, then reference it from `sendPulseDashboardMessage`. Up to 25 MB per file and 5 files per message (requires edit access). | | `getPulseDashboardAttachmentDownloadUrl` | Get a short-lived URL to download a file attached to a dashboard message (requires edit access). | | `stopPulseDashboardMessage` | Stop an in-flight generation turn; no-op when nothing is generating (creator only). | | `refreshPulseDashboard` | Refresh a dashboard's Connection-sourced data in place, keeping the layout unchanged. Runs in the background (requires edit access). | | `updatePulseDashboard` | Rename a dashboard (creator only). | | `duplicatePulseDashboard` | Duplicate a dashboard into a new idle clone (creator only). | | `movePulseDashboard` | Move a dashboard to another team, keeping only its latest version (Manager+ on both teams; supports dry-run preview). | | `publishPulseDashboard` | Share a dashboard with your team (view or edit access), or revert it to private (creator only). | | `deletePulseDashboard` | Delete a dashboard (creator only). | | `listPulseDashboardVersions` | List a dashboard's version history, newest first (creator only). | | `restorePulseDashboardVersion` | Restore a previous version, making it live again (creator only). | | `getPulseDashboardVersionHtml` | Get a specific version's rendered HTML document (creator only). | | `listPulseDashboardMessages` | List a dashboard's chat transcript (requires edit access). | | `answerPulseDashboardQuestion` | Answer a pending question from the dashboard agent and resume the run (requires edit access). | | `listPulseDashboardConnections` | List the connections attached to a dashboard (creator only). | | `attachPulseDashboardConnection` | Attach one of your connections to a dashboard (creator only). | | `detachPulseDashboardConnection` | Detach a connection from a dashboard (creator only). | ## Related Set up a host before calling these tools. Exact request and response shapes for each tool. # Building an MCP Server for Duvo Source: https://docs.duvo.ai/mcp/building-mcp-servers Build a custom MCP server that Duvo can connect to. Covers transport, authentication, tool design, and deployment requirements. Building a Custom MCP server requires software development expertise. This page assumes familiarity with API development and deployment. If you're new to MCP, start with the [official MCP documentation](https://modelcontextprotocol.io/docs/getting-started/intro), which has tutorials and SDKs in multiple languages. To build an MCP server that Duvo can use, your server needs to meet a few technical requirements so Duvo can connect to it as a [custom MCP Connection](/mcp/custom-mcp-servers). This page covers transport, authentication, tool design, and deployment. For the user-facing setup steps in Duvo once your server is live, see the [Custom MCP connection page](/user-guide/connections/available-connections/custom-mcp). ## Requirements For Duvo to call your MCP server, it must meet these technical requirements: * **Cloud accessibility** — The server must be reachable over the public internet via HTTPS. Localhost and private-network-only endpoints are not supported. * **Streamable HTTP transport** — Duvo requires MCP's Streamable HTTP transport. Servers that only expose STDIO or the older HTTP/SSE transport cannot connect. * **Valid HTTPS certificate** — Self-signed certificates may fail to connect; use a certificate from a trusted CA. ## Authentication options Pick whichever method fits your deployment: * **None** — No auth. Use this only when the server handles auth at the network layer or genuinely has no auth surface. * **Static API key or token** — Each teammate enters their own key when they sign into the Connection. Duvo passes the key as a bearer token (or however your server expects it). * **Custom HTTP headers** — Each teammate provides their own header values when they sign in. Use this for any auth that doesn't fit "API key as bearer token". * **OAuth** — Recommended for multi-user deployments. Duvo detects [Dynamic Client Registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591) automatically; if your server supports DCR, teammates can connect with no Client ID/Secret setup at all. ### Implementing OAuth with DCR Supporting DCR is the most polished experience for Duvo users. The MCP server side typically needs: * A `GET /.well-known/oauth-protected-resource` endpoint declaring the authorization server (RFC 9728) * A `WWW-Authenticate: Bearer resource_metadata=...` challenge on 401 responses * A backing OAuth authorization server that implements [RFC 7591 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) If your authorization server doesn't support DCR, you can still use OAuth — teammates will enter a pre-registered Client ID and Client Secret when setting up the Connection, and you'll need to register Duvo's redirect URI (`https://platform.duvo.ai/v1/oauth/mcp/callback`) on your provider. ## Designing your tools A few practical guidelines that pay off when Duvo Agents call your tools: * **Describe every tool clearly.** The description is what an Agent sees when deciding whether to call it. * **Use flat input schemas.** A single top-level object reads better than wrapping params in `query`, `body`, etc. * **Return structured data when possible** (JSON, not just human-readable strings). The Agent can pick out the field it needs without re-parsing. * **Surface errors as proper MCP errors** rather than 200 responses with an error string in the body. Duvo's Agents can retry or escalate more reliably this way. * **Idempotency keys** on destructive operations are a good defense against accidental double-calls. ## Hosting You're free to host MCP servers wherever you like — Cloud Run, Lambda + API Gateway, Fly, a VM, a managed PaaS, your own Kubernetes cluster. Anything that can expose a public HTTPS endpoint works. For small-scale deployments, a single container behind a TLS-terminating load balancer is usually enough. Add caching where it helps, and rate-limit defensively if the underlying system is sensitive to bursts. ## After deploying Once your server is running publicly: Open the [Connections page](https://app.duvo.ai/integrations) in Duvo. Click **Add custom connection** at the bottom of the catalog. Pick your auth method, enter the server URL, and click **Create**. Each teammate signs into the new Connection with their own credentials. For the full UI walkthrough, see [Custom MCP](/user-guide/connections/available-connections/custom-mcp). ## Related Add your finished server to Duvo as a Connection Full setup walkthrough Protocol spec, SDKs, and reference servers # Connect a custom MCP to Duvo Source: https://docs.duvo.ai/mcp/custom-mcp-servers Bring your own MCP server into Duvo as a Connection. Let agents call tools from internal systems, legacy platforms, or custom APIs alongside built-in connections. To connect an MCP server to Duvo, add it as a **Custom MCP Connection**. Your Duvo Agents can then call its tools from an MCP server you host — use this when a built-in Connection doesn't cover the system you need (internal tools, legacy platforms, custom-built APIs) and you'd rather expose those tools via MCP than build a one-off integration. To Duvo, a Custom MCP Connection looks like any other Connection. Your Agent's Setup picks tools from your MCP server alongside tools from Gmail, Slack, or Snowflake. If you haven't built the server yet, see [Build an MCP server for Duvo](/mcp/building-mcp-servers) first. If instead you want to drive Duvo from an MCP host, see [The Duvo MCP server](/mcp/duvo-mcp-server). ## When to use a Custom MCP Connection * You have a proprietary internal system (CRM, warehouse API, internal tool) that isn't a built-in Duvo Connection. * You've already built or can build an MCP server for that system. * You want consistent setup across teammates — add the Connection once, every teammate can connect with their own credentials. If you want to drive Duvo from an MCP host instead, see [The Duvo MCP server](/mcp/duvo-mcp-server). ## What you need to bring * **A deployed MCP server** accessible over the internet via a public HTTPS URL. Localhost is not supported. * **Streamable HTTP transport.** Servers that only support STDIO or HTTP/SSE cannot connect. * **Your authentication method** — Custom MCP supports no-auth, API key, custom HTTP headers, and OAuth (with automatic Dynamic Client Registration where available). ## Setup at a glance Full step-by-step instructions live on the Custom MCP Connection page: [Custom MCP](/user-guide/connections/available-connections/custom-mcp). The short version: Open the [Connections page](https://app.duvo.ai/integrations) in Duvo and click **Add custom connection**. Give the Connection a recognizable name (for example, "Internal CRM"). Pick an authorization method (None, API key, custom headers, or OAuth). Enter your server's public HTTPS URL. Click **Create**. Teammates then sign into the Connection individually with their own credentials. ## OAuth support If your MCP server uses OAuth, Duvo automatically detects whether it supports **Dynamic Client Registration (DCR, [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591))**: * **DCR-capable servers** — Duvo registers itself automatically. No Client ID or Secret required. * **Servers without DCR** — Provide your own Client ID and Client Secret in the **Advanced settings** when setting up the Connection. Duvo displays the redirect URI you need to register on your OAuth provider. You can also force the manual path if you'd rather use a pre-registered OAuth app instead of auto-registration. ## Related The detailed setup walkthrough with every field and option What to consider when implementing the server itself The other direction: connect MCP hosts to Duvo # Connect to the Duvo MCP server Source: https://docs.duvo.ai/mcp/duvo-mcp-server Connect Claude Desktop, Cursor, or ChatGPT to the Duvo MCP server. Every Public API endpoint becomes an LLM-callable tool. Connecting an MCP host to the Duvo MCP server is the main way teams use MCP with Duvo — it's the conversational counterpart to the [Duvo CLI](/cli). Duvo exposes a hosted MCP server at `https://api.duvo.ai/v2/mcp`. Connect to it from any MCP-compatible host — Claude Desktop, Cursor, ChatGPT connectors, your own client — and every Duvo [Public API](../api-reference) endpoint becomes a tool the host can call. Use this to: * Drive Duvo Agents from an AI assistant chat ("Start the invoice processor on yesterday's batch and tell me when it's done.") * Inspect Runs, Cases, and Files conversationally * Build hybrid workflows where one assistant orchestrates Duvo Agents alongside other tools ## What you can do Every endpoint registered in the [Public API](../api-reference) is auto-exposed as an MCP tool. That includes: * **Agents** — list, get, create, update * **Runs** — start, get status, send messages, respond to human-in-the-loop requests, stop * **Connections** — list and inspect your authorized accounts * **Files** — list, read, write, rename, delete * **Cases and Queues** — inspect, delegate, label * **Skills, Plugins, Sandboxes** — list and reference See the full list of available tools on the [Available MCP Tools](/mcp/available-tools) page. When Duvo ships a new Public API endpoint, it automatically becomes an MCP tool on the next deploy. There's no separate maintenance step. ## Server URL ``` https://api.duvo.ai/v2/mcp ``` The server uses MCP's **Streamable HTTP** transport (`POST /v2/mcp`). Most modern MCP hosts support this transport out of the box. The earlier `https://api.duvo.ai/v1/mcp` endpoint still works, so existing setups keep running unchanged. New connections should use `/v2/mcp`. ## Authentication The Duvo MCP server accepts two credential types: ### Option 1 — OAuth (recommended for personal use) Recommended for hosts that prompt you to sign in (Claude Desktop, Cursor, ChatGPT connectors). The host runs a one-time browser-based sign-in to Duvo, then handles token refresh and revocation for you. No API key to copy or rotate. The exact steps depend on the host. In general: Add `https://api.duvo.ai/v2/mcp` as the MCP server URL in your host's settings. The host detects the OAuth challenge and opens a browser tab to Duvo's sign-in page. Sign in and approve the connection. The host stores the OAuth tokens and uses them automatically on every tool call. Duvo's MCP server publishes its OAuth metadata at `https://api.duvo.ai/.well-known/oauth-protected-resource/v2/mcp` (RFC 9728). Compliant MCP hosts use this to discover the authorization server and register themselves via [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) automatically. ### Option 2 — API key (recommended for scripts and service accounts) Use API keys when the host doesn't support OAuth, or for non-interactive use (CI, service accounts). Generate a key in the Duvo dashboard at [Your Profile → API keys](https://app.duvo.ai/settings/profile#api-keys), scoped to a single team or to all teams you can access. Users with the Manager role or above can also create a team's keys at [Team Settings → API keys](https://app.duvo.ai/settings/api-keys). Configure the MCP host to send the key as a bearer token in the `Authorization` header: ``` Authorization: Bearer ``` The host can then call Duvo MCP tools without any further sign-in. API keys are scoped to a single team or to all teams the owner can access, and inherit the permissions of the user who generated them. ## Setup by host The MCP standard means the same Duvo URL works in every compliant host. Configuration syntax differs slightly between products, so check your host's MCP setup guide for the exact field names. Common patterns: Edit your Claude Desktop config (`claude_desktop_config.json`): ```json theme={"dark"} { "mcpServers": { "duvo": { "url": "https://api.duvo.ai/v2/mcp" } } } ``` Restart Claude Desktop. When you mention Duvo or use a tool from the connector, Claude Desktop opens a browser tab for OAuth sign-in. Add the Duvo server from your terminal with the `claude mcp add` command: ```bash theme={"dark"} claude mcp add --transport http duvo https://api.duvo.ai/v2/mcp ``` The first time you call a Duvo tool, Claude Code runs the browser-based OAuth sign-in. To use an API key instead (for CI or service accounts), pass it as a bearer header: ```bash theme={"dark"} claude mcp add --transport http duvo https://api.duvo.ai/v2/mcp \ --header "Authorization: Bearer " ``` In Cursor settings, open the MCP servers section, add a new server with the URL `https://api.duvo.ai/v2/mcp`, and let Cursor run the OAuth flow. Add a Custom Connector pointing to `https://api.duvo.ai/v2/mcp`. ChatGPT handles Dynamic Client Registration and the OAuth flow automatically. Any MCP-compatible client library (TypeScript, Python, etc.) can connect — point it at `https://api.duvo.ai/v2/mcp`, supply either an OAuth token or an API key, and call `tools/list` to discover what's available. ## Tool ergonomics Tools follow the underlying Public API: * Tool names map to OpenAPI `operationId`s (for example, `listAgents`, `startRun`, `getConnection`). * Tool descriptions come from each endpoint's OpenAPI description. * Input schemas are flat — path parameters, query parameters, and request body are merged into a single object so calls read naturally (`startRun({ agent_id: "...", input: "..." })` rather than wrapping each section). * Responses match the corresponding API response. Use the [Public API Reference](../api-reference) for the exact shapes. ## Limits and behavior * All Public API rate limits apply to MCP tool calls. * Every tool call respects the permissions of the authenticating user, just like a direct API call. * Long-running Runs are not streamed over MCP today — start the Run via the tool, then poll `getRun` or `listRunMessages` to monitor progress. ## Troubleshooting **401 Unauthorized** — Your token is missing, expired, or for a different audience. Re-run OAuth, or regenerate the API key in the dashboard. **403 Forbidden** — Your account doesn't have permission to call this endpoint. Check your team role and Connection permissions. **OAuth doesn't open a browser** — The host may not support Dynamic Client Registration. Fall back to API key authentication, or check the host's docs for OAuth setup steps. ## Privacy and terms * [Privacy Policy](https://www.duvo.ai/privacy-policy) — how Duvo handles data accessed through the MCP server. * [Terms of Use](https://www.duvo.ai/terms-of-use) — the terms that apply to Duvo API and MCP usage. For platform-wide details (SOC 2 certification, encryption, Anthropic Zero Data Retention, sub-processors), see [Security & Privacy](/user-guide/resources/security-and-privacy). ## Related The full catalog of tools this server exposes. The other direction: bring your own MCP server into Duvo. The API the Duvo MCP server wraps. Terminal-first wrapper over the same API. # Embedding Duvo as a Callable Tool in Your AI System Source: https://docs.duvo.ai/mcp/embedding-duvo Register Duvo Agents as callable tools your own AI agent or copilot invokes through the Duvo MCP server — your agent orchestrates, Duvo handles the operational task. If you're building your own AI agent, copilot, or workflow runner, you can register individual Duvo Agents as callable tools that your agent invokes when its work enters Duvo's domain. Your agent stays in control of the overall workflow — Duvo handles the specific operational task and hands the result back. ## When to embed Duvo vs. build the capability yourself | Embed Duvo when… | Build natively when… | | -------------------------------------------------------------- | --------------------------------------------------------- | | The task already exists as a configured Duvo Agent | The task is simple and doesn't need connections or HITL | | The task involves approvals, sensitive systems, or audit needs | Latency is critical and a Run round-trip isn't acceptable | | Non-developers need to maintain the task's AOP | You want full control over the execution environment | | The task spans multiple Connections (Gmail + Sheets + Slack…) | The task has no human-in-the-loop requirement | **Common patterns:** * An editor-agent reviews a document and delegates any compliance action to a Duvo Agent. * A customer copilot triages a request and hands a regulated branch (refund, escalation) to Duvo, where a human can approve it. * An internal AI workbench catalogs Duvo Agents as named skills and routes work to them by category. ## How it works Your agent connects to the Duvo MCP server (`https://api.duvo.ai/v2/mcp`). Every Duvo [Public API](/api-reference) endpoint is auto-exposed as an MCP tool. Your agent calls those tools to start Runs, poll for completion, respond to human-in-the-loop requests, and collect results — all through a standard MCP interface. ``` Your agent └─► Duvo MCP server (https://api.duvo.ai/v2/mcp) └─► Duvo Agent (Runs, Connections, HITL) └─► Result returned to your agent ``` For a guide on connecting your MCP host to the Duvo MCP server and authenticating, see [The Duvo MCP server](/mcp/duvo-mcp-server). ## Scoping which Agents your agent can call The Duvo MCP server exposes tools for the full Public API. Your agent can call `listAgents` to discover all Agents visible to its API key, then filter by name or ID to invoke specific ones. **Narrowing scope with API keys:** Each API key is scoped to a team and inherits the permissions of the user who created it. To limit a parent agent to a subset of Agents, create a dedicated Duvo user with access only to the relevant Agents and generate an API key for that user. This prevents the parent agent from accidentally discovering or starting Agents it shouldn't touch. **Discovering Agents at startup:** ```python theme={"dark"} # MCP tool call — exact syntax depends on your MCP client library tools_result = mcp_client.call_tool("listAgents", {"limit": 50}) agents = tools_result["agents"] ``` ## How an Agent appears as a tool When your agent calls `listAgents`, each Agent is returned with metadata your agent can use to decide which one to invoke. Here is a trimmed example of the response (additional fields omitted for brevity): ```json theme={"dark"} { "agents": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "Process Refund Request", "team_id": "string", "created_at": "string", "updated_at": "string", "last_run_at": "string", "created_by": { "id": "string", "name": "string", "email": "string" }, "latest_build": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "revision_name": "string", "revision_description": "string", "revision_number": 0, "status": "string" }, "integration_configs": [ { "integration_id": "string", "integration_type": "string", "integration_name": "string", "is_connected": true } ] } ], "total": 0, "limit": 50, "offset": 0 } ``` The key fields your agent needs are `id`, `name`, and `latest_build.revision_description`. The name and description come from what was entered in the Duvo dashboard — edit them there to make the Agent self-describing for your agent. **Tips for writing agent-friendly Agent metadata:** * **Name**: use a verb phrase — "Process Refund Request", "Triage Support Ticket", "Update Inventory Record". * **Revision description** (`latest_build.revision_description`): explain the input the Agent expects and the output it produces — "Takes a customer complaint email body. Returns a triage decision (escalate / auto-resolve / needs-more-info) with a one-sentence rationale." The Agent's AOP governs what the agent actually does. The name and description only affect how clearly your parent agent can decide when to call it. ## Invocation patterns All Run endpoints are on the base URL `https://api.duvo.ai/v2`. Starting a Run is team-scoped (`POST /teams/{team_id}/runs`); reading and responding to a Run is addressed by `run_id`. Start a Run, then poll `getRun` until the status is `completed`, `failed`, or `stopped`. Suitable for short-running Agents (under a few minutes). ```python theme={"dark"} import time import httpx BASE_URL = "https://api.duvo.ai/v2" API_KEY = "dv_your_key_here" TEAM_ID = "your-team-id" headers = {"Authorization": f"Bearer {API_KEY}"} # 1. Start the Run run_resp = httpx.post( f"{BASE_URL}/teams/{TEAM_ID}/runs", headers=headers, json={ "agent_id": "your-agent-id", "message": "Process refund request for order #99182. Customer says item never arrived.", }, ) run_id = run_resp.json()["run"]["id"] # 2. Poll for completion while True: status_resp = httpx.get(f"{BASE_URL}/runs/{run_id}", headers=headers) status = status_resp.json()["run"]["status"] if status in ("completed", "failed", "stopped"): break time.sleep(5) # 3. Retrieve messages messages_resp = httpx.get(f"{BASE_URL}/runs/{run_id}/messages", headers=headers) result = messages_resp.json()["messages"] ``` Provide a `webhook_url` when starting the Run. Duvo POSTs to that URL on state changes (`run_completed`, `run_failed`, `run_interrupted`) and when the Agent needs input (`human_request`), so your agent doesn't have to poll. Filter on the payload's `event` field for the case you care about. ```python theme={"dark"} run_resp = httpx.post( f"{BASE_URL}/teams/{TEAM_ID}/runs", headers=headers, json={ "agent_id": "your-agent-id", "message": "...", "webhook_url": "https://your-agent.example.com/duvo/events", }, ) ``` A human-input event looks like this: ```json theme={"dark"} { "event": "human_request_created", "run_id": "550e8400-...", "request_id": "req_789xyz", "title": "Confirm data deletion", "description": "About to delete 150 records. Confirm?" } ``` Respond when ready: ```python theme={"dark"} httpx.post( f"{BASE_URL}/runs/{run_id}/human-requests/{request_id}/respond", headers=headers, json={"approved": True}, ) ``` When Duvo reaches a step that requires human approval, the Run's status changes to `waiting`. If your parent agent is polling, it detects this status and can either: * **Forward the request to a human** — surface the `title` and `description` from `getRun`'s `pending_human_request` field in your agent's own UI or chat thread, then relay the human's answer back via `respondToHumanRequest`. * **Respond programmatically** — if your agent has enough context to make the decision itself, it can call `respondToHumanRequest` directly without surfacing it to a human. ```python theme={"dark"} # Detect waiting status during poll if status == "waiting": # The pending HITL request is embedded in the getRun response run = httpx.get(f"{BASE_URL}/runs/{run_id}", headers=headers).json()["run"] req = run.get("pending_human_request") if req: # Surface to your user / decide programmatically approved = ask_operator(req["title"], req["description"]) httpx.post( f"{BASE_URL}/runs/{run_id}/human-requests/{req['id']}/respond", headers=headers, json={"approved": approved}, ) ``` ## Trust and guardrails **What the parent agent can't do:** * The parent agent operates under the permissions of its API key. It cannot bypass Connection-level authorization — if the Agent uses a Gmail Connection that the API key's user can't access, the Run will fail with a permissions error. * The parent agent cannot modify the Agent's AOP or Connections through an MCP tool call without the corresponding write endpoints, which should be locked down for service accounts. **Audit trail:** Every Run started via the API is recorded with the API key's user identity in the Duvo audit log. If multiple parent agents share the same key, their Runs are indistinguishable. Create separate API keys per parent agent to maintain a clean audit trail. See [Audit Log and Activity Tracking](/user-guide/security/audit-log) for how to export and query the log. **High-risk actions:** Agents that take irreversible actions (send emails, delete records, submit transactions) should have Human-in-the-Loop gates in their AOP. A parent agent that responds to HITL requests programmatically bypasses those gates — only do this if your agent has verified the action is safe. See [Guardrails for High-Risk Automations](/user-guide/security/high-risk-guardrails) for the full risk framework. **Rate limits:** All Public API rate limits apply to MCP tool calls: 5,000 requests per minute per API key. Long-polling loops should still sleep between polls (5-30 seconds) to avoid burning through quota during busy periods. ## End-to-end example: email triage with a human approval gate A parent agent monitors an inbound email queue. When it receives a complaint that touches a financial policy, it delegates to a Duvo Agent, waits for a human to approve the proposed response, then sends the final email. ```python theme={"dark"} import time import httpx BASE_URL = "https://api.duvo.ai/v2" API_KEY = "dv_your_key_here" TEAM_ID = "your-team-id" TRIAGE_AGENT_ID = "agent_triage_abc123" headers = {"Authorization": f"Bearer {API_KEY}"} def handle_complaint(email_body: str) -> str: """ Parent agent detects a financial complaint, delegates to Duvo, surfaces the HITL approval, and returns the final outcome. """ # 1. Start the Run — Duvo will draft a response and request approval run_resp = httpx.post( f"{BASE_URL}/teams/{TEAM_ID}/runs", headers=headers, json={ "agent_id": TRIAGE_AGENT_ID, "message": f"Inbound complaint: {email_body}", }, ) run_id = run_resp.json()["run"]["id"] print(f"Run started: {run_id}") # 2. Poll for completion or HITL pause while True: run = httpx.get(f"{BASE_URL}/runs/{run_id}", headers=headers).json()["run"] status = run["status"] if status == "completed": # Retrieve final messages from Duvo msgs = httpx.get(f"{BASE_URL}/runs/{run_id}/messages", headers=headers) return msgs.json()["messages"][-1]["text_content"] if status in ("failed", "stopped"): raise RuntimeError(f"Run ended with status: {status}") if status == "waiting": # 3. Surface the HITL request to an operator req = run.get("pending_human_request") if req: print("\n--- Approval needed ---") print(f"Title: {req['title']}") print(f"Details: {req['description']}") decision = input("Approve? (y/n): ") httpx.post( f"{BASE_URL}/runs/{run_id}/human-requests/{req['id']}/respond", headers=headers, json={"approved": decision.lower() == "y"}, ) time.sleep(5) result = handle_complaint( "I was charged twice for my order #99182. I need a refund immediately." ) print(f"\nOutcome: {result}") ``` **What happens step by step:** The parent agent starts a Run on the "Complaint Triage" Agent with the raw email body. Duvo's Agent reads the complaint, connects to the order system via its configured Connection, drafts a refund proposal, and pauses — asking an operator to approve before sending. The parent agent detects `waiting`, fetches the HITL request, and surfaces the draft to an on-call operator (via a chat message, Slack notification, or UI). The operator approves or rejects. The parent agent relays that decision back to Duvo. Duvo sends the approved response and marks the Run `completed`. The parent agent reads the final result and continues its own workflow. ## Related How to configure authentication and connect any MCP-compatible host The inverse direction: bring your own tools into Duvo Agents Full API reference for Runs, messages, and HITL responses Risk framework for delegating irreversible actions How to trace which agent started which Run # How MCP works on Duvo Source: https://docs.duvo.ai/mcp/overview Understand the two directions Duvo speaks MCP — driving Duvo from an MCP host like Claude Desktop, Claude Code, Cursor, or ChatGPT, and bringing your own MCP servers into Duvo as Connections. The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI assistants and platforms exchange tools, context, and data. Duvo speaks MCP in **two directions**, and this section of the docs is organized around them. If you're new to MCP, the [official MCP documentation](https://modelcontextprotocol.io/docs/getting-started/intro) is a good starting point. ## The two directions ### 1. Drive Duvo from an MCP host — the Duvo MCP server Duvo runs a hosted MCP server. Connect a host like Claude Desktop, Claude Code, Cursor, or ChatGPT to it, and every Duvo Public API endpoint becomes a tool that host can call — start Runs, inspect Cases, manage Files, all from an assistant chat. This is the main way teams use MCP with Duvo, and it's the counterpart to the [Duvo CLI](/cli): another way to operate Duvo from outside the dashboard. Start here: **[The Duvo MCP server](/mcp/duvo-mcp-server)**. ### 2. Bring your own MCP into Duvo — Custom MCP Connections Run an MCP server of your own — for an internal system, a legacy platform, or a custom API — and add it to Duvo as a Connection. Your Agents then call its tools alongside built-in Connections like Gmail or Snowflake. Start here: **[Connect a custom MCP to Duvo](/mcp/custom-mcp-servers)**, and **[Build an MCP server for Duvo](/mcp/building-mcp-servers)** if you're implementing the server yourself. ## Which direction do you need? Drive Duvo from Claude Desktop, Claude Code, Cursor, ChatGPT connectors, or another host. See exactly which Duvo actions are available as MCP tools. Call Duvo Agents as tools from your own AI agent or copilot. Let your Duvo Agents call tools from a custom internal system. Build an MCP server from scratch to expose your own tools. ## The two directions at a glance | | Duvo as MCP server | Custom MCP Connections | | --------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------- | | **Who runs the server** | Duvo | You | | **Endpoint** | `https://api.duvo.ai/v2/mcp` | A public HTTPS URL you provide | | **What tools it exposes** | Every Duvo Public API endpoint | Whatever your MCP server implements | | **Who's the client (host)** | Claude Desktop, Claude Code, Cursor, ChatGPT connectors, or any MCP-compatible app | Duvo Agents | | **Authentication** | OAuth or API key | None, API key, custom headers, or OAuth (DCR-aware) | | **Setup time** | Minutes — paste the URL into your MCP host | Minutes once your server is deployed and reachable | ## How MCP fits alongside the CLI and API MCP is one of three ways to drive Duvo from outside the dashboard, all built on the same [Public API](/api-reference): * **The Duvo MCP server** is a thin layer over the Public API — the same authentication, rate limits, and permissions apply. Best when you want to operate Duvo conversationally from an AI host. * **The [Duvo CLI](/cli)** wraps the same API for terminal-first and CI/CD workflows. * **The [Public API](/api-reference)** itself is the foundation both build on — use it directly when you're writing your own integration. Custom MCP Connections are different: they don't drive Duvo, they extend what your Agents can do. They appear in the dashboard alongside other Connections, and Agents use them the same way they use Gmail or Slack. ## Related Connect a host and start calling Duvo tools. Custom MCP in the Available Connections catalog. The API both the MCP server and CLI wrap. # Agent Versions Source: https://docs.duvo.ai/user-guide/advanced/assignment-versions Duvo saves a version of an agent each time you change it, so you can iterate safely, track changes, and revert. ## Introduction Duvo maintains versions of your agents as you make changes. This allows you to iterate safely, test modifications, and understand how your agents have evolved over time. *** ## How Versioning Works Every time you make significant changes to an agent and save, Duvo creates a new version. This means: * Your previous configuration is preserved * You can see how the agent has changed * Recent changes can be reviewed and understood ```mermaid theme={"dark"} stateDiagram-v2 [*] --> Live: Save first version Live --> NewRevision: Make changes and save NewRevision --> Live: New revision becomes live Live --> ViewingOlder: Open an older revision ViewingOlder --> NewRevision: Create a new revision based on it ViewingOlder --> Live: Return to the live revision ``` *** ## Why Versions Matter ### Safe Iteration Versioning lets you improve agents with confidence: * Make changes without fear of losing working configurations * Test modifications knowing you can reference previous versions * Iterate quickly without extensive documentation ### Change Tracking Understand how agents have evolved: * See what changed between versions * Track who made modifications * Understand the history of an agent ### Troubleshooting When something stops working: * Compare current version to previous working versions * Identify what changed * Understand what might have caused issues *** ## Working with Versions ### Viewing Version History To see an agent's version history: Open the agent. Click the revision selector in the builder toolbar. Review the list of saved revisions and select one to view. ### Non-Live Revision Warning When you open an older revision that is not currently live, a warning banner appears at the top of the builder: **You are viewing a non-live revision.** Scheduling and triggers run the latest revision, not this one. This means: * Runs started manually while viewing this revision will use its configuration * Scheduled runs and trigger-based runs always use the **live** revision, regardless of which revision you are currently viewing * To make an older revision live, create a new revision based on it or use it as a starting point for your next changes ### Understanding Changes Each version captures: * AOP and configuration * Connected connections * Skills and files attached * Settings and options ### Building on Previous Work When creating similar agents: * Review successful agents for patterns * Understand what configurations work well * Apply learnings to new automation *** ## Best Practices ### Make Meaningful Changes Group related changes together rather than saving after every small edit. This creates cleaner version history. ### Test Before Major Changes Before significantly modifying a working agent: Verify the current version is working. Make your changes. Test thoroughly before relying on the new version. ### Document Significant Updates When making important changes, consider: * Updating the agent description * Noting why changes were made * Recording expected improvements ### Regular Review Periodically review your agents: * Are they still meeting needs? * Have requirements changed? * Is the configuration still optimal? *** ## Version Management Tips ### Keeping Agents Current * Review agents when connected systems change * Update when business processes evolve * Refresh when better approaches become available ### Managing Multiple Agents For teams with many agents: * Use consistent naming conventions * Group related agents logically * Document dependencies between agents ### Coordinating Changes When multiple people work on agents: * Communicate about planned changes * Avoid simultaneous modifications * Review changes made by others *** ## Things to Know * Revisions are created automatically when you save changes * Scheduling and triggers always run the **live** revision, even if you are currently viewing an older one * A warning banner appears whenever you open a non-live revision so you always know which revision you are looking at * Version history helps you understand agent evolution * Major changes should be tested before deployment # Model Selection Source: https://docs.duvo.ai/user-guide/advanced/model-selection Choose which AI model powers an agent and match model strengths to your task for better performance. ## Introduction Duvo allows you to choose which AI model powers your agents. Different models have different strengths, and selecting the right one can improve your agent's performance for specific tasks. *** ## Why Model Selection Matters Different AI models excel at different types of tasks: * **Complex reasoning** - Some models are better at multi-step logic and analysis * **Speed** - Faster models are ideal for simple, high-volume tasks * **Specialized tasks** - Certain models perform better with code, data, or creative content Choosing the right model helps you get better results and optimize performance. *** ## Available Models You can pick from three models when configuring an agent: * **Claude Opus 5** - Most capable for the hardest reasoning and long, complex work * **Claude Sonnet 5** - Balanced everyday model for most agents * **Claude Haiku 4.5** - Fastest model for simple, high-volume tasks *** ## How to Select a Model ### When Building an Agent Open the agent you're building or editing. Find the Model selection option in the configuration. Choose from the available models. Save your changes. ### Changing Models Later You can change an agent's model at any time: Open the agent. Edit the configuration. Select a different model. Save and test the changes. *** ## Choosing the Right Model ### For Complex Analysis When your agent needs to: * Analyze detailed documents * Make nuanced decisions * Handle multi-step reasoning * Process complex instructions Choose a more capable model that excels at reasoning. ### For Simple Tasks When your agent needs to: * Perform straightforward data entry * Execute simple, repetitive actions * Handle high-volume processing * Complete quick lookups A faster model may be more efficient. ### For Specialized Work Consider the nature of your task: * **Document work** - Models with strong comprehension * **Data processing** - Models good with structured information * **Communication** - Models that write naturally *** ## Best Practices ### Start with Defaults The default model works well for most tasks. Only change if you have a specific reason. ### Test Before Committing When changing models: Run test executions with the new model. Compare results to previous runs. Verify the agent still works correctly. Monitor for any issues after switching. ### Match Model to Task Don't assume more capable always means better: * Simpler models can be faster and more efficient * Complex models may be overkill for basic tasks * The right fit depends on your specific needs ### Document Your Choice If you select a specific model for a reason, note why in the agent description. This helps future maintenance. *** ## Things to Know * Model availability may vary based on your plan * Changing models doesn't affect past run history * Some tasks may perform differently with different models * Model capabilities are continuously improved * Default selections are optimized for general use # Pulse Source: https://docs.duvo.ai/user-guide/analytics/pulse Create live, custom dashboards of what's happening across Duvo — described in your words, built by an assistant. Pulse lets you build live, custom dashboards of what's happening across Duvo — your Agents, Runs, Queues, and Cases, plus data from your Connections — just by describing what you want to see. Instead of exporting data to a spreadsheet or waiting on a fixed report, you start a conversation, tell Pulse the view you need, and it builds an interactive dashboard for you in seconds. Pulse is for anyone who wants a custom view of their Duvo data without exporting it or asking someone to build a report — any team member with Member access or above can create a Pulse dashboard, then share it so teammates can view or refine it. Your Duvo data — Agents, Runs, Queues, and Cases — is read live, so a dashboard reflects what's happening right now each time it opens. Data pulled from a Connection (such as Gmail or Slack) is captured as a snapshot when the dashboard is built or updated, and refreshes when you ask Pulse to update it. ## Key Capabilities * **Describe what you want in plain language** — ask for "open Cases by queue this week" or "agent success rate over time" and Pulse builds the view. * **Live Duvo data** — your Agents, Runs, Queues, and Cases refresh every time a dashboard opens, so it stays current on its own. * **Connection data on demand** — data from Connections like Gmail or Slack is captured as a snapshot when you build or update a dashboard, and refreshes when you ask. * **Iterate by chatting** — refine any dashboard by continuing the conversation ("make it a bar chart", "filter to the last 14 days"). * **Share with your team** — publish a dashboard so teammates can view it, or let them refine it too. * **Permission-aware** — a shared dashboard only ever shows each viewer the data their own account is allowed to see. * **Approve without leaving the dashboard** — ask for an approvals view and you can approve or reject case approvals, and answer an Agent's questions, right on the page. See [Approving from a dashboard](#approving-from-a-dashboard). ## How to Create a Pulse Click **Pulse** in the left sidebar. Click **New Pulse**. You'll land on a split view — an empty canvas on the left and a chat composer on the right. In the chat, describe what you want to see. For example: *"Show me open Cases by queue for the last 7 days."* Pulse may ask a clarifying question, or it may have enough to work with and start building right away. Watch the dashboard appear on the left as it's generated. Pulse also gives it a title based on your first request. The dashboard is live — it fetches data directly from Duvo each time it loads. ## How to Refine a Pulse You shape a dashboard entirely through conversation — there's no code or settings to edit by hand. Open the Pulse you want to change. In the chat panel on the right, describe the change — for example, "group this by agent instead", "switch to a line chart", or "only show the last 30 days". The dashboard on the left updates to reflect your request. Keep chatting until the view is right. The conversation is saved, so you can scroll back to see what you asked for. Use the element picker to point Pulse at a specific part of the dashboard before you ask for a change — this helps it target exactly the piece you mean. If a change can't be generated, the previous version stays on screen and the chat shows an error you can retry from — you won't lose your working dashboard. ### Attaching a file Sometimes it's easier to show Pulse what you want than to describe it. Click the paperclip — on the new-Pulse screen, or in the chat panel of an existing one — to attach a file. In the chat panel you can also drop a file straight onto it. Pulse reads the file and works from its actual contents. Attaching on the new-Pulse screen means the very first dashboard is built from your file, rather than built first and corrected afterward. This is useful for: * **Matching an existing dashboard** — attach an HTML export and ask for "the same layout, using our data". * **Copying a design** — attach a screenshot or image of a chart you like. * **Bringing in a reference** — attach a CSV, JSON, PDF, or spreadsheet you want the dashboard to reflect. Attach up to **5 files per message**, each up to **25 MB**. Any file type is accepted. You can also attach files from the [Duvo CLI](/cli). Use `duvo pulse send-message --message "..." --attach-file ` to send a message with attachments (the `--attach-file` flag is repeatable), `duvo pulse attach ` to stage a file for later use and print its attachment id, or `duvo pulse attachment-url ` to fetch a short-lived download URL. The same 5-files-per-message and 25 MB-per-file limits apply. Attachments live alongside the dashboard's working session and are cleared after about 12 hours. The dashboard Pulse builds from them is permanent — only the uploaded file itself expires. If you come back the next day and want to reference the same file, attach it again. ## Renaming a Pulse The title sits at the top of the dashboard and is editable inline. Click it, type a new name, and press **Enter** or click away to save. ## Refreshing a Pulse's data For a team-owned Pulse, the creator can use **Connections** in the dashboard header to add or remove up to 10 OAuth or custom Connections. Organization-level Pulses do not support Connections. Attached Connections are available the next time you refine or refresh the dashboard. Your Duvo data is always live, but data from Connections is a snapshot taken when the dashboard was last built or refreshed. To bring those numbers up to date, click **Refresh data** in the dashboard header. Pulse re-fetches the data from every connected source and updates the dashboard in place — the layout and design stay exactly as they are. A refresh runs quietly in the background: a new version is saved and the canvas updates when it finishes, without adding a message to the chat. Anyone who can edit the Pulse can refresh it. ## Approving from a dashboard Pulse dashboards mostly show you what's happening. There is one thing you can also *do* from them: when an Agent has paused a Case to ask a human to approve how it's handling that Case, you can approve or reject right on the dashboard instead of opening [Requests](/user-guide/assignment-features/requests). Ask for it in plain language when you create or refine a Pulse — "a dashboard of the case approvals waiting on me, with Approve and Reject buttons" — and the page comes back with a working control on each row. ### What you can act on Approve or reject the decision an Agent asked you to bless. Every approver named on the request gives their own answer, and the Run stays paused until all of them have answered — so approving on the dashboard is exactly the same as approving from Requests or the Case page. When an Agent asked an open-ended question rather than for a decision, the row shows a text box you can answer in. When an Agent needs a Login for a site, the request appears on the dashboard but can't be answered there, because adding a Login isn't something a dashboard can do. Open [Requests](/user-guide/assignment-features/requests) to answer those. ### Who can approve what A dashboard never grants access you don't already have — it's the same permissions as the rest of Duvo, so two people opening the same Pulse can see different buttons: | You are | You can answer | | --------------------------------------- | ---------------------------------------- | | The person the approval was assigned to | Your own requests | | The person who started the Run | Any request on that Run's Case | | A team Superadmin or Owner | Any request on your team's Cases | | Anyone else who can see the Case | Nothing — the request shows as read-only | A decision is final — there's no undo. If someone else answers a request before you do, your dashboard shows their decision instead of the buttons the next time it loads. A dashboard never decides for you. It won't pre-select an answer, approve anything on its own when the page opens, or offer an "approve all" button — each decision is one deliberate click. If you want approvals handled automatically under a rule, that belongs in the Agent's AOP, not a dashboard. Everything else stays read-only: a Pulse can't retry a Case, change a Queue, start a Run, or edit your data. ## Sharing a Pulse A Pulse is **private by default** — only you can open it, even if someone else has the link. To share it, change its audience. One exception: a dashboard you build from an automation's own tab bar is shared with your whole team from the start, with **Edit** access, because the tab is pinned for everyone who opens that automation and the automation is shared work. Anyone on the team can open it and refine it through chat. Each viewer still sees only the data their own account is allowed to see — sharing the dashboard doesn't share your access to the data behind it. You can still change the audience or drop it to **View** at any time with the steps below — set it to **Only you** and the tab shows only for you. Because this dashboard belongs to the automation, it lives on the automation's tab bar rather than in your **My Pulses** or **Team Pulses** lists, and it's removed automatically if the automation is deleted. Open the Pulse you want to share. Click **Share**. Under **Who can access**, pick the audience: * **Only you** (default) — the Pulse stays private. * **Everyone at \[your team]** — the dashboard appears in the **Team Pulses** list for everyone on your team. * **Everyone at \[your organization]** — shown when your team belongs to an organization. Everyone in the organization can view the dashboard: it appears in each team's **Shared with your organization** list and in the organization workspace's **Pulse** section. * **View** (default) — teammates see the dashboard only. * **Edit** — teammates can also refine it through chat, just like you. For a team-owned Pulse shared with your organization, members outside the owning team can only view. Organization-level Pulses use the **View** or **Edit** permission selected above. Copy the link with **Copy link** to share it directly. For an organization-shared Pulse the link opens for every organization member. To make a Pulse private again, set **Who can access** back to **Only you**. It disappears from the shared lists and the link stops working for others. ## Organization-level Pulses If you belong to an organization, you can also build dashboards that live at the organization level — owned by the organization itself, not by any team. Open **Pulse** in the organization workspace's sidebar and click **New Pulse**. Any organization member can create one. Organization-level Pulses work like team Pulses, with a few differences: * **The audience is the whole organization.** The share options are **Only you** (the default) and **Everyone at \[your organization]**. When you publish, you choose whether organization members can **View** the dashboard or also **Edit** it through chat. * **No Connections.** Connections are set up per team, so an organization-level Pulse builds from your Duvo platform data. Data on the dashboard spans the teams the viewer can access. * **They appear in the organization workspace.** Your own organization-level dashboards show under **My Pulses** on the organization's Pulse page; published ones appear in **Shared with your organization** for every member, labeled **Organization**. Publishing controls who can open a dashboard — it does not change what data they see. A shared Pulse always shows each viewer only the data their own account is authorized to access, so two teammates may see different numbers in the same dashboard. Only the creator can rename, delete, publish, or change the permissions of a Pulse. To adapt someone else's dashboard as your own, duplicate it (see below). ## Managing Your Pulses The Pulse home page lists dashboards in up to three groups: * **My Pulses** — dashboards you created. * **Team Pulses** — dashboards teammates have published to the team, showing who created each one and when it was last updated. * **Shared with your organization** — dashboards shared org-wide by other teams (view-only, attributed to the team that owns each one), plus any organization-level dashboards (labeled **Organization**), which open with whichever **View** or **Edit** permission their creator set. Open any dashboard's menu to: * **Duplicate** — clone an existing dashboard as a starting point instead of building a new one from scratch. * **Export** — save the dashboard as a PDF or HTML file to share outside Duvo. * **View version history** — browse earlier versions of the dashboard and restore one if needed. * **Delete** — remove a dashboard. Only the creator can delete, and deletion can't be undone. ## When to Use Pulse * **Answer a one-off question** — get a custom cut of your Duvo data without asking for a new report or rebuilding it in a spreadsheet. * **Monitor an operation** — keep a live view of open Cases, Run outcomes, or queue backlogs and revisit it whenever you need the latest picture. * **Share a view with your team** — publish a dashboard so everyone works from the same live numbers. * **Work through your approvals** — put every case approval waiting on you on one page and answer them there, instead of opening each Case in turn. ## Related The built-in analytics overview of your team's Agents and Runs. What each metric means and how it's calculated. The full queue of Agent requests waiting on a human — including the ones a dashboard can't answer. How an Agent pauses for a human decision in the first place. # Team Insights Source: https://docs.duvo.ai/user-guide/analytics/team-insights-overview See how your team uses Duvo — agent activity, usage trends, user engagement, and run sources. ## Introduction Team Insights gives you visibility into how your team uses Duvo. Track agent activity, monitor usage patterns, and understand how automation is impacting your organization. *** ## Accessing Team Insights Click on **Team Insights** in the left sidebar under the Team section. You'll see the insights dashboard with key metrics and activity data. You need appropriate permissions to view Team Insights. Contact your team administrator if you don't see this option. *** ## What You Can Track ### Agent Activity See how your agents are performing: * **Total Runs** - How many times agents have executed * **Completed Runs** - Successfully finished executions * **Active Agents** - Agents that have run recently ### Usage Over Time Track trends in your team's automation: * View activity by day, week, or month * Identify peak usage periods * Monitor growth in automation adoption ### User Activity Understand how team members are using Duvo: * See which users are running agents * Track activity levels across the team * Identify power users and engagement levels ### Source Breakdown See where agent runs originate: * **Manual** - Runs triggered by users clicking Run * **Scheduled** - Automatic runs from schedules * **Slack** - Runs triggered from Slack * **Other** - Runs from webhooks or other triggers *** ## Using Insights Effectively ### Monitor Adoption Track whether your team is actively using the agents you've built. Low usage might indicate: * Agents that don't match actual workflows * Opportunities to improve or promote specific agents ### Identify High-Value Agents Agents with many runs and high completion rates are delivering value. Consider: * Documenting these as examples for other teams * Expanding similar automation to other areas * Ensuring these critical agents are well-maintained ### Spot Issues Early Sudden drops in activity or completion rates might indicate: * Connection issues that need attention * Process changes that require agent updates * Technical problems requiring investigation *** ## Time Period Selection Use the date range selector to focus on specific periods: * **Last 7 days** - Recent activity snapshot * **Last 30 days** - Monthly overview * **Custom range** - Specific date range for deeper analysis *** ## Things to Know * Insights data updates regularly throughout the day * Historical data is retained for trend analysis * Only team administrators and authorized users can view insights * Individual run details can be accessed from the agent's run history *** ## Related How to use Team Insights signals to catch problems early after an agent goes live Definitions for all metrics shown in Team Insights Build live, custom dashboards of your Duvo data by describing what you want to see. # Understanding Metrics Source: https://docs.duvo.ai/user-guide/analytics/understanding-metrics Definitions for the agent, user, and source metrics shown in Team Insights, plus how to interpret trends. ## Introduction This page explains the metrics available in Team Insights and how to interpret them for your organization. *** ## Agent Metrics ### Total Runs The total number of times agents have been executed in the selected time period. **What it tells you:** * Overall automation activity level * Whether usage is growing or declining * Comparison baseline for different periods ### Completed Runs Runs that finished successfully without errors or interruptions. **What it tells you:** * Reliability of your agents * Success rate of your automation * Whether agents are working as expected **Healthy target:** Aim for 90%+ completion rate. Lower rates may indicate issues with Connections, AOPs, or edge cases. ### Active Agents Agents that have had at least one run in the selected period. **What it tells you:** * How many agents are actually being used * Breadth of automation across your workflows * Whether some agents are unused and could be retired *** ## User Metrics ### Active Users Team members who have run at least one agent in the period. **What it tells you:** * Adoption rate across your team * Whether automation is spreading or concentrated * Opportunities to improve adoption ### Runs Per User Average number of runs initiated by each active user. **What it tells you:** * Engagement depth with automation * Power users vs casual users * Potential for expanding usage *** ## Source Metrics ### Manual Runs Runs triggered by users clicking the Run button. **Typical patterns:** * Higher for new agents being tested * Common for ad-hoc tasks * May indicate scheduling opportunities ### Scheduled Runs Runs triggered automatically by schedules. **Typical patterns:** * Indicates mature, trusted agents * Represents true automation value * Should grow as agents prove reliable ### Slack Runs Runs triggered through Slack connection. **Typical patterns:** * Shows collaboration and accessibility * Common for team-facing agents * Indicates good connection with daily workflows *** ## Interpreting Trends ### Growing Usage Increasing runs and active users indicates: * Successful adoption of automation * Value being recognized by the team * Opportunity to expand to new use cases ### Declining Usage Decreasing activity might mean: * Initial excitement wearing off * Agents not meeting needs * Process changes making agents obsolete * Team members may need more support or better agents ### Steady Usage Consistent activity suggests: * Stable, reliable automation * Agents well-matched to workflows * Opportunity to optimize or expand *** ## Benchmarking While every organization is different, consider these general benchmarks: | Metric | Starting Out | Maturing | Advanced | | ------------------- | ------------- | -------- | -------- | | Completion Rate | 70-80% | 85-95% | 95%+ | | Scheduled vs Manual | 20/80 | 50/50 | 70/30 | | Active Users | \<25% of team | 25-50% | 50%+ | *** ## Things to Know * Metrics reflect activity within the selected time period * Compare similar time periods for meaningful trends * Seasonal variations may affect some metrics * Focus on trends rather than absolute numbers # Usage Tracking Source: https://docs.duvo.ai/user-guide/analytics/usage-tracking Track agent, user, and connection usage to measure automation impact and find new opportunities. ## Introduction Track how your team uses Duvo to identify opportunities, measure impact, and ensure you're getting maximum value from automation. *** ## Tracking Agent Performance ### Viewing Run History For any agent, you can see its complete run history: Open the agent you want to review. Look for the run history or past runs section. See all executions with their status and timing. ### What to Look For **Successful patterns:** * Consistent completion times * High success rates * Regular scheduled execution **Warning signs:** * Frequent failures or interruptions * Increasing run times * Gaps in scheduled runs *** ## Tracking by User ### Understanding User Activity Team Insights shows activity broken down by user, helping you understand: * Who is actively using automation * Which users might need additional support * Where to focus adoption efforts ### Identifying Champions Users with high activity levels can be: * Resources for helping other team members * Sources of feedback for improvements * Advocates for expanding automation ### Supporting New Users Users with low activity might benefit from: * Simpler agents to start with * Clear documentation of available automation * Direct walkthroughs of relevant agents *** ## Tracking Connection Usage ### Which Connections Are Used Most Understanding which connections your agents use helps you: * Prioritize maintaining critical connections * Identify opportunities for new connections * Ensure tokens and logins stay current ### Connection Health Monitor that connected connections are working: * Check that scheduled agents complete successfully * Watch for authentication errors in run logs * Refresh logins before they expire *** ## Setting Up Effective Tracking ### Naming Conventions Use clear, consistent naming for agents: * **Good:** "Weekly Sales Report - Regional Managers" * **Poor:** "Report v2 final" Good names make it easier to track and analyze usage. ### Organizing by Purpose Group related agents mentally or through naming: * Finance agents * Customer service automation * Internal operations This helps you track usage by business function. *** ## Measuring Automation Impact ### Time Savings Estimate time saved by comparing: * How long the task took manually * How often the agent runs * Total time saved = (manual time × frequency) ### Error Reduction Automation can reduce errors: * Track issues before and after automation * Note consistency improvements * Document quality gains ### Speed Improvements Measure faster turnaround: * Time from trigger to completion * Response times for automated processes * Customer or stakeholder wait times *** ## Reporting on Automation ### For Your Team Share regular updates on: * Number of agents in use * Runs completed this period * New automation added * Success stories and wins ### For Leadership Highlight business impact: * Time and cost savings * Error reduction * Process improvements * Employee satisfaction with automation *** ## Things to Know * Regular review of usage helps optimize your automation * Low-usage agents might need improvement or retirement * High-usage agents deserve careful maintenance * Usage patterns can reveal new automation opportunities # Agent Handover Source: https://docs.duvo.ai/user-guide/assignment-features/assignment-handover Let one agent pass its work to another agent when a Run completes, for triage, escalation, and multi-step workflows. Agent Handover lets one agent pass its work to another agent when a Run completes. Use it to build multi-step workflows where a general agent routes work to a specialist, or where one stage of a process hands off to the next. ## Key Capabilities * **Route work automatically**: An agent can hand off to a pre-configured target agent at runtime—no manual intervention needed. * **Configure targets in the AOP**: Mention other agents with `@Assignment Name` directly in the AOP to set them as allowed handover targets. * **Works with Queue**: For case-based workflows, the case is released and routed to the target agent through the regular case dispatcher. * **Works with standalone Runs**: For non-case Runs, a new Run is started for the target agent, not carrying over any context from the source run. ## How to Use It Open the agent you want to configure as a handover source and navigate to the AOP editor. In the AOP textarea, type `@` followed by the name of the agent you want to hand off to. A dropdown appears listing available agents in your team. Select the agent. A badge is inserted inline in the AOP text—this registers it as an allowed handover target. Place the mention within naturally written rules for handover. You can add multiple targets if your agent may route to different specialists depending on the situation. **Example AOP instruction:** > After reviewing the customer request, determine whether it needs billing support or technical support. If billing, hand over to @Billing Specialist. If technical, hand over to @Technical Support. Save the AOP. On the next Run, the agent will have access to a `request_handover` tool. At runtime, the agent decides when to use it based on your AOP instructions. ### Handover flow ```mermaid theme={"dark"} flowchart TD A[Agent reviews work during Run] --> B{Handover needed?} B -->|No| C[Agent completes the Run normally] B -->|Yes| D[Agent calls request_handover to a target named in the AOP] D --> E{Workflow type} E -->|Case-based| F[Case released and routed to target agent via case dispatcher] E -->|Standalone Run| G[New Run started for target agent, no source context carried over] F --> H[Target agent picks up and continues processing] G --> H H --> I[Source Run shows handover target in its results] ``` ### Viewing handover results After a handover occurs, the source Run shows the handover target in its results. For case-based workflows, the case timeline reflects which agent handled each stage. ## When to Use It * **Triage workflows**: A general agent reviews incoming cases and routes each one to the right specialist. * **Escalation paths**: An agent handles routine cases and escalates complex ones to a more specialized agent. * **Sequential pipelines**: One agent completes an initial stage (data gathering, analysis) and hands off to another for the next stage (reporting, action). * **Domain specialization**: Route work to an agent that has the right connections and context for a specific task type. ## Things to Know * An agent can only hand off to agents configured as targets in its AOP—it cannot hand off to arbitrary agents at runtime. * If a mentioned agent is deleted, the mention badge turns red in the AOP editor. Remove the deleted target before the next run. * For case-based handovers, the target agent must have the **Queue (Consumer)** connection enabled. Agents without it are not available as handover targets in queue workflows. # Agent Memory Source: https://docs.duvo.ai/user-guide/assignment-features/assignment-memory Personalize how an agent works for you with a private context layer, without changing the shared AOP everyone else uses. ## Introduction Agent Memory is a powerful feature that allows you to personalize how an agent works specifically for you, without changing the core AOP that everyone else uses. This means multiple users can run the same agent with their own individual preferences, thresholds, and requirements automatically applied. ## What is Agent Memory? Memory is your personal context layer for any agent you have access to. When you add information to Memory, the agent will remember and apply those preferences every time you run it—but only for your runs. Other users running the same agent will have their own Memory settings applied to their sessions. Think of Memory as your agent's personalized notepad about your specific preferences, while the main AOP remains the shared "company policy" that applies to everyone. ## How Memory Works When you run an agent, Duvo combines: * The agent's core AOP (shared by all users) * Your personal Memory settings (specific to you) * Any run-time prompts you provide during that specific session This allows the same agent to adapt to different users' needs automatically, without requiring separate agents for each person or constant manual adjustments. ## Why Use Memory? **Personal thresholds and preferences**: Set approval limits, priorities, or preferences that match your role and authority level **Saves time**: Avoid providing the same context or guidance every time you run an agent **Maintains consistency**: Your preferences are automatically applied to every run, ensuring the agent always works the way you need it to **Preserves shared workflows**: The core AOP stays intact for everyone else while you get personalized behavior ## How to Add Memory To add information to Memory for a specific agent: Open the agent you want to personalize. Navigate to the Memory section in the agent settings. Agent Memory Describe your preferences in plain English, just like you would in the Agent Builder. Your preferences will now automatically apply every time you run this agent. ## Deleting Memory Files in Bulk When you have edit rights on an Agent or Queue's Memory, you can clear out several files at once instead of removing them one by one. Open the Memory section for the Agent or Queue. Tick individual files, tick a folder to include everything inside it, or use **Select all**. Shift-click the first and last file in a range to select everything in between. Choose **Delete** and confirm. Duvo removes the selected files together and updates progress as each one completes. If some files can't be deleted, Duvo removes the rest and shows how many were deleted; anything that failed stays in the list so you can retry it. ## Real-World Examples ### Example 1: Purchase Order Approvals Your company has a PO approval agent that processes purchase orders. The core AOP requires human approval for orders over a certain amount. **User A (Department Manager)** adds to Memory: *"Auto-approve all purchase orders under $5,000 from approved vendors. Flag anything over $5,000 for my review."* **User B (Director)** adds to Memory: *"Auto-approve all purchase orders under $10,000. For orders between $10,000-$25,000, check if they're budgeted before requesting approval. Anything over $25,000 requires VP sign-off."* Both users run the same agent, but it automatically adapts to their different approval authority levels. ### Example 2: Customer Communications Your team uses an agent that drafts customer response emails. Different team members have different communication styles and preferences. **User A (Account Manager)** adds to Memory: *"Always use a warm, conversational tone. Include my direct phone number in the signature. CC me on all customer correspondence."* **User B (Technical Support)** adds to Memory: *"Keep responses concise and technical. Include links to our documentation. Don't CC me unless it's urgent."* The same agent produces emails that match each user's style and preferences automatically. ### Example 3: Report Generation A weekly sales report agent pulls data and distributes reports to leadership. **User A (Sales Manager - West Region)** adds to Memory: *"Only include data for California, Oregon, and Washington territories. Highlight accounts over \$50K in annual value. Send the report to my regional team."* **User B (Sales Manager - East Region)** adds to Memory: *"Only include data for New York, New Jersey, and Pennsylvania territories. Highlight accounts over \$100K in annual value. Send the report to my regional team and VP of Sales."* Each manager gets a personalized report from the same agent without duplicating the workflow. ## What to Include in Memory Memory works best when you provide: * **Personal thresholds**: Dollar amounts, quantity limits, time frames specific to your role * **Preferences**: Communication style, formatting choices, notification preferences * **Contextual rules**: Exceptions or special handling for your department, region, or responsibilities * **Contact information**: Who should be notified, CC'd, or involved in your runs * **Priority guidance**: What matters most to you when the agent needs to make judgment calls ## What Happens When an Agent Moves to Another Team When an Agent moves to another team, its Memory moves with it, along with the Memory attached to any Queue that moves in the same operation. The Agent arrives on the new team with its context intact, so runs behave the same way after the move as before it. If the destination team already has Memory for that Agent or Queue — which happens when the Agent lived on that team before and left its Memory behind — the destination team's existing Memory is kept and the incoming Memory stays where it is. Nothing the destination team already relies on is overwritten. Archived Memory on the destination stops the move, and the error identifies the Agent or Queue that is blocking it. Restore or delete that Memory on the destination team, then move the Agent again. Duvo stops rather than silently leaving the Agent's Memory behind. Unusually large Memory is also refused rather than moved in part. The message names the limit — clear out Memory the Agent no longer needs, then retry. ## Key Takeaways * Memory personalizes agent behavior for your specific needs without changing the core AOP * Multiple users can run the same agent with their own individual Memory settings * Memory is perfect for thresholds, preferences, and personal context that applies to all your runs * Memory complements (but doesn't replace) run-time prompts for one-time guidance * You can update Memory settings at any time Agent Memory ensures that automation works the way you need it to, while maintaining consistency and collaboration across your team. Set it once, and let your agents remember what matters most to you! # Browsing Capabilities Source: https://docs.duvo.ai/user-guide/assignment-features/browsing Let a Duvo agent work inside any browser-based system to navigate pages, click, type, read values, and capture evidence, with Duvo's guardrails and audit trails. ## What Browsing Is Browsing allows a DUVO agent to work inside any browser-based system. The agent can navigate pages, click buttons, type text, read values, evaluate page state, and capture evidence. It behaves like a teammate executing UI steps, but it does so with DUVO's guardrails, approvals, and audit trails. Browsing is essential for systems without APIs or for workflows that span several applications. It is a governed, safe way to automate the operational work that usually relies on humans. Browsing is an essential tool of the agent, automatically used when the agent runs. ## What browsing tool can do * Log in using stored logins and perform actions on the website * Capture screenshots and send them as evidence * Open and manage new tabs * Download and upload files * Show a screenshot replay in the run view — after the run, you can review each browser step as a visual timeline of screenshots, making it easy to see exactly what the agent did on screen ## When to Use Browsing Browsing is the right choice when: * A system has no reliable API * Evidence is required for audit or human review * The workflow crosses multiple systems * You want fast time-to-value with the option to add deeper connections later ## How to Build Browsing Steps Add the relevant login to My Logins [How to give agents logins to log in on your behalf](/user-guide/resources/my-logins) Write the task in plain language. Mention approval rules and when screenshots should be taken. **Examples** * Navigate to a page * Enter data in a form * Click a button * Capture a screenshot for evidence * Move through multi-step flows with new tabs # Queue Source: https://docs.duvo.ai/user-guide/assignment-features/case-queue Understand how queues and cases route work to agents, including setup, triggers, statuses, and operations. ## Introduction Queue is a queue-based work item system for agents. It lets you feed individual work items — called **cases** — into a queue, where agents automatically pick them up, process them, and report results. This is useful when you have a stream of tasks that need to be handled one at a time (or in parallel), such as processing incoming requests, handling tickets, or working through a batch of items. *** ## Key Concepts ### Queue A queue is a container that holds cases waiting to be processed. Each team has one default queue, and cases flow through it to be claimed by agents. ### Case A case is an individual work item with a title and associated data. Think of it as a task card — it carries the information an agent needs to do its work. ### Case Statuses | Status | Meaning | | --------------- | ----------------------------------------------------------- | | **Pending** | Waiting in the queue to be picked up | | **In Progress** | An agent has claimed the case and is working on it | | **Needs Input** | The agent is waiting for a human response before continuing | | **Postponed** | Waiting until a scheduled time before being picked up again | | **Completed** | The agent finished processing the case successfully | | **Failed** | The agent could not process the case | ### Agent Triggers An agent trigger connects an agent to a queue. When a new case arrives, the trigger automatically dispatches the agent to claim and process it — no manual intervention needed. *** ## How It Works Either by another agent or by an external system via the API. The agent automatically claims the next pending case. The agent uses the case data as input. The agent marks the case as completed or postponed, requests a handover, or the case is marked as failed if the Run ends without any of these actions. ### Status Transitions Case statuses follow a specific lifecycle. Understanding these transitions helps you write better AOPs and troubleshoot processing issues. ```mermaid theme={"dark"} stateDiagram-v2 [*] --> Pending Pending --> InProgress: Agent picks up case (case trigger) InProgress --> NeedsInput: Agent requires human input (Human-in-the-Loop) NeedsInput --> InProgress: Human responds InProgress --> Completed: Agent marks case completed InProgress --> Postponed: Agent postpones to a later time Postponed --> Pending: Postponed time arrives, dispatched again InProgress --> Failed: Run ends without complete/postpone/handover InProgress --> HandedOver: Agent hands off to another agent (handover) Completed --> [*] Failed --> [*] HandedOver --> [*] ``` * **Pending → In Progress**: When an agent picks up a case from the queue, the case moves to In Progress. This happens automatically through the case trigger — the agent claims the next available case and begins working on it. * **In Progress → Needs Input**: If the agent requires human input while processing (via the Human-in-the-Loop feature), the case shows as Needs Input until the human responds. * **In Progress → Completed**: The agent explicitly marks the case as completed after it finishes processing successfully. Your AOP should instruct the agent on when and how to mark a case as done. * **In Progress → Failed**: If the agent's Run ends without completing, postponing, or handing over the case, the system automatically marks it as Failed. This means your AOP should always instruct the agent to explicitly resolve each case — otherwise it will be treated as a failure. * **In Progress → Postponed**: The agent can postpone a case to delay processing until a later time. This is useful when the agent determines that a case needs to wait — for example, waiting for an external event, a cooling-off period, or a specific business hour. The agent specifies when the case should be retried, either as a specific time or a relative duration (e.g., "2 hours", "1 day"). When the postponed time arrives, the case is automatically dispatched for processing again. ### Writing AOPs for Case Processing The agent decides how to handle a case based on your AOP instructions. To get reliable results, your AOP should clearly tell the agent: * **When to complete a case** — define what "done" looks like. For example: "After sending the reply email, mark the case as completed." * **When to fail a case** — define what counts as unprocessable. For example: "If the customer account cannot be found, update the case with the reason and mark it as failed." Note that if the Run ends without the agent completing, postponing, or handing over the case, it is automatically marked as Failed — but explicitly failing with a reason is preferred so you can review what went wrong. * **When to postpone a case** — define conditions for delaying. For example: "If the report data is not yet available, postpone the case for 2 hours." Without clear instructions, the agent may not resolve cases properly, and cases will be implicitly marked as Failed. *** ## Setting Up Queue in the Builder Queue is configured directly from the agent builder. A dedicated **Queue** section appears in the builder header, separate from Connections, where you link the agent to the queues it should read from or write to. To connect an agent to one or more queues: Open the agent you want to link to a queue. In the **Queue** section of the builder header, click the **plus button**. This opens the **Queue Setup dialog**. In the dialog, choose how the agent should interact with each queue: * **Processes Cases (Consumer)** — the agent picks up and processes cases from the selected queue. * **Adds Cases (Producer)** — the agent adds new cases to the selected queue. If your team has more than 20 queues, a search box appears at the top of the dialog so you can filter by name. On a live revision, after selecting a consumer queue, trigger controls appear inside the dialog. You can enable the case trigger and set concurrency here alongside your queue selection. Changes are saved together when you click **Save**. After selecting a consumer queue, choose whether the agent processes Cases sequentially (one at a time) or in parallel (the default). Pick sequential when Cases must not overlap — for example, when they touch the same record or external system. A single agent can act as both a producer and a consumer if needed — just link the relevant queues under each role in the dialog. ## Enabling the Case Trigger Linking a queue as a consumer lets the agent access that queue, but it will not start processing cases until the **case trigger** is enabled. You can manage the case trigger from three places: Recommended when setting up for the first time. Open the **Queue Setup dialog** from the builder header. Select a queue under **Processes Cases (Consumer)**. Enable **Runs on new cases** to start automatic processing. Optionally enable **Process cases one at a time** to restrict the agent to processing one case at a time instead of in parallel. Click **Save** — queue setup and trigger settings are saved together. If another agent is already consuming the same queue with an active trigger, a conflict warning appears and Save is blocked until you resolve it. Only one agent can hold an active trigger on a given queue at a time. For quick adjustments after setup. When a consumer queue is configured on the live revision, a **Case Trigger** section appears in the Schedule & Triggers panel between Triggers and Schedules. You can toggle **Runs on new cases** and **Process cases one at a time** directly from the panel — changes save immediately. For scripting and automation. You can also enable or disable the case trigger from the command line. First find the trigger ID with `duvo agents case-triggers list `, then toggle it: ```bash theme={"dark"} duvo agents case-triggers update --enable duvo agents case-triggers update --disable ``` Only the person who set up a trigger or a team Builder or admin can disable it. For the full set of trigger commands — create, delete, switch queues, set concurrency — see [Scheduling and Triggers](/cli/scheduling-and-triggers#case-triggers). Once the trigger is enabled, the agent will start claiming and processing cases as they arrive in the linked queue. *** ## Producer and Consumer Pattern A common pattern is to have one agent create cases and another process them: * **Producer agent**: Runs on a schedule or trigger, identifies work items, and adds them as cases to the queue. * **Consumer agent**: Has a case trigger enabled and automatically picks up and processes each case. This separation keeps your workflows modular — the producer focuses on identifying work, while the consumer focuses on doing it. ### Adding large batches of cases A producer agent can hand `add_cases` its cases in one of two ways: inline, or as a file. For large batches, always use the file. * **Inline** — the agent writes the case array directly into the tool call. Fine for a handful of cases. * **From a file** — the agent writes the complete case array to a JSON file in its workspace and passes that path instead. Nothing is retyped, so nothing can be lost on the way into the queue. A single case can do the same with its data: point at a workspace file rather than pasting a large payload into the case. If your AOP asks a producer to build a big batch, tell it to write the cases to a file first. When a batch cannot be added, the run now fails with a clear error instead of quietly creating one malformed case. *** ## Case Labels Cases can be tagged with labels to organize and categorize your work. Labels appear as **Key: Value** pills in the case detail header, making it easy to see how a case has been classified at a glance. Labels are scoped to the queue — when adding a label, an autocomplete popover shows labels already used in that queue, making it easy to apply consistent classifications across cases. ### Managing Labels * **Assign a label** — Open the case detail and click the attributes area. Select an existing attribute and one of its values to apply a label. To create a new label type, enter a new attribute name to add it as a draft, then add values to it — the first saved value promotes the attribute from draft to active. * **Remove a label** — Click the × on a label pill to remove it from the case. * **Rename a label** — Click the label text to enter inline edit mode. Update the key or value and press Enter to save, or Escape to cancel. Agents can also assign labels automatically using the `assign_labels` tool in their AOP. This lets cases be categorized as part of automated processing — for example, tagging a case with `Priority: High` or `Type: Escalation` before completing or handing it over. *** ## Case Priority Cases can be given a priority so that important work is picked up first. Priority is optional — by default a case has no priority, and most cases stay that way. There are three levels: | Priority | Meaning | | --------------- | --------------------------------------------------------- | | **No priority** | The default. Cases are handled in the order they arrived. | | **Medium** | Handled ahead of default-priority cases. | | **High** | Handled ahead of medium- and default-priority cases. | When a consumer agent picks up its next case, it takes the highest-priority case first, and within the same priority the oldest case first. Postponed cases that are due are still handled ahead of priority, so raising priority never overrides a scheduled wait. A **High priority** or **Medium priority** badge appears before the case title in the Cases list and on the case detail view. Default-priority cases show no badge, keeping the list uncluttered. ### Setting priority You can change a case's priority at any time: * **A single case** — open the row actions menu (three-dot icon) and choose **Set priority**, or open the case detail view and use the priority control in the header. Choose High, Medium, or No priority (to clear it). * **Multiple cases** — select cases with the checkboxes, then click **Set priority** in the bulk actions bar and choose a level. This works with select-all-matching too. Changing priority never interrupts a Run or changes a case's status — it only affects the order pending cases are picked up in. ### Priority when creating cases Producer agents can set a priority when adding cases with the `add_cases` tool, and the public API accepts a priority when creating cases. Agents should only set a priority when your AOP or a person has explicitly asked for that kind of case to be prioritized — otherwise cases are created with no priority. Raising priority reorders work; it does not add capacity. If you flood a queue with high-priority cases, everything is high priority and normal cases can wait indefinitely behind them. *** ## Retrying and Updating Cases You can manually retry or update cases from both the **Cases** list and the **case detail view**. * **Retry** — Cases in Completed, Failed, In Progress, or Needs Input status can be retried. This resets them to Pending — any active Run is stopped first — so they are picked up and processed again. This is useful when a case failed due to a temporary issue, when you want to reprocess a case after updating your agent's AOP, or when you need to restart a Run that is stuck or waiting for input. * **Mark as Completed** — Manually mark any non-completed case as Completed. Useful when a case was resolved outside the agent workflow. * **Mark as Failed** — Manually mark any non-failed case as Failed. Use this to close out cases that are no longer relevant or cannot be processed. To update a case, open the case detail view and click the status badge to open the status dropdown. *** ## Delegating Cases to Specific Agents You can manually send one or more cases to a specific agent, bypassing the queue's automatic trigger. This is useful when a case needs to be handled by a particular agent — for example, routing to a specialist or re-processing with a different agent after a failure. ### Delegating a single case Open the row actions menu (three-dot icon) on any case and choose **Delegate**. A dialog opens listing all agents connected to the queue as consumers. Agents with their case trigger enabled are labelled **Default**; those with the trigger disabled are labelled **Standalone**. Select the target agent and confirm. ### Delegating multiple cases Select the cases you want to delegate using the checkboxes, then click **Delegate** in the bulk actions bar that appears. Choose the target agent in the dialog and confirm. Delegation immediately dispatches a Run on the target agent for each selected case, regardless of the queue's automatic trigger settings. *** ## Human-in-the-Loop with Cases Cases work with the Human-in-the-Loop feature. If a consumer agent needs human input while processing a case, it will pause and send a notification to Requests. The case shows as **Needs Input** until the human responds and the agent completes its work. For guidance on designing escalation patterns, managing Needs Input backlogs, and ramping toward safe autonomy in queue-based workflows, see [Designing Human-in-the-Loop Workflows](/user-guide/assignment-features/hitl-design#using-queue-to-manage-exceptions-at-scale). *** ## Organizing Queues If your team has many queues, you can organize them into folders in the sidebar. Folders help you group related queues together and keep the sidebar manageable as your workload grows. ### Creating folders To create a folder, click the **+** icon next to the Queues heading in the sidebar and choose **New folder**. Give the folder a name and save it. ### Moving queues into folders Drag any queue and drop it onto a folder to move it inside. You can drag from either the sidebar or the main queue overview. A highlighted ring and background on the folder indicate a valid drop target. To move a queue back to the top level, drag it onto the **Queues** area above all folders. Drag operations require queue management permissions. If you cannot drag a queue, check that your role has permission to manage queues for the team. *** ## Queue Statistics The Queues overview page shows a statistics bar for each queue — a count of cases broken down by status (Total, Pending, Postponed, In Progress, Needs Input, Completed, Failed). These stats help you understand throughput and failure rates at a glance. Use the **time period selector** (top-right of the overview) to filter statistics to a specific window: All time, Last hour, Last day, Last 7 days, Last 30 days, or Last year. Selecting a period filters the Completed and Failed counts to only cases resolved within that window, so you can see recent throughput rather than all-time totals. *** ## Viewing Cases You can monitor your queue from the **Cases** page in your team space: * **Label columns** — Each label group appears as its own column in the cases table, showing the assigned value as a colored chip for every case that has it. This lets you scan and compare label values across cases at a glance without opening each one. * **Filter by status** — Show only cases in a specific status: Pending, In Progress, Needs Input, Postponed, Completed, or Failed. * **Filter by priority** — Show only cases at a chosen priority level: High, Medium, or No priority. * **Filter by labels** — Click the **Filters** button to open the filter dropdown and select one or more label values. Only cases carrying all selected labels are shown. Active filters appear as chips above the table; click the × on any chip to remove it. * **Filter by date** — Narrow the list to cases created within a specific date range. * **Search cases** by title keyword to find specific items in a large queue. * **Sort cases** by date created, last updated, or postponed time — newest first by default. * **Browse pages** of results when your queue has many cases (20 per page by default, up to 100). * **View case details** including title, data, and processing history. * **Track queue stats** to understand throughput and failure rates. Filter state is reflected in the page URL, so you can copy and share a filtered view with teammates. Agents that list cases via the `list_cases` tool can also filter by label values, priority, and a created date range, making it easier to process only a specific subset of cases. *** ## Case Handover An agent can hand a case off to another agent during processing. When the agent determines that a different specialist should handle the case, it requests a handover instead of completing or failing the case. The case is released and routed to the target agent, which picks it up and continues processing. This is useful for triage workflows where a general agent routes cases to specialists, or for escalation paths where routine cases are handled by one agent and complex ones are escalated to another. The case timeline in the case details view shows which agent handled each stage. For setup instructions and setup details, see [Agent Handover](/user-guide/assignment-features/assignment-handover). *** ## Managing Queues and Cases via API Queues and cases can be created and managed programmatically using the Duvo Public API. This is useful for provisioning queues, feeding cases from external systems, or triggering processing as part of automation pipelines. ### Queue operations * **List queues** — retrieve all queues for your team * **Create a queue** — provision a new queue with a name and description * **Get a queue** — fetch details for a specific queue * **Update a queue** — rename or update a queue * **Delete a queue** — remove a queue ### Creating cases via API You can add cases to a queue directly from an external system using the public API. This is useful when your source of work items lives outside Duvo — for example, a webhook from a CRM, a record created in a database, or the output of a batch job. **Endpoint**: `POST /queues/{queue_id}/cases` You can create a single case or up to 100 cases in one request: Single case: ```json theme={"dark"} { "case": { "title": "Invoice #12345", "data": { "invoice_id": "12345", "amount": 1500 } } } ``` Batch (up to 100): ```json theme={"dark"} { "cases": [ { "title": "Invoice #12345", "data": { "invoice_id": "12345" } }, { "title": "Invoice #12346", "data": { "invoice_id": "12346" } } ] } ``` Each case also accepts an optional `priority` (`none`, `medium`, or `high`). Use `medium` or `high` to raise it above default-priority cases in the queue; omit it or pass `none` for normal priority. Cases created via the API are added as **Pending** and, if a consumer agent has a case trigger enabled, will be dispatched automatically. For authentication and general API usage, see [Running Agents via API](/user-guide/running-assignments/running-assignments-via-api). *** ## Key Takeaway Queue gives your agents a structured way to receive and process work items. Pair it with agent triggers for fully automated processing, or use the producer-consumer pattern to build modular, scalable workflows. # Clarity Source: https://docs.duvo.ai/user-guide/assignment-features/clarity Capture, organize, and improve process documentation with Clarity. ## Introduction Clarity is Duvo's process documentation and analysis system. It helps you capture how work actually gets done — through video recordings, AI voice interviews, phone interviews, and documents — then uses AI to turn those captures into structured documentation with cost-benefit insights. Whether you're onboarding new team members, evaluating automation opportunities, or standardizing operations, Clarity gives you a clear picture of your processes. Clarity is built into Duvo — there's no separate setup. Open the Clarity section in the sidebar and create your first process to get started. ## Key Capabilities * **Capture processes** via screen recordings, AI voice agent interviews, phone interviews, and uploaded documents * **AI-powered video analysis** that extracts steps, systems used, and decision points * **Automated documentation generation** with cost-benefit analysis * **Industry-specific benchmarks** for retail, grocery, and CPG workflows * **Sharing and collaboration** through public links or shareable invite links for people outside your team ## Quick Start: End-to-End in 5 Steps Open the **Clarity** section in the sidebar and click **New Process**. Give it a name that describes the workflow (e.g., "Monthly Inventory Count"). Add a voice interview, phone interview, video recording, or document. See the step-by-step guides below. Set your company name, industry, team size, hourly rate, and language so Clarity can calculate cost-benefit figures and work in your preferred language. Click **Start Analysis**. Clarity combines all captures and generates a structured process document with a BPMN diagram. Review the output, edit the Transformation Guidance if needed, and share the process via a public link. ## Capture a Process Clarity supports four capture methods. Pick the one that fits how the knowledge lives today — or combine several on the same process. A voice interview is a conversation with an AI agent that asks you questions about a process and records your answers automatically. This is the fastest way to capture process knowledge — no typing required. Open the process you want to document. Click **Add Content** and select **Interview**. Your browser will ask for microphone access. Click **Allow**. Select your preferred interview language — English, Czech, French, German, Hungarian, Polish, Portuguese (Brazil), Portuguese (Portugal), Slovak, Spanish (Mexico), Spanish (Spain), or Ukrainian. Your team's default Clarity language is preselected; change it here if this interview needs a different one. Click **Start** to begin the interview. The AI agent will introduce itself and start asking questions about the process. Answer naturally. The agent will ask follow-up questions to capture details, decision points, and exceptions. If the agent feels too slow or too fast, click the **Voice speed** button in the interview controls and drag the slider — Slower, Normal, Faster, or Fast. The new pace takes effect as soon as you close the menu, without interrupting the interview. (Shown only when the interview voice supports speed adjustment.) If you need to pause (e.g., someone walks in), click the **Mute** button. Click **Unmute** when you are ready to continue — the interview picks up where you left off. When you have covered everything, click **End Interview**. A dialog appears with three options: * **Continue interview** — return to the interview if you have more to share. * **End interview** — save the session and complete the interview. * **Discard** — permanently delete the recording and transcript. This cannot be undone. Click **End interview** to save. The interview appears as a capture in the process once it is saved. The AI agent may also end the interview proactively when it has gathered enough information. When this happens, the same dialog appears — choose **Continue interview** if you have more to add, or confirm by clicking **End interview**. Tips for a good interview: * Find a quiet space — background noise can affect the AI agent's ability to hear you. * Describe the process as if you are explaining it to a new colleague. * Mention specific tools, systems, and people involved at each step. * If you make a mistake, just correct yourself — the AI will use the most recent version. A phone interview lets Duvo call your mobile or landline to conduct the interview. This is useful when you are away from your computer, prefer speaking naturally without headphones, or want to capture process knowledge while doing something else. Open the process you want to document. Click **Add Content** and select **Phone Interview**. Enter your phone number in international format with the country code and no spaces (for example, +14155552671). Select your preferred interview language — English, Czech, French, German, Polish, Portuguese (Brazil), Portuguese (Portugal), or Spanish (Spain). Phone interviews cover fewer languages than browser interviews; if your team default is not available here, the call falls back to English. Click **Call Me**. A 3-second countdown starts — click **Cancel** if you need to abort before the call is placed. Answer the call when your phone rings. Duvo will introduce itself and guide you through the interview with questions about the process. Answer naturally. Speak as if you are explaining the process to a new colleague. The AI will ask follow-up questions to capture details, decision points, and exceptions. When you have covered everything, say you are done or hang up. After the call ends, the transcript is saved automatically and appears as a capture in the process. Tips for a good phone interview: * Find a quiet space before clicking **Call Me** — background noise affects transcription quality. * Keep the process name in mind so you describe the right workflow. * Mention specific tools, systems, and people involved at each step. Phone interviews are not available for Clarity Members. Clarity Members can use voice interviews from their browser. Upload a screen recording or video walkthrough of someone performing the process. Clarity uses AI to analyze the video and extract individual steps, tools used, and decision points. Open the process you want to document. Click **Add Content** and select **Upload Video**. Select or drag-and-drop your video file. Wait for the upload and analysis to complete. Clarity processes the video automatically — this may take a few minutes depending on the video length. Once analysis is done, the capture appears in the process with a summary of the extracted content. **Supported formats:** MP4, MOV, WebM, MPEG, AVI, FLV, WMV, 3GP.
**Maximum file size:** 2 GB. Tips for a good recording: * Record the entire process from start to finish, including any waiting or decision points. * Use a screen recorder if the process happens on a computer — this captures the exact screens and clicks. * Narrate what you are doing as you go ("Now I open the ERP system and navigate to Purchase Orders..."). Narration helps the AI produce a more accurate breakdown.
Attach an existing AOP, process guide, or reference material. Clarity extracts the text and uses it alongside other captures during analysis. Open the process you want to document. Click **Add Content** and select **Upload AOP**. Select or drag-and-drop your document file. Wait for the text extraction to complete. The capture appears in the process once it is ready. **Supported formats:** PDF, TXT, Markdown (.md).
**Maximum file size:** 10 MB.
You can rename a capture you recorded. Open the capture's actions menu and select **Rename**. Only the person who created a capture can rename it, and a document capture cannot be renamed until it has finished processing. ## How to Invite People You can invite subject matter experts to add their own captures to a process — even if they do not have a Duvo account yet. Open the process you want others to contribute to. Click the **Invite** button. Enter one or more email addresses and send the invitation. You can invite multiple people at once. Each invitee receives an email with a link to the process. When an invitee opens the link, they see a simplified view where they can start a voice interview or upload a video. Their captures appear in the process alongside yours, grouped by person. Invited users who are new to your team are automatically added with the **Clarity Member** role (see below). ## How to Create a Client Invite Link A client invite link lets you share a specific process with an external stakeholder — such as a client or vendor — without sending an individual email invitation or adding them to your team. Anyone with the link can open the process and contribute a voice interview. Open the process you want to share. Click the **Invite** button to open the sharing panel. Select the **Invite Link** tab. Click **Create invite link**. Duvo generates a unique, process-scoped token. Copy the link and share it directly with the people you want to contribute — via email, Slack, or any other channel. To invalidate the existing link and generate a new one, click **Regenerate link**. People who open the invite link see a focused interview view where they can start a voice interview and contribute to the process. They do not gain access to the rest of your team workspace. Client invite links are process-scoped — each link is tied to a single process. If you want to invite people to a different process, generate a separate link from that process. ## How to Generate and Review Documentation Once you have added at least one capture and configured your team settings, you can generate the process documentation. ### Generate Open the process. Click **Start Analysis**. Clarity processes all captures and generates a structured document. A progress indicator shows which sections are being built. Wait for generation to complete. ### Navigate the output The process view uses an immersive layout: the BPMN process diagram fills the full canvas, with a floating tab switcher overlaid on top. Select a tab to open a side panel alongside the diagram. The diagram supports interactive navigation: use the controls overlaid on the canvas to zoom in, zoom out, fit the entire diagram to the view, or download the diagram as an SVG file. You can also pan by clicking and dragging the canvas. | Tab | Content | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Vision** | Where the process could go — what an optimized version looks like | | **Overview** | Summary of how the process works today | | **Impact** | Projected financial impact — revenue recovered, cost avoided, and risk reduced — with confidence rating and supporting assumptions | | **Steps** | Step-by-step breakdown of each stage | | **Risk & Vulnerabilities** | Identified risks, gaps, and exception points | | **Transformation Guidance** | Editable guidance that shapes the automation strategy | ### Share Open the completed process. Enable the **Share** toggle. Copy the public link and send it to anyone — they do not need a Duvo account to view the documentation. The shared view uses the same immersive layout as the private view. *** ## How Clarity Handles Conflicting Inputs When you add several captures to a process, they will not always agree. Two interviewees may describe the same workflow differently, or an uploaded AOP may not match what someone explains in an interview. Clarity does not pick a winner automatically — there is no fixed priority order that ranks one source above another. Instead, Clarity treats every capture as **evidence**: * **Inputs are evidence, not authority.** Clarity does not assume an AOP outranks an interview, or that one interviewee is more correct than another. It weighs what each capture describes rather than deferring to a single source. * **Conflicting versions are surfaced with attribution.** When two captures describe a step differently, Clarity shows both versions and where each one came from, so you can see who said what rather than silently merging them into one account. * **Conflicts in decision logic are flagged.** Disagreements that affect decision points, branching, or escalation paths are flagged as high-priority, because that is where an unresolved conflict has the largest impact on how the process actually runs. * **The team is prompted to align.** Rather than auto-resolving a conflict, Clarity prompts your team to agree on a single standard for the process, so the documented version reflects a real decision instead of a guess. * **Extra capture clarifies missing detail.** When a step lacks enough detail to automate — often because the captures conflict or leave a gap — Clarity asks for an extra capture to clarify it. See [Fill in missing information](#fill-in-missing-information) below and the capture requests in [Organize processes](#organize-processes). This keeps the generated documentation honest about where the source material disagrees, and puts the decision about the single correct version in your team's hands. *** ## Edit and Ask with Clarity Chat Clarity Chat lets you ask questions about a process and make changes to it through a simple chat — without editing anything by hand. It works on both the **Current Process** and the **Transformation Proposal**. ### What you can do * **Ask about the process** — for example, "Why is this step a risk?", "Where are we leaking margin?", or "What would change if we automated this?" * **Edit the process** — add, reword, or remove steps, or refine the Transformation Proposal, just by describing what you want. * **Fill in missing information** — when a step is flagged as needing more detail, Duvo asks you one focused question at a time and updates the process from your answers. * **Review before you accept** — every change appears as a preview, with added text highlighted and removed text struck through, so you see exactly what will change before applying it. ### How to use it Open a completed process. Find the **Ask Duvo** box at the bottom of the diagram. Type what you want, or pick one of the suggestions — **Edit the process**, **Ask about the process**, or **Add missing information**. Duvo reads the process and replies. For an edit, it shows a preview of the changes on the diagram and in the step details. Review the proposed changes. Accept them to apply, or keep chatting to adjust. To stop a response while Duvo is working, click the stop button next to the message box. ### Fill in missing information When the Transformation Proposal has steps that need more detail, those steps are flagged. Where the people who mapped the process give enough signal, Duvo also suggests who is best placed to fill each gap in a follow-up interview, with a short reason. Managers can assign that person to the flagged step in one click. To provide what's missing: Open the flagged step and choose **Answer in chat** from its menu, or click **Add missing information** in the chat. Duvo asks one question at a time about a single step. Answer in your own words — there are no fixed choices, and you can skip a question. Once you've covered the gaps, Duvo proposes a single update for you to review and accept. Clarity Chat works on the generated process. Generate the documentation first (see above) before you start chatting. ## Organize the Process Library The team library has three views, switchable from the toolbar: * **Folders** (default) — collapsible folders your team owns, plus an **Unfiled** section holding every process without a folder. * **Ungrouped** — one flat grid of all processes. * **Organization** — a read-only view grouping your team's processes by their Process Landscape areas, with an **Unclassified** section for processes the landscape has not placed yet. ### Key Capabilities * **Team-owned folders** — create, rename, reorder, and delete folders (team managers and above). Deleting a folder never deletes processes; they return to Unfiled. Any team member can move processes between folders. * **Set up from landscape** — one click creates a folder for each landscape area that contains your team's processes. These folders follow the area's name until you rename them; renaming makes the name permanently yours. Folder changes never modify the landscape itself. * **Suggestions** — an unfiled process that the landscape has classified shows a **Suggested** chip on its card. Click the chip to file it, or use **File all suggested** on the Unfiled section header to file every suggested process at once. * **Focused browsing** — search, status filters, and **My processes** always show flat results across all folders; clear them to return to your folder view. ### How to use it Open **Clarity** and use the view switcher above the library to choose **Folders**, **Ungrouped**, or **Organization**. In the Folders view, choose **Set up from landscape** to start from your operating model, or **New folder** for a custom grouping such as "Q3 priorities". Open a process card's menu and choose **Move to folder**, or click a card's **Suggested** chip to accept the landscape's placement. Switch to **Organization** to see the same processes grouped by their landscape areas — useful for checking how your team's work maps to the operating model. A process lives in at most one folder. For cross-cutting groupings, use labels in the Process Landscape instead. ## Organize processes The Clarity library follows the same hierarchy shown in Process Landscape. Open a folder to review the processes grouped under that part of your operating model. For organizations where Process Landscape is enabled, access works as follows: * **Open and understand the landscape** — All organization members can open **Process Landscape**. Organization Admins, Owners, and Executives see the complete folder hierarchy. Other members see the processes they can access without folder names. A **Restricted content** notice shows how many processes are hidden in each restricted-only branch and tells members to ask an admin for access. * **Maintain process nodes** — Managers can maintain process nodes for teams they manage. Organization Executives, Owners, and Admins can maintain the skeleton and all process nodes. * **Generate the landscape** — Only organization Executives and Owners can generate **Process Landscape**. * **Assign ownership** — Process ownership assignment remains limited to organization Admins, Owners, and Executives. Process Landscape generation organizes your organization’s existing processes into a company landscape. Captures add optional context for grouping and summaries, but existing processes are the source of truth. Generation also suggests high-confidence relationships across teams: directional handoffs, shared steps, and process variants. Suggested relationships include a short explanation in the process sidebar. Review each suggestion there, then confirm it or remove it; relationships that people already confirmed remain unchanged when the landscape is generated again. ### Landscape interviews Voice interviews started from Process Landscape stay at the organization level. Duvo first asks what work, outcomes, and decisions the participant is responsible for. It then uses one interview approach for the rest of the conversation: * **Strategic perspective** — connects company goals to measurements and KPIs, value drivers, high-level contributing processes, and the relationships between those processes. * **Process-owner perspective** — follows a natural walkthrough of the participant's area to discover high-level process purpose, boundaries, ownership, and dependencies. The participant's description of their responsibilities determines the approach, even when their job title or existing context suggests something else. The interview does not switch approaches partway through. Landscape interviews do not collect detailed process steps, systems, inputs and outputs, or exceptions; add a capture to the relevant process when that level of detail is needed. ### Key Capabilities * **Ask Duvo across the organization** — Start a chat from an organization page to compare the accessible Process Landscape across teams, including ownership, coverage, duplication, relationships, and gaps. Duvo reports how many processes and teams it considered and warns when the landscape is too large to read in full. Organization-wide answers use landscape summaries; open a process when you need its captures or interview evidence. * **See the full hierarchy on the map** — for organization Admins, Owners, and Executives, the map view draws each area as an outlined region with its folders nested inside, split into value chain and support rows. Deeper folders appear as section labels above their processes. Other members see their accessible processes without the restricted folder structure. * **See which processes matter most**: **High** priority is visually emphasized on the map. **High**, **Medium**, and **Low** priorities appear in the tree and process details. Open a process and read the **Priority** section in its details for the reason behind the ranking and when it was assessed. Duvo assesses priorities automatically. Managers can override or clear priorities for processes owned by teams they manage; organization Admins, Owners, and Executives can do this across the organization. Select **Not set** to clear a priority and return the process to the unassessed state. * **Maintain the organization skeleton** — organization Admins, Owners, and Executives can move areas and folders, change their order, add sub-areas, and delete areas and folders they no longer need — from the tree and from the map alike. Deleting an area never deletes the processes inside it; they move to **Unsorted**. * **Maintain team processes** — managers can add, edit, move, and remove process nodes for teams they manage. Organization Admins, Owners, and Executives can maintain process nodes across all teams. * **Review proposed processes on the map** — proposed processes appear as dashed cards. Click one to open its details. Organization Admins, Owners, and Executives can assign its owning team or remove it. * **Accept or decline proposed areas and folders** — a proposed area or folder shows a **Proposed** badge and, when selected, the reason it was suggested. Organization Admins, Owners, and Executives can accept it into the landscape or decline it — from the hover actions on its row in the tree, from **Accept suggestion** in its details, or from its region menu on the map. A proposed area or folder stays proposed until acceptance succeeds, so moving or renaming it first does not confirm it. Declining an area or folder that already holds content also removes the suggested items inside it; the processes inside are not deleted and move to **Unsorted**. * **Review ownership suggestions** — managers can review team assignment suggestions for processes owned by teams they manage. Organization Admins, Owners, and Executives can review suggestions across the organization. * **Reassign a process to another team** — organization Admins, Owners, and Executives can change the assigned team on a process. The process moves to the new team together with its interviews, captures, and invite links, and open ownership suggestions for it are cleared. Wait for any capture recording or upload in progress to finish before moving the process. * **Review process relationships** — suggested handoffs, shared steps, and process variants appear with an explanation in the process sidebar. Confirm useful suggestions or remove incorrect ones. * **Add processes manually** — managers can add a missing process for a team they manage and describe it. Organization Admins, Owners, and Executives can also assign the team that owns it. * **Track process people** — add real people by email or placeholders by name, with an optional role tag for each process. * **Accept or dismiss suggestions** — managers can review capture and team assignment suggestions for teams they manage. Organization Admins, Owners, and Executives can review suggestions across the organization. * **Assign capture requests** — choose the teammate who should provide the missing interview or capture. * **Notify the assignee** — accepted capture suggestions become open capture requests, and the assigned teammate receives the same notification used for extra capture. * **Select multiple processes** — tick the checkbox on each process, or the checkbox in the toolbar to select all, to act on several at once. * **Assign or remove in bulk** — organization Admins, Owners, and Executives can assign selected processes to one team. Managers can remove selected process nodes for teams they manage. * **Reorganize together** — drag any selected process, in the tree or on the map, to move the whole selection into another area at once. ### How to use it Open **Clarity** and go to **Process Landscape**. Select a process or area with suggestions. To add a missing process for a team you manage, open an area's action menu, click **Add process**, then enter the process name and an optional description. Organization Admins, Owners, and Executives can also choose the owner team. Review team assignment suggestions in the sidebar's **Overview** area. Managers can accept or dismiss suggestions for processes owned by teams they manage. Organization Admins, Owners, and Executives can review suggestions across the organization. Under **People** in that same **Overview** area, add a person by email to invite them to that process, or add a placeholder name such as "John from Finance" when you do not have an email yet. Add or edit the optional role tag when you want to record how that person relates to the process. In **Captures**, review capture suggestions and choose **Request capture** to create an open request. Use the assignment picker to choose the teammate who should provide the capture. Switch to the **Map** view to see accessible processes laid out spatially. Restricted-only branches appear as **Restricted content** notices with the hidden-process count and guidance to ask an admin for access. Organization Admins, Owners, and Executives also see areas and folders as nested regions. Click a process card — including a dashed proposed card — or an area or folder name to open its details. Organization Admins, Owners, and Executives can hover over an area or folder name and open its menu to move it earlier or later, add a sub-area, delete it, or — for a proposed area or folder — accept or decline the suggestion. Managers can add and maintain process nodes for teams they manage. Drag a process card into another area or folder to move it there, just like in the tree — available when the landscape is grouped by **Structure**, not when it is grouped by **Team**. People added by email show **Pending** until the invitation is accepted. Placeholder people do not receive an invitation and do not create a Duvo account. To move a single process to a different team, open it and click the **Assigned team** row in the **Overview** area, then pick the new owner. Reassignment is available to organization Admins, Owners, and Executives. To act on several processes at once, tick the checkbox on each process you want. Organization Admins, Owners, and Executives can use the toolbar to assign them to one team. Managers can remove selected process nodes for teams they manage. You can also drag selected process nodes for teams you manage to move the whole selection into another area. ### Process tags Process tags help your organization mark and find related processes in the Landscape. Tags are shared across the whole organization, so the same tags are available to every team. * Tags appear on process nodes in the Landscape. * Managers and above (and organization admins) create, edit, and delete tags; everyone in your organization can see them. * Tags are managed by people: add or remove them directly on a process, or ask Duvo in chat to do it for you. Duvo never adds or removes tags on its own. ### When to use it Use Process Landscape suggestions after sorting new captures, importing process material, or reviewing an L1-L4 area where ownership or missing context is still unclear. ## Inspect Processes from the CLI Use the [Duvo CLI](/cli/clarity) when you need terminal access to a Clarity process. The CLI can find processes, compare generated versions, review evidence citations, list gaps and extra capture requests, import Miro exports, create interview invite links, export Markdown briefs, and produce structured JSON for scripts or AI assistants. The Clarity CLI also exposes public write commands for generating, promoting, reverting, postprocessing, and building automations from Clarity process context. ## How to Regenerate Documentation If you add new captures, want to incorporate feedback, or need a more thorough analysis, you can regenerate the documentation at any time. Open the completed process. Click **Regenerate Documentation**. Optionally enter **Additional details** — any extra context or instructions that should inform the new documentation. This is useful when the existing captures do not tell the full story or when you want to emphasize specific aspects of the process. Confirm the regeneration. Regeneration replaces the existing documentation with a new version based on all captures and any additional details you provide. While documentation is regenerating, all tabs are disabled and the diagram canvas shows a loading state. Wait for generation to complete before switching tabs. ## Duplicating a Process You can create a copy of any existing process using the duplicate action. This is useful when you want to start a new process based on an existing one, or when you need to make a variant without modifying the original. To duplicate a process: From the **Clarity** section, find the process you want to copy. Open the process card's menu (three-dot icon). Click **Duplicate**. Duvo creates a new process named "Copy of \[original name]" with: * All captures from the original process (voice interviews, videos, and documents that were fully processed — any captures still recording or processing are skipped) * The full message and generation history * The same analysis, transformation guidance, and process breakdown The duplicate starts as a **Draft** and its sharing settings are reset — it is private by default and you will need to re-enable sharing if required. Duplicating a process requires the **Manager** role or above. ## Process Diagram Version History The process diagram view includes a version history timeline in the bottom-right corner of the diagram canvas. This timeline lets you navigate between previously generated versions of the diagram and revert to an earlier one if needed. Version history is only visible to: * The team member who created the process * Users with the Manager role or above (Manager, Administrator, Owner) Members, Builders, and Clarity Members who did not create the process cannot view or navigate its version history. ## Configure Team Settings Before generating documentation, set up your team context so Clarity can provide accurate cost-benefit analysis. Open **Settings** in your team space. Navigate to the **Clarity** section. Fill in the following fields: | Setting | Description | | ------------ | --------------------------------------------------------------- | | Company name | Your organization's name | | Industry | Sector for relevant benchmarks (e.g., Retail, Grocery, CPG) | | Team size | Number of people involved in the process | | Hourly rate | Average labor cost for time calculations | | Revenue | Annual revenue for ROI context | | Currency | Your preferred currency for financial figures | | Language | Default language for browser interviews and generated processes | These settings apply to all processes in the team and are used to calculate financial impact in the generated documentation. The Language setting is preselected for every new browser interview and is the language Clarity writes the generated current process, transformation proposal, and chat edits in — English, Czech, French, German, Hungarian, Polish, Portuguese (Brazil), Portuguese (Portugal), Slovak, Spanish (Mexico), Spanish (Spain), or Ukrainian. Phone interviews use the languages available in the phone interview form. ## Process Statuses Each process moves through the following stages: ```mermaid theme={"dark"} stateDiagram-v2 [*] --> Draft Draft --> Collecting Collecting --> Generating Generating --> Complete Complete --> Generating: Regenerate documentation Complete --> [*] ``` | Status | Meaning | | -------------- | ---------------------------------------------- | | **Draft** | Process created, no captures yet | | **Collecting** | Captures are being added and analyzed | | **Generating** | Documentation is being generated from captures | | **Complete** | Documentation is ready to review and share | ## Clarity Member Role Team members with the **Clarity Member** role have a focused, interview-only experience. When a Clarity Member opens a process: * Only the voice interview option is shown — video upload and document upload are not available * They can see and manage captures they have personally added * Their captures are visible to process owners and admins alongside other contributions This role is designed for subject matter experts who contribute process knowledge through interviews without needing full Clarity access. Admins can invite Clarity Members from team settings — enter one or more email addresses at once to send bulk invitations in a single step. ## Key Takeaway Clarity turns informal knowledge — videos, voice interviews, and documents — into structured, actionable process documentation. Use it to understand how work gets done today and identify where automation can save time and cost. ## Next steps Use the Duvo CLI for terminal access to Clarity processes — compare versions, export briefs, and produce structured JSON. Turn Duvo's sorting pass into clear ownership and follow-up capture work across your operating model. # Event-Driven Triggers Source: https://docs.duvo.ai/user-guide/assignment-features/event-driven-triggers Start Duvo agents automatically when something happens in a connected service — a new email, a Linear issue, a Slack message, a file, or a record status change. Event-driven triggers let your agents start automatically when something happens in a connected service—no manual kick-off required. ### Key Capabilities * **Inbox triggers**: Start a Run whenever a new email arrives in Gmail or Microsoft Outlook * **Linear triggers**: Start a Run when a Linear issue is created, updated, assigned, or commented on * **Slack mention triggers**: Start a Run by mentioning the Duvo app in any enabled channel * **Slack channel triggers**: Start a Run automatically from channel messages matching a pattern, or on a reaction * **File-drop triggers**: Start a Run when a new file lands in a monitored cloud folder * **Status-change triggers**: Start a Run when a record in HubSpot, Salesforce, Notion, or another connected tool reaches a particular state * **Google Sheets row triggers**: Start a Run when a row's watched values change in a connected spreadsheet, including a change back to a previous value * **Email trigger filters**: Narrow Gmail triggers by sender, subject keywords, email keywords, recipients, labels, attachments, and categories * **Linear event filtering**: Filter by event type, team, assignee, and workflow state * **Per-user setup**: Each team member configures their own trigger using their own connected account (Slack and Microsoft Teams channel triggers can also run on a connection a teammate shared with the team) ### Trigger Types at a Glance | Trigger type | How it fires | Typical latency | Deduplication | Retry behavior | Payload size limits | | ------------------------------------------- | --------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Email — new message | Polling (inbox check) | Depends on the configured schedule interval | Duvo tracks processed trigger items so each matching message starts once | Polling retries on the next schedule run if the current run fails | N/A — not exposed | | Email — filtered message | Polling, filtered | Depends on the configured schedule interval | Same as email trigger | Same as email trigger | N/A — not exposed | | Linear — new issue / state change / comment | Push (webhook) | Seconds | Each event fires once | Linear retries webhook delivery on failure | N/A — not exposed | | Slack mention | Push (Slack event) | Seconds | Each mention fires once | Slack retries event delivery | N/A — not exposed | | Slack channel message | Push (Slack event) | Seconds | Each matching message fires once | Slack retries event delivery | N/A — not exposed | | Slack reaction | Push (Slack event) | Seconds | Each reaction fires once | Slack retries event delivery | N/A — not exposed | | File drop in cloud folder | Polling | Depends on configured schedule interval | Use Agent Memory to track already-processed files | Polling retries on next schedule run if current run fails | N/A — not exposed | | API-triggered (sandbox upload) | Push (HTTP POST) | Seconds | Caller is responsible for deduplication | No automatic retries — caller must retry on failure | See [Running Agents via API](/user-guide/running-assignments/running-assignments-via-api) | | CRM / PM status change | Polling | Depends on configured schedule interval | Use Agent Memory to track last-seen state | Polling retries on next schedule run if current run fails | N/A — not exposed | | Google Sheets row change | Polling | Depends on the configured schedule interval | Fires when a row's watched values differ from the last-checked values, including reverts | Polling retries on the next schedule run if the current run fails | Watch window caps at 5,000 rows and 250,000 cells combined (columns × rows), with row numbers up to 10,000,000; up to 250 changed rows processed per check | For details on each trigger type beyond inbox and Linear, see the linked guides below. *** ### How to Use It Open your agent in the Duvo workspace and navigate to the **Setup** tab. Find the connection that supports triggers in the Connections section. Toggle the trigger on. A settings modal opens automatically. Choose which events or senders should start a Run. Click Save. The trigger is now active. To pause a trigger, toggle it off. To change the filters, toggle it off and back on to re-open the modal. *** ### Supported Connections | Connection | Trigger Event | Available Filters | | ----------------- | ------------------------------------ | -------------------------------------------------------------------------------------- | | Gmail | New email received | Senders, subject keywords, email keywords, recipients, labels, attachments, categories | | Microsoft Outlook | Email received | Sender email address, folder, shared mailboxes | | Microsoft Outlook | Email sent | Recipient (To) address, shared mailboxes | | Linear | New issue created | Team, assignee, workflow state | | Linear | Issue workflow state changed | Team, assignee, destination state | | Linear | Issue assigned | Team, assignee | | Linear | New comment posted | Team, issue assignee | | Slack Workspace | Mention of the Duvo app in a channel | Agent selection | | Slack Workspace | New message in a channel | Channel, keywords or patterns | | Slack Workspace | Reaction added to a message | Channel, reaction emoji | | Google Sheets | Row's watched values change | Columns (required), row range (required), tab, key column | *** ### Configuring a Linear Trigger When you enable a Linear trigger, a settings modal lets you specify: * **Start work when**: Choose one of the four event types — new issue, state change, agent, or new comment. * **Team** (optional): Enter one or more Linear team keys (for example, `ENG` or `DESIGN`) to restrict the trigger to issues from those teams. Leave empty to match all teams. * **Assignee** (optional): Enter one or more Linear user IDs, or `me`, to restrict the trigger to issues assigned to specific people. Leave empty to match any assignee. * **Workflow state** (optional, for new issue and state change events): Select one or more states (Triage, Backlog, Unstarted, Started, Completed, Canceled). Leave empty to match any state. The trigger uses the Linear account you have connected under your profile. Each team member must enable the trigger individually using their own connection. *** ### Email Trigger Filters By default, an email trigger fires on every new message in the connected inbox. You can narrow Gmail triggers by sender, subject keywords, email keywords, recipients, labels, attachments, and Gmail categories. Outlook filters vary by trigger type. **How to configure:** Enable the Gmail or Outlook trigger in **Setup**. In the trigger settings modal, add one or more filter values: * **Specific address** — for example, `orders@acmecorp.com` * **Domain** — for example, `@acmecorp.com` to match all addresses at that domain * **Subject keywords** — for example, `Invoice` to match emails whose subject contains the word * **Label** — for example, `Finance` to match emails Gmail has tagged with that label * **Has attachment** — toggle on to match only emails with an attachment Save. The trigger now fires only when an email matches the configured filters. **When to use this:** * An order-intake agent that should only fire for emails from known supplier addresses, not all incoming messages * A vendor alert agent scoped to one specific vendor's notification domain * Combining with subject or body filtering in your AOP to further narrow what the agent acts on **Worked example — supplier order intake:** ``` Trigger: New email from @acmecorp.com OR @betasupply.com AOP: For each matching email, extract the order fields and create a record in your ERP. Emails from other senders land in the inbox but do not start a Run. ``` *** ### When to Use It * **Customer request processing**: Start a Run automatically when a customer emails a support address * **Order intake**: Kick off purchase order processing when an order email arrives from a known supplier * **Issue triage**: Start a Run when a new Linear issue lands in Triage so it can be automatically classified, enriched, or routed * **Workflow automation**: Trigger a Run when a Linear issue moves to a specific state, such as starting downstream work when an issue enters "In Progress" * **Report distribution**: Trigger data collection or summary runs when a scheduled report lands in your inbox * **Vendor alerts**: React to supplier notifications or price change emails as Duvo checks the inbox ### How It Works When you enable a trigger, Duvo monitors the connected service for matching events. When an event occurs, Duvo starts a new Run for your agent and passes the event details as context. Your agent's AOP then processes the event and carries out the workflow. Email triggers check your connected inbox on a schedule. Linear triggers listen for webhook events from your Linear workspace. ```mermaid theme={"dark"} flowchart TD A[Event in connected service] --> B{How does the trigger fire?} B -->|Push: Linear, Slack| C[Duvo receives the event in seconds] B -->|Polling: email, file drop, status change| D[Duvo checks the service on a schedule] C --> E{Matches your filters?} D --> E E -->|No| F[No Run started] E -->|Yes| G[Deduplicate: each matching item starts once] G --> H[Start a new Run, pass event details as context] H --> I[Agent AOP processes the event] ``` *** ### Slack and Microsoft Teams Triggers Slack and Microsoft Teams each present their triggers as two separate rows in the Connections section — an **@mention** row and a **channel** row (Teams labels the second as channels or conversations). **@mention triggers** — Mention the Duvo app in any enabled channel to start a Run on demand. The agent runs and posts results back to the same thread. An @mention trigger always runs as the mentioning user, so it uses that user's own personal connection. See [Slack Mention Workflows](/user-guide/examples/slack-mention-workflows) for a full guide. **Channel triggers** — Start a Run automatically from any message (or messages matching a keyword pattern) in a channel, without anyone needing to mention the Duvo app. Useful for monitoring channels like #alerts or #support-inbox. When you create a channel trigger, a connection picker lets you choose which connection backs it. If your organization has Connections sharing enabled, the picker groups connections into **Team** (shared) and **Personal** sections, and a channel trigger can run on a team-shared connection. See [Slack Channel Triggers](/user-guide/assignment-features/slack-channel-triggers) for setup and examples. *** ### File-Drop Triggers Start a Run whenever a new file lands in a monitored cloud folder (Google Drive, OneDrive, SharePoint) or arrives as an attachment in your inbox. Useful for invoice processing, document validation, and any workflow where the input arrives as a file rather than a message. See [File-Drop Triggers](/user-guide/assignment-features/file-drop-triggers) for setup and a worked example. *** ### Status-Change Triggers Start a Run when a record in a CRM or project management tool reaches a particular stage — for example, when a HubSpot deal moves to "Closed Won" or a Notion page status changes to "Ready for Review". Implemented by scheduling an agent to poll the service and using Agent Memory to track what it last saw. See [Status-Change Triggers](/user-guide/assignment-features/status-change-triggers) for setup and examples. *** ### Google Sheets Row Triggers Start a Run when a row's watched values change in a connected spreadsheet — including when a value changes back to what it was before. Both a column range and a row range are required, so the trigger always watches a bounded area of the sheet rather than the whole thing. See [Google Sheets Triggers](/user-guide/connections/available-connections/google-sheets#triggers) for field details and limits. *** ### What Is Not Supported Today Be aware of these gaps when planning your trigger setup: Duvo does not currently expose a dedicated URL that external systems can POST events to. **To start a Run when an external system fires a webhook** (for example, a form submission service, payment processor, or custom app), set up a lightweight webhook handler on your side that calls the [Duvo API](/user-guide/running-assignments/running-assignments-via-api) `POST /teams/{teamId}/runs` endpoint. Pass the event payload as the run context. Retry logic, signing secret verification, and payload mapping are handled by your webhook handler, not by Duvo. See [Running Agents via API](/user-guide/running-assignments/running-assignments-via-api) for the full run API reference. Status-change triggers for these tools use scheduled polling, not real-time webhooks. Latency depends on your polling schedule — typically 5 to 60 minutes. Duvo cannot watch a local folder or network drive. Files must be in a cloud storage service (Google Drive, OneDrive, SharePoint) or arrive via email attachment. Status-change detection for Jira uses scheduled polling. An agent with multiple trigger types enabled must use a single AOP for all triggers. You cannot assign different AOPs to different trigger types on the same agent. *** ### API Trigger Every agent can also be started via the Public API. The Triggers section of the Setup tab includes a collapsed **API trigger** card that shows a ready-to-use curl example pre-filled with your agent's ID: ```bash theme={"dark"} curl -X POST https://api.duvo.ai/v2/teams/{teamId}/runs \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"agent_id": "", "message": "Optional first message"}' ``` The `message` field is optional — include it to pass an initial prompt to the agent when starting the Run. API keys can be created under **Your Profile → API keys** (scoped to a single team or to all teams you can access), or under **Team Settings → API keys** by users with the Manager role or above. For a full reference of run options (sandbox files, webhooks, and polling), see [Running Agents via API](/user-guide/running-assignments/running-assignments-via-api). ### Related Features Run agents on a recurring time-based schedule instead of (or in addition to) event-driven triggers. Start Runs from new files in cloud folders or inbox attachments. Start Runs when CRM or project management records change state. Start Runs from channel messages without mentioning the Duvo app. Connect your Gmail account. Connect your Outlook account. Connect your Linear workspace. Install the Duvo app in your Slack workspace. Connect Google Sheets and set up row-change triggers. # File-Drop Triggers Source: https://docs.duvo.ai/user-guide/assignment-features/file-drop-triggers Start Duvo agents automatically when a new file arrives — in a cloud folder, as an email attachment, or via the Duvo-hosted upload endpoint. File-drop triggers let your agents start automatically when a new file arrives — in a monitored cloud folder, as an email attachment, or via the Duvo-hosted upload endpoint — without anyone having to kick off a Run manually. ## Key Capabilities * **Cloud folder monitoring** — Watch a Google Drive folder, OneDrive folder, or SharePoint library for new files and start a Run as each one lands * **Email attachment monitoring** — Start a Run when an email arrives in Gmail or Outlook with an attachment, passing both the message and its files to the agent * **Duvo-hosted upload endpoint** — Upload files programmatically via the Duvo API (sandbox upload), then start a Run with those files as input. Useful when an external system (a form, script, or pipeline) needs to push files to Duvo directly over HTTP * **Deduplication with Agent Memory** — Track which files have already been processed so the agent never acts on the same file twice * **Multi-format support** — Process PDFs, spreadsheets, images, Word documents, and other formats using the built-in Email Attachments Reader and Intelligent Document Reader connections * **Flexible response** — Extract structured data, validate against business rules, write records to downstream systems, and flag anomalies for human review *** ## How File-Drop Triggers Work Duvo does not currently support a native "watch folder" push event. File-drop monitoring is implemented by **scheduling an agent to run on a short interval** — every 5 or 15 minutes, for example — and having the AOP list new files in the target folder, compare against what it has already seen (stored in Agent Memory), and process only the new ones. For email attachment workflows, you can use the **email trigger** directly: the agent fires as soon as a new email arrives in the connected inbox. No polling interval is needed. | Landing location | Mechanism | Latency | | --------------------------- | ----------------------------- | ------------------------------- | | Gmail or Outlook inbox | Push (email trigger) | Seconds | | Google Drive folder | Polling (scheduled agent) | Equal to your schedule interval | | OneDrive folder | Polling (scheduled agent) | Equal to your schedule interval | | SharePoint library | Polling (scheduled agent) | Equal to your schedule interval | | Duvo-hosted upload endpoint | Push (HTTP POST via Duvo API) | Seconds | *** ## When to Use File-Drop Triggers * **Invoice processing** — Vendors drop PDF invoices in a shared folder; the agent extracts fields and posts records to your accounting system * **Document validation** — Suppliers submit compliance documents via email; the agent checks required fields and flags missing information * **Report ingestion** — A third-party system exports CSVs to a shared drive nightly; the agent imports and transforms the data each morning * **Image and scan processing** — Field teams photograph forms and upload to a shared folder; the agent reads and transcribes each image *** ## How to Set It Up Push, seconds latency. This is the simplest path. Use it when files arrive as email attachments. Open your agent and go to **Setup**. Enable the **Gmail** or **Microsoft Outlook** trigger. Optionally add a sender filter to restrict the trigger to emails from known senders (see [Sender-Scoped Email Triggers](/user-guide/assignment-features/event-driven-triggers#sender-scoped-email-triggers)). Add the **Email Attachments Reader** connection to extract data from PDF, Excel, image, and other attachment types. Write your AOP to describe what to do with each attachment — extract fields, validate, write records. Minutes latency. Use this when files land in Google Drive, OneDrive, or SharePoint. Open your agent and go to **Setup**. Set a **schedule** of every 5 or 15 minutes (or whatever interval is appropriate for your workflow). Add the relevant cloud storage connection (**Google Drive**, **Microsoft OneDrive**, or **Microsoft SharePoint**). Agent Memory is on by default for agents on plans that include it. Note a memory key such as `processed_files` where the agent will store the list of file IDs it has already handled. Write your AOP to: * List all files in the target folder * Compare against `processed_files` in memory to identify new files * Process each new file * Add each processed file's ID to `processed_files` in memory before finishing Push, seconds latency. Use this when an external system — a form submission service, a script, or a data pipeline — needs to push files directly to Duvo over HTTP and start a Run immediately. The Duvo API provides a sandbox that acts as a staging area for files. Your external system uploads files to the sandbox, then calls the run endpoint to start a Run with those files as input. **How it works:** 1. Your external system calls `POST /sandboxes` to create a sandbox and receives a `sandbox_id`. 2. It uploads one or more files to `POST /sandboxes/{sandbox_id}/files`, passing each file as multipart form data with an `Authorization: Bearer ` header. 3. It calls `POST /teams/{teamId}/runs` with the `sandbox_id` and your agent ID to start the Run. The uploaded files are available to the agent at the path specified during upload. 4. Optionally, provide a `human_request_webhook_url` when calling `POST /teams/{teamId}/runs`. Duvo will POST to this URL whenever the agent reaches a Human-in-the-Loop step — that is, when it cannot complete processing automatically and needs a human to approve, reject, or supply information. The payload includes the run ID, request ID, request title and description, and a timestamp. Use the [Respond to Human Request](/user-guide/running-assignments/running-assignments-via-api) endpoint to resume the Run once the reviewer has responded. **Requirements:** * A Duvo API key — create one in **Your Profile → API keys** or, with the Manager role or above, in **Team Settings → API keys**. See [Running Agents via API](/user-guide/running-assignments/running-assignments-via-api) for authentication details. * Your external system should handle retries and protect its webhook endpoint (for example, by validating a shared secret or token). Duvo does not validate signatures on requests sent to your endpoint. **Example (curl):** ```bash theme={"dark"} API_KEY="dv_your_api_key" TEAM_ID="your-team-id" ASSIGNMENT_ID="your-assignment-id" BASE_URL="https://api.duvo.ai/v2" # Step 1 — Create a sandbox SANDBOX_ID=$(curl -s -X POST "$BASE_URL/sandboxes" \ -H "Authorization: Bearer $API_KEY" | jq -r '.sandbox_id') # Step 2 — Upload the file curl -X POST "$BASE_URL/sandboxes/$SANDBOX_ID/files" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@./invoice.pdf" \ -F "path=/workspace/invoice.pdf" # Step 3 — Start the Run curl -X POST "$BASE_URL/teams/$TEAM_ID/runs" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"agent_id\": \"$ASSIGNMENT_ID\", \"sandbox_id\": \"$SANDBOX_ID\"}" ``` The agent's AOP can read the file from `/workspace/invoice.pdf` (or whatever path you specified in Step 2). *** ## Worked Example — Vendor Invoice Processing **Outcome**: Vendor invoices arrive in a shared Google Drive folder. Each invoice is read, key fields are extracted, a record is written to your accounting spreadsheet, and anomalous invoices are held for human review. **Connections used**: * Google Drive — list and read files in the shared folder * Intelligent Document Reader — extract fields from PDF invoices * Google Sheets — write extracted records * Human-in-the-Loop — pause for review when a field is missing or out of range ### Before You Start Make sure you have these ready before building the agent: **Invoice folder** — A shared Google Drive folder where vendors drop invoices. Note the folder name or ID. **Approved vendor list** — A Google Sheet with a column of valid vendor names (for example, a sheet named "Approved Vendors" with a "Vendor Name" column). Optionally add an "ERP Vendor ID" column for downstream mapping. Note the sheet name and tab. **Accounting spreadsheet** — A Google Sheet where extracted invoice records will be written. Note the sheet name and column headers you expect (Vendor Name, Invoice Number, Invoice Date, Due Date, Line Items, Total Amount, Processed Date). **Google Drive and Google Sheets connections** — [Connect Google Drive](/user-guide/connections/available-connections/google-drive) and [Connect Google Sheets](/user-guide/connections/available-connections/google-sheets) from the Connections page. **Agent Memory** — On by default for agents on plans that include it; no pre-configuration needed. 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. Paste and adapt this into the Agent Builder: ``` Check the Google Drive folder at [folder name or ID] for new files that have not been processed before. For each new file: 1. Read the file using the Intelligent Document Reader and extract: - Vendor name - Invoice number - Invoice date - Due date - Line items (description, quantity, unit price) - Total amount 2. Validate the extracted data: - Vendor name must appear in [your approved vendor list in Google Sheets / your ERP] - Invoice number must not already exist in [your accounting spreadsheet] - Total amount must be greater than 0 and below [your single-invoice limit, e.g. $50,000] 3. If all fields are present and pass validation: - Append a new row to the "Invoices" sheet with all extracted fields and today's date. 4. If any field is missing, unreadable, or fails validation: - Do not write the row. - Request human review. Title: "[Issue type] — [Invoice number or filename] — [Vendor name]". Include all extracted fields and the specific issue. - After the reviewer approves (with any corrections) or rejects, either write the corrected row or leave the invoice unprocessed and log the reason. 5. Record the file ID in memory under the key "processed_files" so it is not processed again. ``` Under **Connections**, enable: * **Google Drive** — to list and read files in the shared folder * **Intelligent Document Reader** — already available by default * **Google Sheets** — to write invoice records and look up the approved vendor list * **Human-in-the-Loop** — already available by default Agent Memory is on by default for agents on plans that include it. Have your AOP read and write a `processed_files` key holding the IDs it has already handled, and open the **Memory** tab to review what it has stored. 1. Click **Schedule** in the agent header. 2. Choose **Custom** and set an interval of every 15 minutes, or every hour if near-real-time processing is not required. 3. Click **Add schedule** to save. 1. Upload a sample invoice PDF to the Google Drive folder. 2. Click **Start Work** to run the agent manually. 3. Confirm the fields were extracted correctly and the row was written to your spreadsheet. 4. Upload a second PDF with a missing field and verify the Human-in-the-Loop request is created. *** ## Expected Results When the agent is running: **In Google Sheets**: * A new row for each valid invoice, with all extracted fields populated. * No rows created for invoices with validation errors — those are held for review. **In your Requests**: * A Human-in-the-Loop request for each invoice with a missing, unreadable, or anomalous field. **In Agent Memory**: * The `processed_files` list grows with each Run. Files already processed are skipped even if they are still in the folder. **In Duvo**: * A session log per scheduled Run showing which files were found, processed, and skipped. *** ## Troubleshooting * **Folder path**: Verify the folder name or ID in your AOP matches the actual folder in Google Drive. Paste the folder URL into the AOP if the name is ambiguous. * **Memory conflict**: If the `processed_files` list was corrupted or contains a wrong ID, remove just that entry from the **Memory** tab and run the agent again. Clearing all of the agent's memory also deletes unrelated keys and makes every previously handled file look new, so only do that if you want everything reprocessed. * **Permissions**: Confirm the Google Drive connection has read access to the shared folder, including folders owned by others. Re-authorize from the [Connections page](https://app.duvo.ai/integrations) if needed. * The `processed_files` key in Agent Memory is case-sensitive. Make sure your AOP writes the same file ID format that it reads when checking for duplicates. * If Agent Memory was cleared, files previously processed will appear new on the next Run. * **Scanned PDFs**: Low-resolution scans reduce extraction accuracy. Ask vendors to send native PDFs where possible. * **Multi-page invoices**: Explicitly state in your AOP: "Read all pages of the document." * **Non-standard layouts**: Add two or three sample invoices to **Files** and reference them in the AOP as formatting examples. By default, listing a folder returns only top-level files. To include subfolders, add to your AOP: "List all files in the folder and all its subfolders recursively." *** ## Take It Further **Route by vendor** ``` After writing the invoice row, check if the vendor has a preferred reviewer in [your spreadsheet]. If so, include their name in the Human-in-the-Loop request title. ``` **Send a confirmation to the vendor** ``` After writing the invoice row, send a confirmation email to the vendor's address (extracted from the invoice) with the subject "Invoice [number] received — processing in progress." ``` **Trigger from Slack** Drop a file directly in a Slack channel and mention the Duvo app to process it on demand, rather than waiting for the next scheduled Run. See [Slack Mention Workflows](/user-guide/examples/slack-mention-workflows). *** ## Related Overview of all trigger types and the trigger matrix. Set the polling interval for cloud folder monitoring. Store processed file IDs to prevent duplicate processing. Handle anomalous invoices with approval gates. Extract data from PDFs, spreadsheets, and images attached to emails. Parse unstructured PDFs from cloud storage. Connect your Google Drive. Connect your OneDrive. Connect your SharePoint library. Full API reference for the Duvo-hosted upload endpoint (sandbox creation, file upload, run start). # Files Source: https://docs.duvo.ai/user-guide/assignment-features/files Give your agents access to important documents so they have the context and knowledge to complete tasks to your specifications. ## Introduction Files are how you give your agents access to important documents. These provide your agents with context and knowledge that helps them complete tasks according to your specifications. ## What is Files? The Files section sits in the resources section of the left sidebar. Similar to Connections and My Logins, Files is another tool in the toolbelt that your agents can refer to to get the job done. Files supports any file up to 50 MB. Once you upload a file to Files, you will be able to give individual agents access to it. Files ## How to upload a file to Files To upload a file to Files, simply click on "Upload Files" and select a document from your computer. Upload Files ## How to give an agent access to files ### Manually Once you have uploaded files into Files, you can give individual agents access to specific files. To do this, go to the agent you want to give access to via the *Assignments* section in the left sidebar, and click on the files block to edit access to specific files. Agent Files Access Once you give an agent access to a specific file from your Files, you will see it appear in the Files section as an icon. Files Icon ### Using Agent Builder The Agent Builder sees all available files in Files for the team and can add files to the agent setup if instructed. This reflects the same mechanics as the connection principle. ## Real-World Example ### Example 1: Write on-brand marketing email copy Your company has a specific and well-defined brand voice used for all customer communications. The email copywriter wants to make sure that the next campaign follows the brand voice guidelines. The copywriter uploads the Brand Voice Guidelines to Files and asks the agent to create copy for the next marketing campaign following those guidelines. ### Example 2: Extract data from technical documents Your team has a bunch of technical revision documents for all the fire extinguishers at your offices. Each document has the date of revision, the type of fire extinguisher, and other important information on the revision. You want to make sure that your team can easily access this information in a fast way, without having to individually dig through numerous documents. You upload the documents into Files and create an agent that extracts the important information from each document and stores it in a single table, so your team can have everything neatly organized in one place without having to transcribe the information manually. ## Things to know * Files allows you to give additional context and information to your agents. * You can update Files at any time * You can grant or remove access to specific documents from Files for agents anytime. * The Agent Builder sees all files and can add them during the creation process # Designing Human-in-the-Loop Workflows Source: https://docs.duvo.ai/user-guide/assignment-features/hitl-design Decide where humans belong in the loop, choose the right approval shape, and set escalation thresholds before an incident reaches production. This guide helps you decide where humans belong in the loop, choose the right approval shape, and set escalation thresholds before you encounter an incident in production. For a reference on the mechanics of creating approval requests — how to write AOP instructions, respond via Slack, or manage Requests — see [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop). ## When to Add an Approval Step Not every step needs human review. Use this risk framework to decide where approval gates add genuine value and where they only add friction. ```mermaid theme={"dark"} flowchart TD A[Agent is about to take an action] --> B{Irreversible external?
Tier 1} B -->|Yes| G[Always gate] B -->|No| C{Destructive internal?
Tier 2} C -->|Yes| G C -->|No| D{High-value transaction?
Tier 3} D -->|Above threshold| G D -->|No| E{Ambiguous interpretation?
Tier 4} E -->|Low-confidence match| G E -->|No| F{Routine and reversible?
Tier 5} F -->|Yes| H[Skip the gate] F -->|No| G ``` ### Risk tier framework | Tier | Action type | Examples | Default stance | | -------------------------------- | ------------------------------------------------- | ----------------------------------------------------------- | ------------------------------ | | **1 — Irreversible external** | Sends something that cannot be recalled or undone | Outbound email, publish to public channel, submit a payment | Always gate | | **2 — Destructive internal** | Removes or overwrites data | Delete records, overwrite fields, archive items | Always gate | | **3 — High-value transaction** | Financial or compliance impact above a threshold | Approve purchase order, grant access, sign contract | Gate above threshold | | **4 — Ambiguous interpretation** | Agent cannot reliably determine intent | Categorizing a one-off case, routing to the right team | Gate on low-confidence matches | | **5 — Routine and reversible** | Can be corrected without consequence | Tagging a record, updating a status, creating a draft | Skip the gate | A practical starting point: start with an approval gate on all Tier 1 and 2 actions. Remove gates only after you have observed that a branch never produces surprises. ### Decision criteria by action category | Category | Gate? | Notes | | ---------------------------------- | ----------- | -------------------------------------------------------------- | | Send email to external recipient | Yes | Include recipient, subject, and full body in the request | | Post to a public Slack channel | Yes | Include the channel name and draft text | | Submit a financial transaction | Yes | Include amount, recipient, and reference number | | Modify or delete a customer record | Yes | Include the record ID and the proposed change | | Reply to an internal thread | Usually not | Gate only if the reply is policy-sensitive | | Tag or label a record | No | Reversible; iterate without a gate | | Create a draft (not sent) | No | Show in the approval request instead of gating during creation | ## Choosing the Right Approval Shape The Human-in-the-Loop connection supports three request types. Picking the right one keeps operators efficient and prevents ambiguous responses. Use when the agent has already determined what to do and just needs a go/no-go before acting. **When it fits:** The agent is about to send an email, submit a payment, or delete a batch of records. **AOP pattern:** ``` Before sending the email, request approval. Set the title to "Send to [recipient] — [subject line]". Include the full email body in the description. Only send after approval. If denied, ask what to change and revise. ``` Use when the right next step depends on context the agent does not have, and the options are well-defined. **When it fits:** The agent needs to route a case, choose a tone, or decide between two valid policies. **AOP pattern:** ``` If the invoice currency does not match the vendor's default, ask: (a) Convert to USD at today's rate and continue (b) Flag for manual review by the finance team (c) Reject and return to sender with a note ``` **Design rules for good options:** * Keep option labels short and action-oriented. * Make options mutually exclusive — if they overlap, the operator will guess. * Do not add an "Other" option unless you also tell the agent what to do with a free-text answer. Free-text operator input makes sense when the operator needs to supply content, not just choose a path: dictating a reply, providing context about an anomaly, or overriding a specific field value. **Risk:** Free-text answers must be parsed by the agent in its next step. If the agent expects a decision but gets prose, it may misinterpret. Only use free-text when the agent's AOP explicitly handles open-ended input. **Common mistake:** Using a free-text question where a structured Question would do. Structured options are faster for operators and produce more reliable downstream behavior. ## Designing Fallback and Escalation Behavior Every approval gate needs an explicit answer to "what happens if no one responds?" Without a defined fallback, the agent stalls indefinitely or makes an unsafe assumption. ### Timeout → escalate or fail-safe Decide up front: if the operator does not respond within a reasonable window, should the agent escalate or default to the safe action? **Escalate pattern:** ``` Request approval with a 4-hour timeout. If not approved within 4 hours, ask the account manager: [same options]. If still no response after 24 hours, cancel the action and notify the original requester. ``` **Fail-safe default pattern:** ``` Request approval before sending the refund. If not approved within 2 business days, cancel the refund and log the reason as "Approval timeout". ``` Use the escalate pattern when delay is costly (outbound communications, time-sensitive transactions). Use fail-safe defaults when the safe outcome is to do nothing and revisit manually. ### Repeated rejection → halt If the operator rejects the same action multiple times, the agent has likely misunderstood the requirement. Continuing to loop wastes operator time. ``` If the approval is denied twice in a row for the same case, stop and add a note: "Halted after two rejections — requires manual review." Mark the case as Failed. ``` ### Multi-tier escalation For high-stakes workflows, define a clear escalation chain so a request never hangs waiting for a single person. ``` Request approval from the team lead. If not answered within 2 hours, escalate to the department head. If not answered within 24 hours, escalate to the account manager and halt processing until resolved. ``` Keep escalation chains short. More than three tiers signals a process that is not well-defined. ## Using Queue to Manage Exceptions at Scale When an agent processes many cases, Requests becomes a bottleneck. The [Queue](/user-guide/assignment-features/case-queue) is the right tool for managing exceptions across high-volume workflows. ### Triage pattern 1. **Consumer agent** processes cases automatically. 2. Cases that need a human decision surface as **Needs Input** in the queue. 3. An operator reviews the **Needs Input** filter, responds in the case detail panel, and the agent resumes. 4. Cases the agent cannot resolve at all land as **Failed** — the operator reviews, updates the case data, and retries. This separates routine processing from exception handling: the agent handles volume, the operator handles judgment calls. ### Bulk delegation for surges When a backlog of Needs Input cases accumulates, you can select multiple cases and delegate them to a specialist agent — one designed specifically for exception handling — rather than asking one person to respond to dozens of individual HITL requests. ### Aging and escalation logic For cases that sit in Needs Input beyond an acceptable window: ``` After processing the case, if it moves to Needs Input, postpone it for 24 hours. On retry, check whether the human has responded. If not, escalate to the team lead by asking a question: (a) Proceed with the default option, (b) Assign to a specialist, (c) Close the case. ``` ## Ramping Toward Safe Autonomy The goal is not maximum oversight — it is the right level of oversight. As an agent matures, you should expect to remove approval gates where they no longer provide signal. When you first deploy an agent, add approval gates on all Tier 1-2 actions and any branch where you are unsure what the agent will do. After a few weeks of production traffic, review the pattern of approvals and denials in Requests or the Runs list. Estimate the approval rate per gate. * **Approval rate above \~95%**: The agent is getting it right consistently. Consider removing the gate and trusting the output directly. * **Approval rate below \~70%**: The agent is frequently wrong. Refine the AOP before removing the gate. * **High denial rate with a consistent pattern**: The agent is doing the same wrong thing repeatedly. Update the AOP to correct the root behavior. Remove gates one at a time, in order of confidence. Monitor the next two weeks of output. If quality holds, the gate can stay removed. **Do not remove a gate** if: * The action is irreversible and errors are high-cost. * Volume is too low to measure a meaningful approval rate. * You have changed something in the connected systems recently. Re-add approval gates when: * You modify the AOP in ways that could affect the gated branch. * The agent gains access to a new system. * Volume increases significantly (edge cases appear at scale that were rare before). * Approval rate drops during a quarterly review. **Quarterly cadence:** Review approval rates for all agents in production. Prune gates with consistently high approval rates. Re-add gates on branches that have drifted. ## Worked Examples The agent auto-handles low-value expenses and escalates high-value ones through a structured flow. ``` Process each expense report: — Under $200: approve automatically and update the status. — $200–$1,000: request approval. Title: "Approve expense — [employee] — $[amount]". Description: employee name, department, line items. If denied, return to the employee with the reason. — Over $1,000: ask whether to (a) approve, (b) deny, or (c) escalate to the finance director. If no response within 1 business day, escalate automatically. ``` See the full tutorial: [Expense Report Approval](/user-guide/examples/expense-report-approval) The agent drafts a reply and holds it for review before sending. ``` Draft the reply email. Request approval before sending. Title: "Send reply to [customer name] — [ticket ID]". Description: the full draft email body. If approved, send immediately. If denied, ask: (a) Revise the tone to be more formal, (b) Revise the tone to be more empathetic, (c) Escalate to the account manager. Regenerate based on the selected option and request approval again. ``` See a related example: [Reviewing Drafts Before Sending](/user-guide/examples/reviewing-drafts-before-sending) The agent follows up on outstanding purchase orders and escalates if no response arrives. ``` Send the follow-up email to the supplier. Request approval from the operations lead before sending. Title: "Follow-up: PO [number] — [supplier] — [days overdue] days overdue". If the approval request is not answered within 4 hours during business hours, escalate to the account manager with the same request. If still no response after 24 hours, send the email using the default template and log: "Sent without explicit approval after escalation timeout". ``` ## Related Reference for request types and responding via Slack, Teams, and Requests. Managing and responding to pending approval requests. Queue-based exception handling for high-volume workflows. Risk classification, hard caps, allow/deny lists, and kill switch procedures. Using HITL approval feedback to improve your AOP. Full tutorial showing threshold-based approvals. Full tutorial showing draft review before outbound communication. # Human-in-the-Loop Source: https://docs.duvo.ai/user-guide/assignment-features/human-in-the-loop Add human approval steps to Duvo agents. Pause workflows for review, approval, or input before the agent continues. Human-in-the-Loop lets your agents pause at specific points and wait for your input before continuing. Use it to keep a human decision in the loop wherever your workflow requires review — approving a risky action, answering a follow-up question, or checking a draft before it goes out. Human-in-the-Loop is a built-in connection. No setup is required — it is available for every agent automatically. ## How it works ```mermaid theme={"dark"} flowchart TD A[Agent reaches a checkpoint in the AOP] --> B{Request type} B -->|Approval| C[Proposes an action] B -->|Question| D[Asks you to choose an option] B -->|Login| E[Requests a login] C --> F[Delivered to Requests, live run, Slack, or Teams] D --> F E --> F F --> G{Your response} G -->|Approve / Answer| H[Agent continues] G -->|Deny| I[Agent follows the fallback in your AOP] ``` ## When to Use It Human-in-the-Loop is the right tool when: * **The action is irreversible** — sending an email, deleting records, submitting a form, making a payment * **The decision requires judgment** — exception handling, ambiguous requests, policy edge cases * **Compliance requires sign-off** — expenses over a threshold, contract changes, PII-related actions * **You want to review a draft first** — see what the agent will send or publish before it does If a step is routine and low-risk, let the agent handle it on its own. Reserve Human-in-the-Loop for steps where a wrong decision would be costly or embarrassing. ## Request Types Agents can send three types of requests: The agent presents a proposed action and waits for you to confirm or reject before proceeding. **What you see:** A request with a title summarizing the action and a description providing the context you need to decide. * **Approve** — the agent continues with the proposed action. * **Deny** — the agent receives your rejection and follows whatever fallback you defined in the AOP (for example: skip this step, try an alternative, or stop). **Example AOP instruction:** ``` Before sending any email to a customer, request approval. In the title, include the recipient and subject line. In the description, include the full email body. Only send after receiving approval. ``` The agent asks you to choose from a set of options before it decides how to proceed. Use this when the right next step depends on context only you have. **What you see:** A question with selectable options. Pick one and submit — the agent receives your answer and continues down the correct path. **Example AOP instruction:** ``` If the customer's request cannot be resolved automatically, ask the user: (a) Reply asking for clarification, (b) Escalate to the account manager, or (c) Close the ticket. ``` The agent needs a login to access a system it has not been authorized for. It pauses and directs you to add the login in **Resources > Logins and Secrets**. Once the login is saved, the agent continues. ## Adding Approval Gates to Your AOP You control exactly where approvals happen by writing them into your AOP. You do not configure Human-in-the-Loop separately — just describe the checkpoint in plain language and the agent will pause there. **Review before sending:** ``` Draft the reply but do not send it. In the approval title, include the recipient and subject. In the description, include the full draft body. Only send after I approve. ``` **Threshold-based gate:** ``` Auto-approve refunds under $200. For refunds between $200 and $1,000, request approval with the customer name, order ID, and reason. For anything over $1,000, ask whether to approve, deny, or escalate to the finance team. ``` **Content review before publishing:** ``` Generate the post and request approval before publishing. If I deny, ask what to change and regenerate the content. ``` **Exception routing:** ``` If the issue cannot be categorized automatically, ask whether to route it to tier-1 support, tier-2 support, or the customer success team. ``` **Batch summary gate:** ``` After processing all line items, show me a summary of the changes and request approval before committing any updates to the system. ``` ### Writing good approval request titles The title is the first thing you see when a request arrives. Write your AOP so the title includes the specific details, not just "Requesting approval." For example: * "Send invoice to Acme Corp — \$4,200 due 2026-06-01" * "Delete 47 archived records from the leads table" * "Publish blog post: 5 Ways to Cut Procurement Costs" You can instruct the agent explicitly: ``` When requesting approval, set the title to "[action] — [key detail]". ``` ## Responding to Requests You can respond wherever you work. The agent waits and resumes the moment you reply. [Requests](/user-guide/assignment-features/requests) is your central queue for all pending requests. A badge in the left sidebar shows the count of pending items. Requests appear the moment an agent pauses. To respond: 1. Open Requests from the left sidebar. 2. Click the request to open the detail panel. 3. For approvals: click **Approve** or **Deny**. 4. For questions: select your answer and submit. The agent resumes immediately after you respond. When you are watching an agent run in real time, approval requests appear directly in the session window. You can approve or answer without leaving the run view — the agent is waiting and will continue as soon as you respond. If you have connected Slack and enabled notifications, pending requests are delivered as direct messages from the Duvo bot. Each message includes the request title, description, and interactive buttons. * Tap **Approve** or **Deny** directly in Slack — no need to open Duvo. * For questions, select your answer from the options in the message. * Once you respond, the message updates to confirm the outcome and the agent resumes. To enable Slack notifications, go to **Settings > Notifications** and connect your Slack account. Pending requests arrive as Adaptive Cards in Microsoft Teams. Select your response directly from the card. To enable Teams notifications, connect Teams at the team level, link your personal Teams account, then enable **Requests in Microsoft Teams** under **Settings > Notifications**. ## Managing High Volumes When an agent generates many requests — for example, a batch job that reviews dozens of items — use the bulk actions in Requests to keep up: * **Mark all as responded** — dismisses all pending requests at once. Use this when a backlog of requests no longer needs individual review. * **Delete all responded** — removes answered requests to keep the inbox clean. * **Delete all** — clears everything, both pending and answered. You can also filter by **status** (Pending / Answered) and **type** (Approval / Question) to focus on what matters most before taking a bulk action. ## Practical Examples Add this to any agent that sends messages on your behalf: ``` Draft the message but do not send it. In the approval title, include the recipient and subject. In the description, include the full body. Only send after I approve. If I deny, ask what to change and revise. ``` Add this to an expense-processing AOP: ``` Auto-approve expenses under $200. For $200 to $1,000, request approval with the employee name, amount, and justification. For over $1,000, ask: approve, deny, or escalate to the finance director? ``` Add this before writing to a live system: ``` Before updating any records, summarize the changes you are about to make and the number of rows affected. Request approval before committing. If denied, stop and report what was skipped. ``` Add this to a support or operations agent: ``` If the case does not match any standard category, ask: should I route this to tier-1 support, tier-2 support, or the customer success team? ``` ## Tips **Define the rejection behavior.** Tell the agent what to do if denied. Without a fallback, it may stop entirely or retry the same action. **Use questions for branching.** When the right path depends on context you have but the agent does not, use a question rather than a yes/no approval. **Do not overuse approvals.** Every approval gate adds wait time. Use them only for decisions that genuinely require human judgment, and let the agent handle routine steps on its own. **Test the pause behavior.** Run the agent once and verify it pauses where you expect, and that the approval title and description give you enough context to decide without opening other systems. ## Related When to add approval gates, how to choose request types, escalation patterns, and ramping toward safe autonomy. Where you manage and respond to all pending requests. Run agents automatically so requests appear in your inbox. A full tutorial showing Human-in-the-Loop in a finance workflow. # Learning Feature Source: https://docs.duvo.ai/user-guide/assignment-features/learning-feature Capture a successful run as a learning so an agent replicates that good example and improves over time. ## Introduction The Learning feature helps your agents improve over time. When an agent completes a task particularly well, you can capture that success as a "learning" that guides future runs. ## What is Learning? Learning allows you to tell an agent: "This is how you should handle this type of task." By marking a successful run as a learning, you help the agent understand what good looks like. Think of it as positive reinforcement—showing the agent an example of excellent work so it can replicate that success. ## Why Use Learning? ### Improve Consistency When an agent handles a task perfectly, capture that approach so future runs follow the same pattern. ### Handle Edge Cases If an agent successfully navigates a tricky situation, save that learning so it knows how to handle similar cases. ### Refine Over Time As you work with an agent, you can continuously improve it by adding learnings from its best performances. ### Reduce Instruction Complexity Instead of writing detailed instructions for every scenario, let the agent learn from examples of good work. ## How to Create a Learning Go to your agent's run history. Find a run that completed the task excellently. Click the **Create Learning** button at the top of the run. The agent will now reference this run for guidance. While viewing a run in progress or just completed: If the run is going well, look for the **Create Learning** option. Click to save this run as a learning. Future runs will benefit from this example. ## How Learning Works When you create a learning: The agent analyzes what made that run successful. It extracts patterns and approaches used. Future runs reference this learning for guidance. The agent applies similar approaches to new tasks. The learning becomes part of how the agent approaches its work—like institutional knowledge that improves performance. ## Best Practices ### Choose Representative Examples Select runs that: * Completed the task correctly * Handled the typical case well * Demonstrate the approach you want * Produced the output quality you expect ### Avoid Edge Cases Initially Don't make unusual situations the learning: * Start with standard, successful runs * Edge cases can create unexpected patterns * Build a foundation with typical examples ### One Learning at a Time Each agent carries only one learning: * Creating a new learning replaces the old one * Choose your best example * Update when you find a better example ### Review Results After creating a learning: * Monitor subsequent runs * Verify the learning improves performance * Adjust if results aren't as expected ## Real-World Examples ### Example 1: Email Responses Your agent drafts customer responses. One response was particularly well-written—professional tone, addressed all concerns, and followed brand guidelines perfectly. **Create a learning from this run.** Now future responses will follow this high-quality example. ### Example 2: Data Processing Your agent extracts data from invoices. One run correctly handled a complex invoice with multiple line items and applied the right categorization. **Create a learning from this run.** The agent now knows how to handle similar complex invoices. ### Example 3: Report Generation Your agent creates weekly reports. One report had exactly the right structure, formatting, and level of detail. **Create a learning from this run.** Future reports will follow this successful template. ## Limitations Agents carry only one learning at a time: * New learnings overwrite previous ones * Choose your best example carefully * You can always update the learning later The learning influences behavior but: * Isn't shown directly in the instructions * Works behind the scenes * Complements your written instructions Learnings work best when: * The task is similar to the learned example * Inputs are comparable * Expected outputs are consistent ## Things to Know * Learning helps agents improve through positive examples * Only one learning can be active per agent * Creating a new learning replaces the previous one * Learnings work alongside your written instructions * Choose runs that represent your best outcomes # Requests Source: https://docs.duvo.ai/user-guide/assignment-features/requests Your central queue for reviewing, responding to, and managing requests from agents that need human input. ## Introduction Requests is your central queue for handling requests from agents that need human input. When an agent reaches a point where it requires your approval or needs you to answer a question, it sends a request to Requests. You can review, respond to, and manage all of these requests in one place. ## Key Concepts **Request types:** * **Approval** — The agent needs you to confirm or reject a decision before it can proceed. * **Question** — The agent needs you to provide an answer or additional information. **Statuses:** * **Pending** — The request is waiting for your response. Your agent is paused until you act. * **Answered** — You have responded and the agent has continued. ## Where to Find It Requests is located in the left sidebar under your workspace. A badge on the icon shows the number of pending requests so you can see at a glance when agents need your attention. ## Viewing Requests The inbox lists all requests with their title, description, the agent that sent them, the request type, and a timestamp. Use the filters at the top to narrow the view: * **By status** — Show only Pending or Answered requests * **By type** — Show only Approval or Question requests Click on any request to open a detail panel on the right side of the screen, which shows the full context of the agent run that generated the request. The header of the detail panel displays the agent name as a link — click it to navigate directly to the specific Run that sent the request. ## Responding to Requests To respond to a pending request: Click on the request to open the detail panel. Type your response in the text field. Submit your answer. The agent will resume with your input. You can also mark a request as responded without providing a text reply if the agent no longer needs the input. ## Bulk Actions When managing a large number of requests, use the bulk actions available at the top of the inbox: * **Mark all as responded** — Clears all pending requests at once. * **Delete all responded** — Removes answered requests from the list. * **Delete all** — Clears the entire inbox. Requests can also be answered in bulk through the Public API — up to 100 in a single call. ## Real-Time Notifications Requests updates in real time. When a new request arrives: * A toast notification appears on screen. * The sidebar badge counter increments. You do not need to refresh the page to see new requests. ## API Webhook Status For agent runs triggered via the API, Requests shows the webhook delivery status alongside the request details. This lets you verify whether external systems were notified when a request was created or resolved. ## Related Using Requests as a daily health signal during the first week after an agent goes live When to add approval gates, escalation patterns, and how to manage exceptions at scale How to write AOP approval instructions and respond via Slack or Teams # Scheduling Agents Source: https://docs.duvo.ai/user-guide/assignment-features/scheduling-assignments Schedule Duvo agents to run automatically on a recurring basis. Set up daily, weekly, or monthly runs with cron-style flexibility. Agents can be scheduled to run automatically at regular intervals, eliminating the need for manual intervention on recurring tasks like daily reports, weekly inventory checks, or monthly reconciliations. Agents can also self-schedule during a Run — for example, a workflow that processes a request can automatically schedule a follow-up check without any separate configuration. *** ## How to Schedule an Agent Open your agent in the Duvo workspace. Click the **Schedule** button (or the calendar icon) in the agent header. In the panel that opens, select the **Schedules** tab (calendar icon) for time-based schedules, or the **Triggers** tab (lightning bolt icon) for event-driven triggers. See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for trigger setup. Use the frequency picker or describe the schedule in plain language. Click **Add schedule** to save it. ### Setting a frequency Use the frequency picker to select from common presets: * **Every Hour** — runs at the start of each hour * **Every Day** — runs once per day at a time you choose * **Every Weekday** — runs Monday through Friday at a time you choose * **Every Week** — runs on a specific day of the week at a time you choose * **Every Month** — runs on a specific day of the month at a time you choose * **Custom** — enter a cron expression directly for precise timing ### Using plain-language input Type a description in the text field (for example, "every weekday at 9am" or "first Monday of the month at noon") and the system converts it to the equivalent schedule automatically. *** ## Multiple Schedules An agent can have up to 5 active schedules at the same time. This lets you cover multiple cadences without creating separate agents — for example, running a daily summary at 8am and a weekly digest every Friday at 5pm. Each schedule appears as a separate row in the Schedule modal. To remove a schedule, click the delete icon on the row and confirm. *** ## Managing Schedules **Viewing status**: Agents with active schedules display a "Scheduled" badge in the agent list. **Pausing or removing**: Open the Schedule modal and delete a schedule row to stop it. Add it back any time to resume. **Monitoring**: Each scheduled Run appears in the agent's session log so you can track performance over time. **One-time schedules**: Schedules set up to run once (for example, via the API) automatically retire after they fire. They do not repeat. *** ## Self-Scheduling During Execution Agents can create, update, or delete their own schedules while a Run is running. This lets your AOP instruct the agent to manage its own cadence based on what it finds. For example, an agent monitoring a supplier's delivery status might: 1. Check the current status 2. If the order is still pending, schedule itself to check again in 24 hours 3. Once the order ships, cancel the follow-up schedule To enable self-scheduling, write your AOP to explicitly instruct the agent when and how to schedule follow-up runs. The agent handles the scheduling automatically — no separate configuration is needed. *** ## Common Scheduling Patterns Most automations fit one of these four patterns. Choosing the right one shapes how you write the AOP and configure the trigger. ### Recurring digest **When to use it**: You want a formatted summary — report, roundup, briefing — delivered to a person or channel on a fixed cadence. **How it works**: Schedule the agent to run at a set time (daily, weekly, or monthly). The AOP pulls data from one or more sources, formats the result, and delivers it via Slack, email, or a spreadsheet. The agent does nothing between Runs. **Examples**: * Weekly KPI summary posted to Slack every Monday at 7am * Daily inbox roundup emailed to the ops manager at 8am * Monthly reconciliation report written to Google Sheets on the first of each month Include a sanity check in your AOP — if the numbers look out of range, alert the owner instead of distributing a potentially wrong report. *** ### Continuous monitoring with threshold alerting **When to use it**: Something needs to be watched regularly, but you only want to hear about it when a condition is met — not every time the agent runs. **How it works**: Schedule the agent to run every hour (or every 15 minutes for time-critical metrics). The AOP checks a data source against a defined condition. If the condition is not met, the agent stops silently. If it is met, it sends an alert. **Examples**: * Inventory alert when any SKU drops below the reorder point * Slack notification when a fraud rate crosses 2% * Email to the finance team when a daily expense total exceeds budget Add a deduplication instruction to your AOP — for example, "do not alert if the same condition was already alerted in the last 4 hours" — to prevent repeated notifications for an issue already in progress. *** ### Event-driven trigger with scheduled follow-up **When to use it**: A workflow starts from an event (an email, a Slack mention, a file upload) and needs to check back later without human involvement. **How it works**: The agent starts from a trigger (not a schedule), processes the initial event, and then uses self-scheduling to arrange a follow-up Run. The follow-up check can itself reschedule or cancel depending on what it finds. **Examples**: * Process an order email immediately; follow up 48 hours later if no corrected response arrives * Acknowledge a supplier query when it lands; re-check the supplier's status every 24 hours until the delivery ships * Start a Run from a Slack mention; send a progress update to the thread 30 minutes later See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for how to set up the initial trigger, and [Self-Scheduling During Execution](#self-scheduling-during-execution) above for the follow-up mechanism. *** ### Batch processing window **When to use it**: A high-volume agent needs to run once per day, preferably during off-peak hours, to process a backlog that has accumulated since the last Run. **How it works**: Schedule the agent to run at a quiet time — overnight, early morning, or end of day. The AOP processes all unhandled items (emails, records, files) since the last Run in a single session. **Examples**: * Process all unread order emails overnight at 2am * Reconcile all completed transactions from the day at 11pm * Generate invoices for every run closed during the day, sent at 6pm For large batches, add a pause instruction between items (e.g., "wait 2 seconds between each record write") to avoid hitting rate limits on external systems. *** ## Related Features Run agents on events instead of (or in addition to) a time-based schedule. Start Runs from new files in cloud folders or inbox attachments. Start Runs when CRM or project management records change state. Start Runs from channel messages without mentioning the Duvo app. # Slack Channel Triggers Source: https://docs.duvo.ai/user-guide/assignment-features/slack-channel-triggers Start Duvo agents automatically from Slack channel activity — every message, keyword matches, or an emoji reaction — without anyone mentioning the Duvo app. Slack channel triggers let your agents start automatically from activity in a Slack channel — without anyone needing to mention the Duvo app. Use them to monitor channels continuously, process every message that matches a pattern, or react to a specific emoji on a message. This page covers **automated channel triggers**. For on-demand workflows started by a team member mentioning the Duvo app, see [Slack Mention Workflows](/user-guide/examples/slack-mention-workflows). ## Key Capabilities * **Channel message trigger** — Start a Run automatically from every new message in a channel, or from messages containing specific keywords or patterns * **Reaction trigger** — Start a Run when someone adds a specific emoji reaction to a message (for example, `white_check_mark` to approve, or `ticket` to create a ticket) * **Scheduled channel digest** — Run a scheduled agent that reads recent channel messages and produces a summary, alert, or report on a time-based cadence * **Bot and third-party app message support** — Capture structured messages from Jira, GitHub, PagerDuty, and other Slack integrations, not just messages from humans * **No mention required** — Team members do not need to tag the Duvo app; the trigger fires silently in the background *** ## How Channel Message Triggers Work The **Channel Message trigger** is a push-based trigger: the Duvo app listens to the channel and starts a Run for every new message (or every message matching your keyword filter). It fires within seconds of the message being posted. If multiple agents have a matching Channel Message trigger on the same channel, they all start simultaneously — there is no selection menu. Use keyword filters to prevent unintended overlaps. **Reaction triggers** work the same way: the Duvo app listens for emoji reactions in enabled channels and starts a Run when the configured reaction is added. **Scheduled digests** use a time-based schedule rather than a real-time trigger. The agent runs at a set time, reads the recent message history of the channel, and produces output. *** ## Choosing the Connection for a Trigger When you create or edit a Slack (or Microsoft Teams) channel trigger, you choose **which connection** backs it using the connection picker on the trigger. If your organization has Connections sharing enabled, the picker groups connections into two sections: * **Team** — connections a teammate has shared with your team * **Personal** — connections you set up under your own profile A **channel trigger can run on a team-shared connection**, so the Duvo app can listen to a channel through a connection a teammate installed — every agent owner does not need to install the app themselves. **@mention triggers always run as the mentioning user.** A Slack or Microsoft Teams @mention trigger uses the mentioning person's own personal connection, so it cannot use a team-shared connection. Only **channel** triggers can be backed by a shared connection. If an org admin turns Connections sharing off, shared connections revert to their creator, and any channel triggers other users had pinned to those shared connections are automatically disabled. The creator's own triggers keep working. *** ## When to Use Channel Triggers * **#alerts or #incidents** — Every alert that lands in the channel is automatically triaged, deduplicated, or escalated without anyone reading and forwarding each message * **#support-inbox** — Every inbound support message is read, categorized, and a ticket is created — no manual scanning required * **Weekly digest** — On Friday at 5pm, summarize everything posted in #operations that week and send the digest to stakeholders * **Approval shortcut** — Team members react with the `white_check_mark` emoji on a pending item in #approvals to trigger the approval workflow, without opening a separate tool * **Monitoring** — Watch #deploys or #ci-alerts for failure patterns and post a summary to the engineering team each morning *** ## How to Set It Up Fires on every matching message. Open your agent and go to **Setup**. Find the **Slack Workspace** connection in the Connections section. Enable the **Channel Message** trigger. Select the channel you want to monitor. Choose which connection backs the trigger. If Connections sharing is enabled, pick a **Team** (shared) connection or one of your **Personal** connections. Channel triggers can run on a team-shared connection. Optionally enter keywords or patterns. The trigger fires only when a message contains one of these terms. Leave empty to fire on every message in the channel. Save. **Prerequisites**: The [Slack Workspace connection](/user-guide/connections/available-connections/slack-workspace) must be installed by a team admin, and the Duvo app must be invited to the target channel (`/invite @Duvo`). Fires when a specific emoji is added. Open your agent and go to **Setup**. Enable the **Slack Reaction** trigger. Select the channel to monitor. Choose which connection backs the trigger. If Connections sharing is enabled, pick a **Team** (shared) connection or one of your **Personal** connections. Channel triggers can run on a team-shared connection. Enter the emoji name (for example, `white_check_mark` or `ticket`). Save. When a team member adds the configured reaction to any message in the channel, Duvo starts a Run and passes the original message content as context. Fires at a set time. Channel digests use a scheduled agent rather than a real-time trigger. Open your agent and go to **Setup**. Set a **schedule** — for example, every Friday at 5pm, or every weekday at 8am. Write your AOP to read recent message history from the target channel and produce the desired output. Add the **Slack** connection so the agent can read channel history and post replies. *** ## Worked Example 1 — #support-inbox Triage **Outcome**: Every message posted in #support-inbox is automatically read, categorized, and routed. A ticket is created in your issue tracker and the poster receives an acknowledgment — without a human scanning the channel. **Connections used**: * Slack Workspace — triggers from channel messages * Slack — reads the message thread and posts replies (required for actions beyond the trigger thread) * Linear — creates tickets for engineering issues * Human-in-the-Loop — escalates ambiguous or urgent requests ### Trigger setup Enable the **Channel Message** trigger on the agent. Select **#support-inbox** as the channel. Leave keyword filter empty so every message starts a Run. ### AOP ``` You will receive a message from the #support-inbox Slack channel. 1. Read the message and any files or images attached to it. 2. Classify the request: - Bug report: something is broken or behaving incorrectly - Feature request: the user wants something new or changed - Question: the user needs information or help - Urgent: anything flagged as blocking, critical, or production-down 3. For bug reports and urgent issues: - Create a Linear issue titled "[Bug] [one-sentence summary]" in the [your team] team. - Set priority to Urgent for urgent issues, Medium for standard bugs. - Post a reply in the #support-inbox thread: "Logged as a bug — ticket created: [Linear issue link]." 4. For feature requests: - Create a Linear issue titled "[Feature Request] [one-sentence summary]" with priority Low. - Post a reply: "Thanks — logged as a feature request: [Linear issue link]." 5. For questions: - Search [your knowledge base or Notion] for an answer. - If a clear answer is found, post it in the thread. - If no answer is found, post: "Good question — escalating to the team." and send a Human-in-the-Loop request to [on-call Slack handle] with the question and context. 6. For urgent issues, also post in #engineering: "Urgent support issue: [summary]. Ticket: [link]." ``` ### Expected results * Every message in #support-inbox triggers a Run within seconds. * Bug reports and feature requests get a Linear ticket and a thread acknowledgment automatically. * Questions are answered from the knowledge base or escalated to the on-call engineer. * The channel stays organized — every message gets a response, nothing is missed. *** ## Worked Example 2 — Reaction-Based Approval in #approvals **Outcome**: Finance and operations team members post pending approvals in #approvals. A reviewer adds a `white_check_mark` reaction to approve, or an `x` to reject. The agent detects the reaction, records the decision, and notifies the requester. **Connections used**: * Slack Workspace — reaction trigger * Slack — post DM to the requester and reply in the channel * Google Sheets — log the approval decision ### Trigger setup Enable the **Slack Reaction** trigger on the agent. Select **#approvals** as the channel. Set the emoji to `white_check_mark` for approvals. Create a second agent with `x` for rejections, or handle both reactions in one AOP. ### AOP ``` You will receive a Slack message that had a reaction added to it, along with the reaction emoji and the name of the person who added it. 1. Read the original message to understand what is being approved or rejected. 2. Determine the decision: - If the reaction is white_check_mark: approved - If the reaction is x: rejected 3. Extract the requester's Slack username from the original message. 4. Log the decision in the "Approvals" Google Sheet with: - Date and time - Requester name - Approver name - Decision (Approved / Rejected) - Summary of what was approved 5. Send a Slack DM to the requester: - If approved: "Your request has been approved by [Approver Name]. Reference: [row number in sheet]." - If rejected: "Your request was not approved by [Approver Name]. Reply here with questions." 6. Post a reply in the #approvals thread confirming the decision is recorded. ``` ### Expected results * A reviewer adds the `white_check_mark` reaction on any message in #approvals. * The requester receives a DM within seconds confirming the decision. * The decision is logged in Google Sheets with a timestamp and approver name. * The original message thread gets a confirmation reply. *** ## Worked Example 3 — Weekly #operations Digest **Outcome**: Every Friday at 5pm, Duvo reads the past week of messages in #operations, identifies key decisions, open items, and blockers, and posts a structured summary to #operations-digest. **Connections used**: * Slack — read channel history and post the digest * Human-in-the-Loop (optional) — flag items needing follow-up ### Trigger setup Set a **schedule** of every Friday at 5pm. No Slack trigger needed — the agent runs on the time schedule and reads the channel. ### AOP ``` Read all messages posted in the #operations Slack channel from the past 7 days. From those messages, extract and organize: 1. Decisions made — items that were agreed, approved, or confirmed 2. Open items — questions or tasks raised but not yet resolved 3. Blockers — anything described as blocking, stuck, or waiting on someone 4. Upcoming deadlines — any dates, deliverables, or commitments mentioned Format a digest with these four sections. Keep each item to one sentence. Include the name of the person who raised or resolved each item. Post the digest to the #operations-digest channel with the header: "Operations digest — week of [Monday's date]" If there are more than 3 open items or blockers, also post a Human-in-the-Loop request to the #operations channel: "Weekly digest ready. [N] open items need follow-up." ``` ### Expected results * Every Friday at 5pm, #operations-digest receives a structured summary. * Open items and blockers are surfaced even if they were buried in a busy week of messages. * The team has a single record of decisions and follow-ups without anyone manually reviewing the channel. *** ## Tips **Use keyword filters to avoid overlapping triggers**: If you have two agents with channel message triggers on the same channel, add distinct keyword filters to each (for example, "invoice" and "contract") so they do not both fire on every message. **Write the AOP to handle bot messages**: Slack channels often receive structured messages from Jira, GitHub, PagerDuty, and similar tools. The Duvo app captures these messages including their fields and values. Explicitly instruct your AOP: "If the message is from a bot or app, read its structured content (title, fields, links) as well as any plain text." **Set a cooldown for high-volume channels**: In a channel with dozens of messages per hour, a channel message trigger will start a Run for each one. Confirm your AOP handles this volume, or use a keyword filter to narrow the trigger. **Combine with scheduled digests**: Use a channel message trigger for time-sensitive items (like incidents) and a scheduled digest for summary reporting on the same channel. *** ## Troubleshooting * Confirm the Duvo app has been invited to the channel: `/invite @Duvo` in the channel. * Verify the Slack Workspace connection is active on the [Connections page](https://app.duvo.ai/integrations). * Check that the agent has a published build — draft-only agents cannot be triggered. * If a keyword filter is set, confirm the test message contains the exact keyword (case-insensitive match). * Add a keyword filter to the trigger so only relevant messages start a Run. * Alternatively, keep the trigger broad and add a filter step to the AOP: "If the message does not match \[criteria], stop processing." * The Slack connection (not Slack Workspace) is required for reading channel history. Confirm it is enabled under **Connections** and authorized. * Confirm the agent has permission to read the target channel. Re-authorize the Slack connection if needed. * Emoji names in Slack are case-sensitive and use underscores, not spaces. Use `white_check_mark` not `white check mark`. Find the exact name by hovering over the emoji in Slack and checking the tooltip. *** ## Related Overview of all trigger types and the trigger matrix. On-demand workflows started by mentioning the Duvo app. Install the Duvo app and configure team-level settings. Read channel history and post messages from agents. Set up time-based digests. Escalate items needing human attention from channel digests. # Status-Change Triggers Source: https://docs.duvo.ai/user-guide/assignment-features/status-change-triggers Start a Duvo agent automatically when a record in a CRM or project management tool reaches a particular state — a deal closes, a page moves to review, a ticket is resolved. Status-change triggers let your agents start a Run 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 Run 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** — Agent Memory stores the last-seen status of each record so the agent 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 Run, or trigger one Run 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](/user-guide/assignment-features/event-driven-triggers)). Status-change monitoring is implemented by **scheduling an agent to run on a regular interval** and having the AOP: 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 Agent Memory. 3. Process only the records that genuinely changed since the last Run. 4. Update Agent Memory with the new state before finishing. ```mermaid theme={"dark"} flowchart TD A[Scheduled Run fires on interval] --> B[Query the connected tool for records in the target state] B --> C[Compare against last-seen state in Agent Memory] C --> D{Record genuinely changed since last Run?} D -->|No| E[Skip — already processed] D -->|Yes| F[Process the record's downstream action] F --> G[Update Agent Memory with the new state] ``` | Service | Mechanism | Typical latency | | ----------------------- | --------------------- | -------------------------------------------------------------------------------------------- | | HubSpot | Polling | Equal to schedule interval | | Salesforce | Polling | Equal to schedule interval | | Notion | Polling | Equal to schedule interval | | Jira (via Computer Use) | Polling | Equal to schedule interval | | Linear | Native webhook (push) | Seconds — see [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) | *** ## When to Use Status-Change Triggers * **Sales onboarding** — When a HubSpot or Salesforce deal moves to "Closed Won", start an onboarding agent 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 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. The AOP 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. 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.). Agent Memory is on by default for agents on plans that include it. The AOP will use it to store the IDs of records already processed; open the **Memory** tab to review what it has stored. 1. Click **Schedule** in the agent 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 Run 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 ### AOP ``` 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 agent runs every 15 minutes: * Deals that moved to "Closed Won" since the last Run are identified. * A Human-in-the-Loop approval appears in Requests for each new deal. * After approval, a personalized welcome email is sent and #customer-success is notified. * The deal ID is added to Agent Memory so the next Run does not re-process it. *** ## Adapting for Other Services **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. **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. **Issue status change** — Jira does not have a native Duvo connection. To monitor Jira status changes, use [Computer Use](/user-guide/connections/computer-use-overview) 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 Agent Memory key must be written at the end of each successful Run. If the Run fails partway through, the memory update may not have been saved. Check the session log to see where the failure occurred. * Make sure the AOP adds the ID to memory **before** the Run ends, even if the downstream action fails. Adjust the AOP: "Add the ID to memory regardless of whether the downstream action succeeds." * **Time window too narrow**: The AOP 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 AOP: "Retrieve all pages of results, not just the first." Agent 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 agent** After completing the onboarding Run, schedule a follow-up check 7 days later: ``` At the end of the Run, 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 Agents](/user-guide/assignment-features/scheduling-assignments) for self-scheduling patterns. **Notify via multiple channels** Combine email and Slack in the same Run, 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 agents for each key pipeline stage. When a deal enters "Contract Sent", fire one Run; when it enters "Closed Won", fire another. Each agent handles the actions appropriate to that stage. *** ## Related Overview of all trigger types and the trigger matrix. Set the polling interval. Track last-seen state to avoid duplicate processing. Add approval gates before irreversible actions. Connect HubSpot. Connect Salesforce. Connect Notion. Browser-based access for tools without a native connection. # Agent Builder Source: https://docs.duvo.ai/user-guide/building-assignments/assignment-builder Use the Duvo Agent Builder to create automations by describing tasks in plain English. Build from templates or start from scratch. ## What is the Agent Builder? The Agent Builder is where you describe the task you want Duvo to automate in plain English. It can create new agents from scratch or modify and improve agents you've already built. ## Getting Started: The Welcome Screen When you open a new agent, the builder shows a welcome screen with suggested templates. These cover common workflows and are a quick way to get started. You can: * **Pick a template**: Click any template chip to pre-fill the input with a working example. Edit it or use it as-is before generating. * **Start from scratch**: Click "Start from scratch" to type your own workflow description from a blank input. ### Guided Tour for New Users If this is your first time using the Agent Builder, Duvo walks you through the process with a short guided tour: A template is selected to show how it works. You can edit the pre-filled description or replace it with your own. Hit **Generate** to create a step-by-step workflow from your description. You can skip the tour at any point by clicking "Skip tour." ## How to Use the Agent Builder Consider the workflow you want to automate. What steps do you do manually? What's the end result you're looking for? Write as if you're explaining the task to a coworker. Be specific about: * What the agent should do * *"Check for overdue invoices in NetSuite and send Slack reminders to #overdue"* * *"Update customer records when their subscription status changes"* * *"Monitor inventory levels and create purchase orders when stock is low"* * Where it should get information from * *"Pull data from our CRM"* * *"Read customer feedback from the Google Form submissions"* * *"Get order details from the Orders spreadsheet in Google Drive"* * What actions to take * *"Send an email notification, update the spreadsheet, and post a message in Slack"* * *"Create a new folder in Google Drive, copy template files into it, and share it with the team"* * *"Fill out the vendor form, attach the purchase order, and submit it through their portal"* * Any approvals or checks you want along the way * *"Before sending any email to a customer, show me a draft for approval"* * *"If the purchase order is over \$5,000, send it to me for review before submitting"* * *"Flag any customer records with missing information for me to review before processing"* Click **Generate** to submit your description. Duvo streams the AOP as it builds it, so you can watch the workflow take shape in real time. If the result isn't what you expected, click **Stop** to cancel generation mid-stream and adjust your description before trying again. When the AI modifies an existing AOP — through generation, editing, or refinement — the changes are shown as a visual diff. Additions appear with a green gutter and background, removals with a red gutter, and modified lines show word-level highlights so you can see exactly what changed. This makes it easy to review what the AI adjusted before accepting the result. ## Testing Your Agent Once you've generated an AOP, the right panel of the builder is where you run and test your agent. Before you can start a Run, the builder checks that everything is in place. ### Setup Checklist The builder shows a checklist with what needs to be ready: * **Agent configured**: Your AOP has been generated. * **All connections enabled**: Any connections required by your AOP have been authorized. When both items are complete, the checklist header changes to "Ready to test" and the **Start Work** button becomes active. If connections are missing, the checklist shows which ones still need to be set up—click a connection badge to open the Connections panel and authorize it. ### Testing the Agent Click **Start Work** to start a Run directly from the builder. This lets you test the agent against a real workflow before deploying it more broadly. If your agent is connected to a Queue as a consumer, you can choose which case to test with before starting. A **case selector** appears in the test panel — use it to pick a specific case by name or ID, or leave it on **Next available case** to let the queue dispatch automatically. You can also paste a case URL directly into the selector to jump to a specific item. ### Scheduling from the Builder To run your agent on a recurring schedule, click **Enable Schedule & Trigger** in the execute panel. This opens schedule setup without leaving the builder, so you can configure the cadence immediately after finishing your AOP. If a schedule is already active, the button shows a countdown to the next scheduled run. The builder also detects when your description implies a recurring task. If you write something like "send a weekly report" or "check inventory every morning," a scheduling suggestion appears after generation completes. Click the suggestion to open the schedule setup directly — or dismiss it and set up scheduling manually later. ## Evaluations Tab The Evaluations tab in the builder gives you a performance summary for an agent based on its recent run history. **Eval scores**: Duvo automatically scores completed and failed runs against criteria derived from the agent's AOP. The Evaluations tab shows aggregated scores for the last 24 hours or the last 7 days. Use the time window selector to switch between views. **Issue alerts**: If the same type of failure recurs across multiple recent runs, the tab surfaces a consolidated alert so you can address the root cause in the AOP rather than investigating each failure individually. Click **View past runs** within the tab to jump to the Runs List filtered to this agent. ## View-Only Access If you open an Agent that you do not have permission to edit, the builder shows a **View only** banner at the top. You can still inspect the AOP, review connections, and run the Agent — but edits are disabled. To get edit access, ask an Administrator or Manager to update your role or transfer ownership. ## Remember There's no pressure to get it perfect immediately. The Agent Builder is designed for iteration—you can always come back and refine the AOP as many times as needed. Write in whatever way feels comfortable. # AOP Source: https://docs.duvo.ai/user-guide/building-assignments/assignment-sop Learn how to write an effective AOP so your Duvo agent can execute workflows reliably. ## What is an AOP? An AOP (Agent Operating Procedure) is the detailed, structured rules that your Duvo agent follows to execute your workflow. Think of it as the "operating manual" for your agent—a guide that tells it exactly what to do, when to do it, and how to handle different situations. *** ## How the AOP Differs from the Agent Builder * Purpose: To create and modify the AOP * Format/Style: Your casual, plain-English description - like you're talking to a coworker * Example: `Check for new expense reports and send them to managers for approval` * Purpose: The actual "code" that controls your agent's behavior * Format/Style: Structured, detailed, containing specific logic, conditions, and procedures * Example: ``` Route submitted expense reports to the appropriate managers for approval every Monday. # STEPS 1. Access the expense management system - Navigate to the expense reports dashboard - Filter for reports with status "Submitted" and submission date within the past 7 days - If expense system is unavailable: retry after 30 minutes 2. Retrieve expense report details - For each report found, extract: employee name, employee email, report ID, total amount, submission date, manager name, manager email, line items, and receipts - If report is missing required receipts: return to employee with a note requesting them 3. Determine appropriate approver - Identify the employee's direct manager from the HR system - If no manager assigned: escalate to department head 4. Send approval request - Compose email to manager with: Subject: "Expense Report Approval Required - [Employee Name] - [Report ID]" Body: report summary, total amount, submission date Attachment: expense report PDF Include "Approve" and "Reject" links - If manager email is invalid: notify HR system administrator 5. Log activity - Record date approval request sent and manager notified - Update report status to "Pending Manager Approval" ``` *** ## Formatting Matters The structure and formatting of the AOP significantly impacts how well your agent performs: **Clarity**: A one-sentence GOAL followed by numbered STEPS makes the workflow easy to scan and understand at a glance **Precision**: Bullet points and numbered steps create unambiguous sequences that the agent can follow reliably **Self-contained steps**: Each step includes everything needed to execute it — data formats, expected values, and error handling — so you can review each step independently **Debugging**: When something goes wrong, structured steps make it easy to identify exactly which step needs adjustment **Consistency**: Standardized formatting helps the AI agent interpret the AOP the same way every time, leading to more predictable behavior Think of formatting like punctuation in a sentence—it tells the agent where one thought ends and another begins, preventing misinterpretation. *** ## Tips for Writing Effective AOPs **Mention all systems involved**: List every tool, app, or system your agent needs to access (e.g., "Hubspot," "Gmail," "our internal database"). **Include decision points**: Explain conditional steps clearly (e.g., "If the order is over $5,000, send it for manager approval. If under $5,000, process it automatically"). **Specify approval requirements**: Tell the agent when you want to review actions before they're finalized (e.g., "draft the email for my review before sending"). **Define the output**: Be clear about the end result (e.g., "save the report as a PDF in the shared folder" or "update the status field to 'Complete'"). # From Process Discovery to Working Agent Source: https://docs.duvo.ai/user-guide/building-assignments/clarity-to-assignment Turn a Clarity process analysis into a working Duvo agent. Learn the handoff steps, decisions to make at each stage, and follow a complete worked example from discovery to deployment. When you use Clarity to document a process, you get a complete picture of how work happens today and where automation could help. This guide shows how to take that Clarity output and turn it into a working Duvo agent — covering the decisions to make at each stage and an end-to-end example from start to finish. ```mermaid theme={"dark"} flowchart TD A[Review the Clarity Output] --> B[Decide What to Automate First] B --> C[Build the Agent] C --> C1[Open the Agent Builder] C1 --> C2[Write the AOP] C2 --> C3[Add Human-in-the-Loop Approval Gates] C3 --> C4[Add Connections] C4 --> C5[Test with Start Work] C5 --> D{Result as expected?} D -->|No| C2 D -->|Yes| E[Deploy and expand over time] ``` *** ## Before You Start Make sure these are in place: * [ ] A Clarity process in **Complete** status with at least one capture analyzed * [ ] Team settings configured in **Settings > Clarity** (company name, industry, hourly rate) so the Impact figures are meaningful * [ ] A rough sense of which part of the process you want to automate first — you do not need a fully scoped plan, but a starting hypothesis helps *** ## Step 1: Review the Clarity Output Open your completed process in Clarity and work through the tabs in this order. Each one gives you something specific you will use when building the agent. ### Steps The Steps tab shows a breakdown of each action in the process — who does it, what system they use, what decision they make, and what happens next. Read through the steps and mark the ones that are: * **Good automation candidates**: repetitive actions, data lookups, form submissions, rule-based decisions, and anything the same person does every time the process runs * **Keep human for now**: judgment calls based on context the agent cannot see, sensitive communications, or actions where mistakes are hard to reverse You are looking for a contiguous sequence of steps that can run without human intervention. That sequence becomes the core of your agent's AOP. ### Vision The Vision tab describes what the process could look like once optimized. This is the end state to aim for, not the first version to build. Read it to understand the goal, then set it aside — you will start with a narrower scope and expand over time. ### Impact The Impact tab shows projected financial impact — time saved, cost avoided, and estimated return. Use this to confirm you are automating the right thing first. If the Impact figures are lower than expected, check whether you have captured all the people and systems involved in the process. ### Risk and Vulnerabilities This tab lists the exception cases, edge conditions, and failure points identified in the process. Keep this open when you write your AOP — every risk listed here is a case your agent needs to handle, either by resolving it automatically or by pausing for human review. ### Transformation Guidance The Transformation Guidance tab contains editable guidance that describes how automation could be applied to this specific process. This is the bridge between the Clarity analysis and your agent. Read through the Transformation Guidance. Edit it to reflect any adjustments you want to make — for example, keeping a step human that the AI marked for automation, or noting a specific system connection to prioritize. The guidance you leave here shapes the context your agent operates in. *** ## Step 2: Decide What to Automate First Start with the smallest slice that delivers meaningful value. A common mistake is trying to automate the full end-to-end process in the first version — this makes testing harder and refinement slower. **A good first version:** * Covers three to seven consecutive steps * Has a clear start trigger (a file arrives, a Slack message comes in, a schedule fires) * Produces a clear, verifiable output (a row in a spreadsheet, a message in Slack, an email sent) * Handles the two or three most common exception cases from the Risk and Vulnerabilities tab **Leave for later:** * Steps that require significant judgment or context from outside the process * Edge cases that happen less than once a month * Connections to systems you do not yet have access to *** ## Step 3: Build the Agent 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. Use the Steps tab, Transformation Guidance, and your own notes to write the AOP. Describe the workflow as you would explain it to a colleague, starting with what triggers the agent and ending with the final output. A practical AOP for a Clarity-derived agent includes: 1. **The trigger** — what starts the agent (a schedule, a Slack mention, a file drop, a status change) 2. **The input** — what data or context the agent reads at the start 3. **The steps** — the sequence of actions from the Steps tab, phrased as instructions 4. **Decision logic** — the conditions from the Steps tab that determine which path to take 5. **Exception handling** — what to do when the situations in the Risk and Vulnerabilities tab occur 6. **Approval gates** — where a human should review before the agent proceeds, based on the high-risk steps you identified 7. **The output** — what the agent produces or updates when the run is complete Click **Generate** to create the AOP from your description. Review the output, then refine the description and regenerate if it does not match the workflow. For any step where a mistake would be hard to reverse — sending a customer email, updating a financial record, submitting a form to an external system — add a Human-in-the-Loop step in the AOP: ``` Before [action], send a Human-in-the-Loop request showing: - What you are about to do - The key data you are acting on - The expected outcome Wait for approval before proceeding. If the request is denied, stop and post a summary of what was skipped. ``` See [Designing Human-in-the-Loop Workflows](/user-guide/assignment-features/hitl-design) for guidance on where to place approval gates and how to phrase them. Under **Connections**, enable the connections to the systems involved in the process. Check the Steps tab in Clarity to identify every system that appears — each one needs a connection authorized in the agent. If a system you need is not in the available connections list, see [Building Custom Connections](/user-guide/connections/building-custom-connections). Click **Start Work** to run the agent against a real or representative example. Watch the live execution view to see exactly what the agent does at each step. Compare what you observe to the Steps tab in Clarity — the agent should follow the same sequence. If the result is not what you expected, return to the Agent Builder, note what diverged, and update the AOP. See [Refining Your Agent](/user-guide/building-assignments/refining-your-assignment) for a structured approach to iteration. *** ## End-to-End Example: Supplier Invoice Follow-Up **The situation**: Your procurement team spends about an hour each week chasing suppliers for overdue invoices. The process involves checking a spreadsheet for invoices past their due date, looking up the supplier's contact email in the ERP, drafting a follow-up email, getting a manager's approval, and sending the email. Three people are involved but the work is largely the same each time. **What Clarity found**: * The Steps tab showed seven steps, five of which were the same every time regardless of supplier or invoice amount * The Risk and Vulnerabilities tab flagged invoices over \$50,000 and suppliers with an active dispute as cases that needed extra care * The Impact tab projected 3.2 hours saved per week at current team size * The Transformation Guidance described an automation that reads the overdue invoice list, drafts follow-up emails using templates keyed to invoice age, and routes anything above \$50,000 or flagged as disputed to the procurement manager for review before sending **The scoping decision**: Automate the five repeatable steps. Keep the manager review for high-value and disputed invoices, and start with invoices under \$50,000 to de-risk the first version. **The AOP**: ``` You are a procurement assistant. Your job is to follow up on overdue supplier invoices. Run every Monday at 9:00 AM. Step 1: Read the "Overdue Invoices" tab in the Procurement Tracker spreadsheet. Collect all rows where the Due Date is more than 7 days ago and the Status is "Unpaid". Step 2: For each overdue invoice: - Look up the supplier's accounts payable contact email in the ERP using the Supplier ID column. - If the invoice is over $50,000 or the supplier's "Dispute Flag" column is "Yes", skip it and add it to the escalation list. Step 3: For each remaining invoice, draft a follow-up email: - Subject: "Payment reminder — Invoice [Invoice Number]" - Body: A polite, professional reminder that includes the invoice number, amount, original due date, and a request to confirm the expected payment date. Do not threaten or express frustration. Step 4: Send each drafted email to the supplier's accounts payable contact. Update the Status column in the spreadsheet to "Chased - [today's date]" after each email is sent. Step 5: For any invoices in the escalation list, send a Human-in-the-Loop request to the procurement manager. Include the invoice number, amount, supplier name, and reason for escalation (over $50,000 or dispute flag). Wait for the manager to review before sending — do not send the follow-up email without approval. Step 6: Post a summary in the #procurement Slack channel: how many invoices were chased, how many were escalated for review, and the total overdue amount covered. ``` **Connections added**: * Google Sheets (to read and update the Procurement Tracker) * \[ERP system via Custom MCP] (to look up supplier contact emails) * Gmail (to send follow-up emails) * Slack (to post the summary) **Trigger**: Weekly schedule, Monday at 9:00 AM **First test result**: The agent correctly identified four overdue invoices, drafted professional follow-up emails, and escalated one invoice above \$50,000 to the procurement manager. One email had the wrong contact email because the ERP lookup returned a primary contact rather than the AP contact — the AOP was refined to specify "accounts payable contact" and the test was rerun successfully. **What expanded later**: After two weeks of reliable operation, the team added the disputed invoices workflow (a different email template and a different escalation path) and extended the schedule to run twice a week. *** ## Tips for Better Results **Use the Steps tab as a checklist**: After the first run, compare what the agent did against the Steps tab in Clarity step by step. Any divergence is a specific refinement to make in the AOP. **Copy exception handling verbatim from Risk and Vulnerabilities**: The exception cases in Clarity are grounded in what your subject matter experts described. Copy the language directly into the AOP rather than paraphrasing — it preserves the nuance. **Start the Transformation Guidance with what you want, not what you have**: Before copying the guidance into the AOP, edit it in Clarity to reflect your scoping decision. Remove steps you are keeping human, add notes about the connections you will use, and clarify any ambiguous language. The edited guidance becomes part of the AOP context. **One scope, one agent**: If the Clarity process covers multiple distinct workflows — for example, both routine invoices and disputed invoices — create separate agents for each rather than a single agent with complex branching logic. This makes testing and refinement easier. *** ## Related Resources How to capture processes and generate documentation How to describe and generate AOPs Placing approval gates correctly Iterating after the first test run How to test without affecting production systems # Duplicating Agents Source: https://docs.duvo.ai/user-guide/building-assignments/duplicating-assignments Create an exact copy of an existing agent, including its AOP, connections, and queue links, so you can build a similar agent without starting from scratch. The Duplicate feature creates an exact copy of an existing agent, including its AOP, connection setup, and queue links. Use it when you want to build a new agent that is similar to one you have already configured, without starting from scratch. ## Key Capabilities * Copies the full agent configuration: AOP, Connections, and queue links. * Creates the duplicate immediately and opens it for editing. * The original agent is left unchanged. ## How to Duplicate an Agent On the Agents page, find the agent you want to copy. Open the three-dot menu on the agent card or row. Click **Duplicate**. Duvo creates a copy and takes you directly to the new agent, ready to rename and edit. ## When to Use It * You need multiple agents that share the same workflow but differ in a few details — for example, the same report sent to different departments. * You want to experiment with changes to an agent without modifying the live version. * You are setting up a new agent based on a proven workflow and want to skip the initial build step. # Getting Started Source: https://docs.duvo.ai/user-guide/building-assignments/how-to-build-an-assignment Build your first Duvo agent step by step. Describe your workflow, connect your tools, and let the Agent Builder create it for you. Building your first Duvo agent is simple and can be done in just a few steps. Whether you prefer describing your workflow in plain English, starting from a template, or writing detailed AOPs yourself, Duvo gives you the flexibility to work in the way that suits you best. Click the **"+ Create Agent"** button to begin. You'll be prompted to choose how you want to build your agent. Create Agent button and build-method picker You have three ways to build your agent: The three Agent build options: Builder, Template, and Manual ### Option 1: Use the Agent Builder (Recommended) The Agent Builder allows you to describe your workflow in plain English, just like explaining a task to a colleague. Simply type what you want the agent to do, and Duvo will generate the structured AOP for you. This is the fastest way to get started and requires no technical knowledge. The Agent Builder translates your conversational description into detailed AOPs automatically. **Learn more:** [Getting Started with the Agent Builder](/user-guide/building-assignments/assignment-builder) ### Option 2: Start from a Template Browse Duvo's library of pre-built templates for common workflows like expense processing, customer onboarding, inventory management, and weekly reporting. Templates provide a ready-made starting point that you can customize to fit your specific needs. This option is perfect when your workflow matches a common business process—you can deploy faster by adapting an existing template rather than starting from scratch. ### Option 3: Start from scratch (Manual) If you prefer complete control or have complex requirements, you can write the agent AOP directly. This method gives you precise control over every aspect of your agent's behavior, including goals, triggers, steps, decision logic, and error handling. This approach is ideal for experienced users or when you need to create highly customized workflows with specific conditions and rules. **Learn more:** [Agent AOP](/user-guide/building-assignments/assignment-sop) # Multi-Agent Process Decomposition Source: https://docs.duvo.ai/user-guide/building-assignments/process-decomposition Decide when to keep a business process in one Agent or split it across several, and how to wire the hand-offs — with pipeline, fan-out, and escalation patterns and a worked example. This guide helps you decide when to keep a business process as one agent and when to split it across multiple, and how to wire the hand-offs between them so work flows cleanly from stage to stage. *** ## When to Keep It One Agent A single agent is the right choice when the process fits these conditions: * **One coherent AOP.** All steps belong to one logical flow that a single person would carry out end-to-end. * **One primary operator persona.** The human approval steps all go to the same role — a single agent handles its own exceptions. * **One integration cluster.** The required connections belong to the same system or domain (for example, all Gmail + Google Sheets, or all Salesforce + Slack). * **Short end-to-end latency.** The work completes in under five minutes with no waiting stages that could block downstream work. If your process fails any of these checks, splitting it will make it more maintainable, reliable, and easier to reason about. *** ## When to Split — and Which Seam to Use Three conditions consistently warrant splitting into multiple agents: 1. **Different personas handle different stages.** If the first stage requires a procurement manager to approve and the second stage requires a finance analyst to validate, keep the stages in separate agents so each persona manages their own exceptions. 2. **Different SLAs.** High-priority intake should not be slowed down waiting for a batch of low-priority items to clear. Splitting lets each agent run on its own schedule. 3. **Reusable subroutines.** If five agents all need to "look up a customer record and validate their account status," extract that step into one specialist agent that the others can hand to. Once you've decided to split, pick the seam based on the hand-off shape: | Hand-off shape | Use this | | -------------------------------------------------------------------- | ----------------------------------- | | One agent produces items; another processes them asynchronously | **Queue (producer/consumer)** | | A running agent needs to escalate or route to a specialist right now | **Agent Handover** | | Multiple agents share a reusable step | **Agent Handover** from each caller | *** ## Three Canonical Patterns ### Pattern 1: Pipeline (A → B → C) Each agent adds context and passes the result to the next stage. Use the Queue producer/consumer seam. ```mermaid theme={"dark"} flowchart LR Trigger[Trigger] --> A[Stage A — Producer] A -->|adds case| Q1[(Queue 1)] Q1 --> B[Stage B — Consumer / Enrich] B -->|adds enriched case| Q2[(Queue 2)] Q2 --> C[Stage C — Final Consumer / Write action] ``` **When it fits:** * Intake, enrichment, and action are conceptually distinct stages * Each stage has its own AOP author and approval chain * Stages run at different speeds (intake is fast; enrichment is slow) **When it doesn't fit:** * The stages are so tightly coupled that they share state in ways the queue data model can't represent cleanly * Total end-to-end latency matters more than separation of concerns **How to set it up:** Runs on a trigger (email, webhook, schedule). Its AOP extracts the raw data and adds a case to the queue with the structured fields Stage B needs. Picks up Pending cases, enriches them, and adds enriched cases to a second queue for Stage C. Takes the enriched data and performs the write action (update the ERP, send the email, post the Slack message). **AOP snippet for Stage A (producer):** ``` For each new order email: 1. Extract order number, customer ID, SKU list, and requested quantity. 2. If any required field is missing, flag the email for manual review and stop — do not add a case. 3. Add a case to the "Order Intake" queue with title "Order [order number]" and the extracted fields as data. ``` **Anti-pattern to avoid:** Stages that write overlapping data to the same external record in parallel. Serialise with the queue, don't parallelise. *** ### Pattern 2: Fan-Out (A → N parallel B's) One agent identifies a batch of items and hands each one to a consumer that processes them in parallel. ```mermaid theme={"dark"} flowchart TD P[Producer Agent] -->|one case per item| Q[(Queue)] Q --> B1[Consumer Run 1] Q --> B2[Consumer Run 2] Q --> B3[Consumer Run N] ``` **When it fits:** * A large batch arrives on a schedule (end-of-day, end-of-week) and each item can be processed independently * The items share the same AOP but contain different data * Throughput matters — sequential processing would take too long **When it doesn't fit:** * Items within a batch depend on each other (process item 1 before item 2) * The write destination has strict rate limits and parallel consumers would breach them **How to set it up:** Runs on a schedule or trigger. Queries the source system (database, spreadsheet, API), identifies all items to process, and adds one case per item to the queue. Has the case trigger enabled with concurrency set to the appropriate parallel limit. Each case runs its own Run independently. **AOP snippet for the producer:** ``` Run every weekday at 07:00. 1. Query Snowflake for all invoices with status "Pending" and due date today or earlier. 2. For each invoice, add a case to the "Invoice Processing" queue. Title: "Invoice [invoice_id] — [vendor_name]" Data: invoice_id, vendor_name, amount, due_date, bank_details. 3. If the query returns more than 200 invoices, stop and request approval before adding cases — this may indicate a data issue. ``` **Capacity planning:** The queue's statistics bar shows Pending, In Progress, and Failed counts. If Pending grows faster than In Progress clears, add a second consumer agent — or contact Duvo to raise the queue's parallel limit above the platform default. *** ### Pattern 3: Escalation (A handles routine, hands to B for exceptions) One agent covers the standard path. When a case falls outside the standard, it hands off to a specialist agent rather than failing or requesting a generic HITL. ```mermaid theme={"dark"} flowchart TD In[Incoming case] --> T[Triage Agent] T --> D{Routine or exception?} D -->|Routine| Done[Complete the action directly] D -->|Exception| S[Specialist Agent via Agent Handover] ``` **When it fits:** * A large volume of cases follow a predictable pattern but a small percentage require specialist judgment * The specialist agent has access to different connections or a different AOP * You want clean separation between routine volume and exception handling **When it doesn't fit:** * The majority of cases are exceptions — this pattern breaks down if the "routine" path is not actually routine * The specialist agent and the routine agent are maintained by the same person — in that case, a single agent with HITL is simpler **How to set it up:** Processes all incoming cases. For routine cases, completes the action directly. For exceptions, requests a handover to the specialist agent. Configured as an allowed handover target. Its AOP handles the narrow class of edge cases the triage agent escalates. See [Agent Handover](/user-guide/assignment-features/assignment-handover) for step-by-step setup instructions. **AOP snippet for the triage agent:** ``` Process each customer complaint case: 1. Read the case data and classify the complaint as Billing, Technical, or Policy. 2. For Billing complaints: look up the customer's account. If the disputed amount is under $200 and the account is in good standing, issue the credit and complete the case. 3. For Billing complaints over $200, or for accounts flagged for review: hand over to @Billing Specialist with a note explaining the issue. 4. For Technical complaints: create a support ticket and complete the case. 5. For Policy complaints: hand over to @Policy Review. ``` *** ## Lineage and Traceability When a source event travels through two or three agents, you need to be able to follow it from end to end. Two practices make this reliable: ### Passing a correlation ID Include a unique identifier for the originating event in every case you add to the queue. Use the same field name across all stages. ``` Add the case with: - title: "Order [order_id]" - data.order_id: [the original order ID from the email] - data.source_email_id: [the Gmail message ID] ``` Every downstream agent receives this ID in its case data and can include it in run outputs, log entries, and any external records it writes. ### Reading the case timeline When a case passes through multiple agents via Handover, the case detail view shows the full timeline: which agent handled each stage, when it started, and what it did. Open a case in your queue and scroll to the timeline to see the complete processing history. For runs in the Runs list, the run output for each stage includes the case ID so you can link stages together. *** ## Anti-Patterns | Anti-pattern | Why it causes problems | What to do instead | | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **One mega-agent** that handles intake, enrichment, action, exception routing, and reporting | Nobody can safely edit it; one AOP change affects every path; test coverage is impossible | Split along the seams above; start with the natural persona or SLA boundaries | | **Two agents that should be one** | Adds latency, creates brittle queue serialisation for steps that share tight state, costs more to operate | Merge if they have the same AOP author, same operator, and complete in under five minutes | | **Circular handovers** — A hands to B, B hands back to A | Creates infinite loops unless both AOPs have explicit termination conditions | Add a `handover_count` field to case data; instruct each agent to stop if the count exceeds a threshold | | **Producer faster than consumer** | Cases pile up in Pending; queue grows unbounded | Keep the consumer running in parallel (the default), add a second consumer agent, or add a cap in the producer's AOP (e.g., "add at most 100 cases per run") | | **Implicit failure** — an agent ends without completing, postponing, or handing over the case | The case silently lands in Failed; no one knows what happened | Every agent that consumes cases must explicitly complete, postpone, fail with a reason, or hand over | *** ## Worked Example: Complaint Triage This example shows how to take a Clarity-generated process and split it across three agents. ### The Clarity output A Clarity session captured the following steps for handling inbound customer complaints: 1. Read the incoming email 2. Classify: Billing, Technical, or Escalation 3. For Billing: look up account, issue credit if under \$200, else forward to billing team 4. For Technical: create a support ticket, assign to on-call engineer 5. For Escalation: forward to account manager with a summary ### The decomposition decision | Step | Agent | Reason | | ----------------------------- | ---------------------------- | ---------------------------------------------------------------------------------- | | Steps 1–2 (intake + classify) | **Triage** | Runs continuously on an email trigger; needs access to Gmail only | | Step 3 (billing resolution) | **Billing Specialist** | Needs CRM access and billing system access; different operator persona; low volume | | Step 4 (technical ticket) | **Triage** | Simple action; same connections; no specialist judgment needed | | Step 5 (escalation) | **Account Manager Briefing** | Different SLA (same-day); needs CRM + Slack; different recipient | ### The wiring * **Triage** consumes from the "Customer Complaints" queue (case trigger enabled). * **Triage** uses Agent Handover to route to @Billing Specialist or @Account Manager Briefing when the case falls outside its path. * **Billing Specialist** and **Account Manager Briefing** are each configured with "Queue (Consumer)" so they appear as valid handover targets. ### Lineage Each case in the "Customer Complaints" queue carries `data.source_email_id` from the originating Gmail message. When a case passes through Handover to the Billing Specialist, the case timeline shows both stages. The Billing Specialist's AOP includes the original email ID in any CRM record it creates, so the audit trail runs from inbox to CRM record. *** ## Related Producer/consumer setup, case triggers, and concurrency Configuring handover targets in the AOP Where to place approval gates within each agent in a multi-stage process Risk classification applies per agent, not per pipeline How individual run failures propagate through multi-agent flows A full end-to-end example using the escalation pattern # Refining Your Agent Source: https://docs.duvo.ai/user-guide/building-assignments/refining-your-assignment Iterate on your agent across multiple runs to align it with your exact business process. **Don't expect perfection on the first try.** Just like training a new employee, your agent needs guidance and refinement to learn your specific process. Multiple runs are normal and expected when developing an agent. *** ## How to refine Run your agent. Observe the steps it takes to accomplish the task. Note what works and what needs adjustment. Use the Agent Builder again to describe changes, or edit the AOP directly. Test and continue refining. ```mermaid theme={"dark"} flowchart LR A[Run your agent] --> B[Observe the steps] B --> C[Note what to adjust] C --> D[Describe changes or edit the AOP] D --> E[Test and continue refining] E --> A ``` *** ## Common refinements * **Adjusting edge case handling** * What happens when expected data is missing? * How should the agent handle unexpected formats or values? * **Clarifying which data fields to use** * Which specific column or field contains the information? * What should the agent do if multiple fields could match? * **Handling data variations**: * Different date formats * Varying currency symbols * Alternative naming conventions * **Adding more approval checkpoints** * Where do you want to review before the agent proceeds? * What threshold requires your input? *** ## Conclusion Each run is a training session that helps align your agent with your exact process. Use human-in-the-loop (HITL) approval points as strategic checkpoints to review the agent's progress and identify where the AOP needs refinement. When making changes, focus on one modification per run—this makes it easy to understand the impact of each change and isolate what works. Refinement isn't a sign of failure; it's how you develop an agent that truly understands your unique business process. *** ## Things to know The Agent Builder is looking at the current run that happened and is visible in the interface. *** ## Related Test plan template, mocking patterns, and environment separation before enabling autonomous Runs How to classify risk and apply the right guardrails before an agent runs autonomously Using approval gates as checkpoints during refinement # Amplitude Source: https://docs.duvo.ai/user-guide/connections/available-connections/amplitude Amplitude is a product analytics platform for tracking user behavior, funnels, and experiments. Connecting Amplitude to Duvo lets your agents query analytics data, search charts, create dashboards, run experiments, and analyze user behavior as part of automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Amplitude account. ## Capabilities * **Query analytics data** — Retrieve event data, funnel metrics, and user activity across your Amplitude projects. * **Search and browse charts** — Find existing charts and visualizations to pull insights from previously built analyses. * **Create dashboards** — Build new dashboards to organize and present analytics data for reporting workflows. * **Run experiments** — Manage A/B tests and experiments, including launching experiments and reviewing outcomes. * **Analyze user behavior** — Explore behavioral trends, segments, and engagement patterns to understand how people interact with your product. ## Key Benefits * **Automated analytics delivery** — Retrieve and summarize Amplitude data on a schedule without manual dashboard work. * **Cross-tool reporting** — Combine product analytics with data from other sources to create unified business reports. * **Faster experiment review** — Automatically pull experiment results and format them for stakeholder communication. * **Consistent metric tracking** — Ensure the same metrics are pulled and calculated the same way every time. * **Reduced analyst overhead** — Let agents handle routine data retrieval so analysts can focus on interpretation. ## Works Well With Post daily or weekly analytics digests to product, growth, or leadership channels automatically. Post daily or weekly analytics digests to product, growth, or leadership channels automatically. Export Amplitude metrics into spreadsheets for tracking trends over time or building dashboards. Export Amplitude metrics into spreadsheets for tracking trends over time or building dashboards. Send experiment result summaries or performance reports to stakeholders on a schedule. Send experiment result summaries or performance reports to stakeholders on a schedule. # Apify Source: https://docs.duvo.ai/user-guide/connections/available-connections/apify Apify is a cloud platform for web scraping and automation, built around Actors—ready-made tools that extract data from websites and run automated web tasks. Its Store offers thousands of Actors for sites like Google Maps, Google Search, Instagram, LinkedIn, and Amazon, plus general-purpose website crawlers. Connecting Apify to Duvo lets your agents find the right Actor, run it, and pull the results into any workflow. Duvo also includes a built-in [Web Scraper](/user-guide/connections/available-connections/web-scraper) connection that handles general web scraping with no setup required. Use this Apify connection when you need a specific Apify Actor or want to run scrapes against your own Apify account. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Apify account. You will need an Apify account—you can create one for free at [apify.com](https://apify.com). ## Capabilities * **Search the Apify Store** — Find the right Actor for a task across thousands of ready-made web scraping and automation tools. * **Run Actors** — Trigger any Apify Actor with the inputs it needs—for example, scraping search results, business listings, social profiles, or product pages. * **Crawl websites** — Extract clean, structured content from one page or across an entire site, ready for analysis or summarization. * **Retrieve results** — Pull the output of a run from Apify datasets and key-value stores so your agent can act on the data. * **Track runs** — Check the status and logs of an Actor run to confirm it finished and handle long-running jobs. ## Key Benefits * **Access ready-made scrapers** — Tap into a large library of maintained Actors instead of building and maintaining custom scraping code. * **Reach data behind complex sites** — Apify's infrastructure handles dynamic pages, JavaScript rendering, and scale, so your agents get reliable results. * **Get structured, usable output** — Receive organized data instead of raw HTML, ready to feed into downstream steps. * **Bring your own account** — Runs use your Apify account, so you stay in control of usage and credentials. ## Works Well With Scrape web data with an Apify Actor and write the results straight into a spreadsheet for tracking or reporting. Scrape web data with an Apify Actor and write the results straight into a spreadsheet for tracking or reporting. Monitor websites for changes and send a summary email when something new is found. Monitor websites for changes and send a summary email when something new is found. Run market or competitor scrapes on a schedule and post alerts to the right channel. # Asana Source: https://docs.duvo.ai/user-guide/connections/available-connections/asana Asana is a project management platform for tracking tasks, projects, and team workflows. Connecting Asana to Duvo lets your agents create, update, and manage work items automatically as part of end-to-end business processes. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Asana account. ## Capabilities * **Create and update tasks** — Add new tasks to projects, update details like assignee, due date, and status, or mark tasks complete as workflows progress. * **Track projects** — Access project details, milestones, and status updates to monitor progress across your workspace. * **Organize work** — Move tasks between sections, assign them to team members, and structure projects to match your team's workflow. * **Search and retrieve** — Find existing tasks, projects, and workspaces to use in downstream workflow steps. * **Log progress** — Record results, decisions, and status changes as task updates or comments. ## Key Benefits * **Eliminate manual task entry** — Agents create and update Asana tasks automatically, so your team spends less time on data entry. * **Keep project boards accurate** — Task status stays current as workflows execute, giving your team a reliable picture of what is happening. * **Standardize how work is logged** — Every agent follows the same process, ensuring consistent task creation and updates regardless of who triggers the workflow. * **Reduce coordination overhead** — Let agents handle routine Asana updates so your team can focus on the work itself. ## Works Well With Create Asana tasks automatically from incoming emails, and send confirmation messages when tasks are completed. Create Asana tasks automatically from incoming emails, and send confirmation messages when tasks are completed. Post task updates and project status alerts to team channels as work progresses. Post task updates and project status alerts to team channels as work progresses. Sync task data into spreadsheets for reporting, or import bulk task lists from a spreadsheet into Asana. Sync task data into spreadsheets for reporting, or import bulk task lists from a spreadsheet into Asana. # Attio Source: https://docs.duvo.ai/user-guide/connections/available-connections/attio Attio is a modern CRM platform for managing contacts, companies, deals, and relationship data. Connecting Attio to Duvo lets your agents read and write CRM records directly, keeping your pipeline and relationship data up to date without manual entry. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Attio account. ## Capabilities * **Contact and company management** — Create, update, search, and retrieve records for people and organizations in your workspace. * **Deal and pipeline tracking** — Create and update deal records, move opportunities through pipeline stages, and monitor deal progress. * **Task management** — Create and update tasks with deadlines, assignees, and linked records. * **Notes** — Attach notes to records and search existing notes by metadata or topic using semantic search. * **Meetings and call recordings** — Search meetings by participants or timeframe, find call recordings, and retrieve transcripts. * **Email search** — Find emails by participants, timeframe, or topic using semantic search, and retrieve full email content. * **Record search and retrieval** — Full-text and attribute-based search across all record types to use in downstream workflow steps. ## Key Benefits * **Automated CRM hygiene** — Keep contact and deal records accurate without manual data entry after every interaction. * **End-to-end sales workflows** — Connect lead capture, deal tracking, and follow-up tasks in a single automated process. * **Consistent record-keeping** — Ensure notes and activities are logged the same way every time, regardless of who runs the workflow. * **Reduced admin overhead** — Let agents handle routine CRM updates so your team can focus on building relationships. ## Works Well With Automatically log email interactions as notes on Attio contact records and create follow-up tasks after key messages. Automatically log email interactions as notes on Attio contact records and create follow-up tasks after key messages. Post deal updates, new lead alerts, or task reminders to sales or partnership channels. Post deal updates, new lead alerts, or task reminders to sales or partnership channels. Export contact or deal data into spreadsheets for pipeline reporting and analysis. Export contact or deal data into spreadsheets for pipeline reporting and analysis. # BambooHR Source: https://docs.duvo.ai/user-guide/connections/available-connections/bamboohr BambooHR is an HR platform for employee records, time off, documents, and HR reporting. Connecting BambooHR to Duvo lets your agents read and update HR data directly from your BambooHR account. ## Setup A BambooHR account. The company subdomain from your BambooHR URL. For example, if you sign in at `https://acme.bamboohr.com`, your subdomain is `acme`. A BambooHR API key. In BambooHR, open your user menu and select **API Keys**. If the option is not available, ask a BambooHR admin to create a key or enable access for the right user. A dedicated service account is recommended when possible, so access is not tied to an individual employee account. New to the BambooHR API? Follow [BambooHR's Getting Started With The API guide](https://documentation.bamboohr.com/docs/getting-started) for company domains, API keys, authentication, and permissions. BambooHR API keys use the same access level as the user who created the key. Make sure that user can access the employees, fields, reports, time off data, and file sections your agents need. For write workflows, the user must also have permission to create or update the relevant records in BambooHR, such as employee profile fields, time off requests, or employee files. The API key inherits the creating user's access level, so it can reach everything that user can. Use a dedicated service account scoped to only the records your agents need. On the [Connections page](https://app.duvo.ai/integrations), open BambooHR and fill in these fields: The subdomain in your BambooHR URL. For `https://acme.bamboohr.com`, enter `acme`. The BambooHR API key generated from the user menu or admin API key settings. The key inherits that user's access level. * [BambooHR Getting Started With The API](https://documentation.bamboohr.com/docs/getting-started) - BambooHR's guide to company domains, API keys, authentication, and permissions. * [BambooHR Technical Overview](https://documentation.bamboohr.com/docs/api-details) - request format, response codes, and API behavior. * [BambooHR Admin API Keys Settings](https://www.bamboohr.com/product-updates/admin-api-keys-settings) - BambooHR's account-level API key management overview. ## Capabilities * **Manage employee records** - list employees, find individual employee profiles, create new employees, update employee fields, and identify records changed since a prior sync. * **Use directory and field metadata** - read the company directory and discover available BambooHR fields before building reports or updates. * **Work with time off** - list who is out, review time off requests, create new requests, check balances, list time off types, and update request status when the API key has approval access. * **Access HR files** - list employee and company file categories, download files, and upload employee documents subject to BambooHR permissions and file limits. * **Run reports and datasets** - list saved reports, run custom reports, discover dataset fields, and export larger results for agents to analyze. ## Key Benefits * **Live HR data in workflows** - agents can use current BambooHR records instead of relying on manual exports. * **Permission-scoped access** - BambooHR controls what Duvo can read or change through the API key user's access level. * **Fewer manual HR handoffs** - agents can look up employees, update records, attach files, and prepare time off information without switching tools. * **Better operational reporting** - saved reports and dataset queries help agents pull HR data into recurring summaries, audits, and exception checks. ## Works Well With Export employee lists, time off summaries, or report results into spreadsheets for review. Export employee lists, time off summaries, or report results into spreadsheets for review. Send onboarding, offboarding, or HR status updates using current BambooHR data. Send onboarding, offboarding, or HR status updates using current BambooHR data. Post employee change alerts, time off summaries, or approval follow-ups to the right team channel. Post employee change alerts, time off summaries, or approval follow-ups to the right team channel. # Google BigQuery Source: https://docs.duvo.ai/user-guide/connections/available-connections/bigquery Google BigQuery is a serverless data warehouse built for fast SQL analytics over large datasets. Connecting BigQuery to Duvo lets your agents query your data warehouse directly, pulling metrics, running analyses, and feeding results into automated workflows. ## Setup A Google Cloud project with the [BigQuery API enabled](https://console.cloud.google.com/apis/library/bigquery.googleapis.com). A service account with a JSON key file. Need to create a key? Follow Google's [Create and delete service account keys](https://cloud.google.com/iam/docs/keys-create-delete) guide. Grant the service account these IAM roles on the project (or on specific datasets if you prefer tighter scoping): * **BigQuery Job User** (`roles/bigquery.jobUser`) — required to run query jobs * **BigQuery Data Viewer** (`roles/bigquery.dataViewer`) — required to read table and view data If your tables use column-level access control, the service account also needs the **Data Catalog Fine-Grained Reader** role (`roles/datacatalog.categoryFineGrainedReader`) on the relevant policy tags to read protected columns. Treat the service account JSON key as a secret. Don't share it or commit it to source control, and rotate the key in Google Cloud if you suspect it has been exposed. Scope the service account's roles to only the projects and datasets your agents need. On the [Connections page](https://app.duvo.ai/integrations), open BigQuery and fill in these fields: The full contents of your service account JSON key file. Open the downloaded `.json` file in a text editor, copy everything, and paste it here. The JSON must include `project_id`, `client_email`, and `private_key` fields. * [Authenticating with a service account key file](https://cloud.google.com/bigquery/docs/authentication/service-account-file) * [BigQuery IAM roles and permissions](https://cloud.google.com/bigquery/docs/access-control) * [Control access to resources with IAM](https://cloud.google.com/bigquery/docs/control-access-to-resources-iam) ## Capabilities * **Run SQL queries** — Execute standard SQL against any dataset and table your service account can access, including aggregation and filtering queries. * **Explore schemas** — List available datasets, tables, and column definitions using BigQuery's `INFORMATION_SCHEMA` views. * **Export results** — Query results are automatically saved as files in your workspace, optimized for efficient downstream processing by your agent. ## Key Benefits * **Direct warehouse access** — Query petabytes of data without manual exports or CSV downloads. * **Real-time insights** — Pull current metrics and KPIs straight from your data warehouse into automated workflows. * **Secure, scoped access** — Service account permissions control exactly which projects and datasets your agents can reach. * **Data-driven automation** — Combine warehouse data with other connections to make intelligent decisions within a workflow. ## Works Well With Query BigQuery for raw data, then write summaries or reports into a spreadsheet for stakeholders. Pull key metrics from your warehouse and post automated updates to team channels. Generate data-driven reports from BigQuery and email them on a schedule. # Browser Source: https://docs.duvo.ai/user-guide/connections/available-connections/browser The Browser connection gives your agents direct access to any website or web application, letting them navigate pages, fill out forms, click buttons, and complete multi-step processes just like a person would. This is especially valuable for systems that lack API access, such as internal portals, ERPs, and vendor platforms. ## Setup No setup required. The Browser connection is available to every agent automatically. ## Capabilities * **Navigate websites** — Go to any URL, follow links, and move through multi-page workflows. * **Fill out forms** — Enter data into text fields, dropdowns, date pickers, and other form elements. * **Click and interact** — Press buttons, select menu items, and use any interactive page element. * **Extract information** — Read and capture data from web pages for use in downstream steps. * **Upload and download files** — Attach files to web forms or download documents, reports, and exports from portals. * **Sign in with stored Logins** — Sign in to protected sites using logins saved in [Logins and Secrets](/user-guide/resources/my-logins), including one-time 2FA codes, without exposing passwords to the agent. Sites that require HTTP Basic Auth (browser-level username/password prompts) are handled automatically using matching stored logins. * **Complete end-to-end processes** — Chain actions across multiple pages to finish entire business workflows in a single run. ## Key Benefits * **Universal access** — Work with any website or web application, including systems that have no API or modern connection options. * **Human-like interaction** — Perform the same clicks, form fills, and navigation a person would, with no technical integration required. * **Secure authentication** — Use stored logins to access protected sites while keeping credentials safe. * **Full auditability** — Every browser action is tracked, giving you a clear record of what the agent did and when. * **Flexible automation** — Automate virtually any browser-based task without custom development or vendor cooperation. ## Works Well With Gather data from a web portal, then draft and send a summary email with the results. Gather data from a web portal, then draft and send a summary email with the results. Extract information from vendor websites or internal dashboards and write it directly into a spreadsheet for reporting. Pull reference data from a database, then use the browser to enter it into a legacy system that only has a web interface. # Computer Use Source: https://docs.duvo.ai/user-guide/connections/available-connections/computer-use **Beta** — This feature is currently in beta and may change. The Computer Use connection gives your agents access to a full Windows desktop environment, letting them click, type, navigate applications, and interact with desktop software just like a person would. This is especially valuable for automating Windows-native applications, legacy systems without APIs, and multi-application workflows that span desktop programs. ## Setup No setup required. The Computer Use connection is available for any agent. Add it to your agent from the Connections panel in the agent builder. ### Route traffic through your network with OpenVPN (optional) If your agents need to reach systems that are only available inside a private network, you can route the desktop's traffic through your own OpenVPN server. This is optional — without it, the desktop uses direct internet access. Your team's OpenVPN config — the `.ovpn` file your network admin provided, plus an optional username and password if your VPN uses password authentication — is set up in Team Settings and applied to the agents that need it. Credentials are encrypted at rest and are never returned by the API. Once an agent is set to use a VPN, the tunnel is established before the agent starts working, and all of the desktop's traffic flows through it. If the tunnel cannot be established, the run stops rather than continuing outside the VPN. ## Capabilities * **Control desktop applications** — Open, navigate, and operate any Windows application, including Office, custom business software, and legacy systems. * **Click and type** — Click buttons, menu items, and UI elements, and type into text fields, forms, and dialog boxes. * **Sign in with stored Logins** — Use saved logins from [Logins and Secrets](/user-guide/resources/my-logins) to sign in to applications and websites, including one-time 2FA codes, without exposing passwords to the agent. * **Navigate multi-step workflows** — Complete processes that span multiple windows and applications. * **Read screen content** — Capture and interpret what's displayed on the desktop to make informed decisions. * **Transfer files** — Move files between applications, save documents, and work with local file systems. * **Handle dialog boxes** — Respond to prompts, confirmations, and alerts that appear during automation. ## Key Benefits * **Beyond the browser** — Automate desktop applications that have no web interface or API, including legacy Windows software and thick-client applications. * **Visual interaction** — Duvo operates the desktop the same way a human would, so complex UI workflows work without technical integration. * **Live visibility** — Watch the desktop in real-time as your agent works, with the ability to intervene or guide the process. * **Session continuity** — Follow-up messages preserve the desktop state, so open applications and files remain available across interactions. * **Full audit trail** — Every click, keystroke, and screenshot is captured, giving you a complete record of what the agent did. ## Works Well With Extract attachment data, process it in a desktop application, and send the results by email. Extract attachment data, process it in a desktop application, and send the results by email. Pull data from your warehouse and use it to populate fields in desktop business software. Pull data from your warehouse and use it to populate fields in desktop business software. # Confluence Source: https://docs.duvo.ai/user-guide/connections/available-connections/confluence Confluence is Atlassian's team workspace for documentation, knowledge bases, and collaborative content. Connecting Confluence to Duvo lets your agents create, search, update, and organize pages across your Confluence spaces without manual effort. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Atlassian account. ## Capabilities * **Create pages and blog posts** — Draft new documentation, meeting notes, or reports directly in your Confluence spaces. * **Update and delete content** — Edit and revise pages and blog posts to keep documentation current as processes change. * **Search across spaces** — Find relevant pages, articles, and content across your entire Confluence workspace with powerful, workspace-wide search and filters. * **Read page content** — Access page text and metadata for research or cross-referencing. * **Manage comments and labels** — Add footer comments to pages and apply or remove labels to organize content by category or topic. * **Navigate space hierarchies** — Browse spaces, page trees, and child pages to locate and structure information. * **Download and upload attachments** — Transfer files between your Confluence pages and the agent's workspace. ## Key Benefits * **Automated documentation** — Keep your knowledge base up to date without manual editing or copy-pasting between tools. * **Cross-system knowledge access** — Let agents pull context from Confluence when working with data from other connections. * **Content creation at scale** — Generate reports, summaries, or process docs as Confluence pages from workflow results. * **Centralized search** — Give agents access to your team's institutional knowledge in one place. ## Works Well With Summarize Confluence pages and share them in channels, or create documentation from Slack discussions. Generate project documentation in Confluence based on completed issues and milestones. Turn spreadsheet data into formatted Confluence reports or sync findings back to pages. # Coupa Source: https://docs.duvo.ai/user-guide/connections/available-connections/coupa Coupa is a cloud procurement platform for managing purchasing, suppliers, invoices, and spend. Connecting Coupa to Duvo lets your agents read procurement data directly — pulling purchase orders, supplier records, invoices, contracts, and expense reports without manual exports. Coupa is **read-only** in Duvo. The connection only reads data from Coupa. It does not create, modify, or delete any records. ## Setup A Coupa administrator account (or access to someone with one) to create an OAuth2 client. Your Coupa instance must be accessible over the internet (most Coupa Cloud instances are by default). An OAuth2/OpenID Connect client registered in Coupa with the **Client Credentials** grant type. To create one, go to **Setup > Integrations > OAuth2/OpenID Connect Clients**, click **Create**, and select **Client Credentials** as the grant type. The OAuth2 client must have read scopes enabled for the resources your agents need. Duvo requests the following scopes: `core.common.read`, `core.accounting.read`, `core.approval.read`, `core.supplier.read`, `core.supplier_sites.read`, `core.user.read`, `core.business_entity.read`, `core.purchase_order.read`, `core.purchase_order_only.read`, `core.purchase_order.assignment.read`, `core.purchase_order_change.read`, `core.purchase_order_change.assignment.read`, `core.invoice.read`, `core.invoice.assignment.read`, `core.payables.invoice.read`, `core.requisition.read`, `core.requisition.assignment.read`, `core.contract.read`, `core.contract_party_role.read`, `core.contracts_template.read`, `core.expense.read`, `core.payables.expense.read`. Enable all of these on the OAuth2 client to avoid authentication errors. You can review available scopes at `https://{your-instance}/oauth2/scopes`. New to Coupa OAuth2? Follow [OAuth 2.0 Getting Started with Coupa API](https://compass.coupa.com/en-us/products/total-spend-management-platform/integration-playbooks-and-resources/integration-knowledge-articles/oauth-2.0-getting-started-with-coupa-api) for a step-by-step guide to creating an OAuth2 client and generating credentials. On the [Connections page](https://app.duvo.ai/integrations), open Coupa and fill in these fields: Your Coupa instance URL (for example, `https://your-org.coupacloud.com`). This can end in `.coupacloud.com` or `.coupahost.com` depending on your deployment. The OAuth2 client identifier, found in Coupa under **Setup > Integrations > OAuth2/OpenID Connect Clients** after saving the client. The OAuth2 client secret for authentication, shown alongside the client identifier after saving. Copy and store it securely. * [OAuth 2.0 Getting Started with Coupa API](https://compass.coupa.com/en-us/products/total-spend-management-platform/integration-playbooks-and-resources/integration-knowledge-articles/oauth-2.0-getting-started-with-coupa-api) — step-by-step guide for creating an OAuth2 client and generating credentials. * [OpenID Connect Clients](https://compass.coupa.com/en-us/products/product-documentation/integration-technical-documentation/the-coupa-core-api/oauth-2.0-and-oidc/openid-connect-clients) — reference for managing OAuth2/OIDC clients in Coupa, including scope configuration. ## Capabilities * **Purchase orders** — List, filter, and retrieve purchase orders and their line items, including status, amounts, and supplier details. * **Invoices** — Look up invoices by date, supplier, status, or amount for reconciliation and audit workflows. * **Suppliers** — Search and retrieve supplier profiles, contact information, addresses, and compliance status. * **Requisitions** — Access purchase requisitions and their approval status to track the request-to-order pipeline. * **Contracts** — Retrieve contract records for compliance checks, renewal tracking, and spend-against-contract analysis. * **Expense reports and lines** — Pull expense report data and individual line items for policy compliance reviews and spend analysis. * **Approvals** — Check approval status across procurement documents to identify bottlenecks. * **Users** — Look up Coupa user profiles, roles, and account groups. * **Accounts and organizational data** — Query chart of accounts, business entities, departments, and commodity categories for reporting context. * **Flexible querying** — Filter by any field, sort results, select specific columns, and paginate through large datasets. ## Key Benefits * **Direct procurement access** — Agents read from your Coupa instance in real time, eliminating manual data exports and copy-paste workflows. * **Secure OAuth2 authentication** — Uses the standard Client Credentials grant with scoped permissions, so access is limited to exactly what you authorize. * **Broad data coverage** — Covers the core procurement lifecycle from requisitions through purchase orders, invoices, contracts, and expenses. * **Read-only by design** — The connection only reads data from Coupa. It does not create, modify, or delete any records. ## Works Well With Pull Coupa spend data, purchase order summaries, or supplier lists into spreadsheets for financial analysis and stakeholder reporting. Pull Coupa spend data, purchase order summaries, or supplier lists into spreadsheets for financial analysis and stakeholder reporting. Retrieve procurement records and include them in automated approval notifications, spend summaries, or vendor communication. Retrieve procurement records and include them in automated approval notifications, spend summaries, or vendor communication. Post purchase order status updates, invoice alerts, or spend threshold notifications to relevant channels. Post purchase order status updates, invoice alerts, or spend threshold notifications to relevant channels. # Custom MCP Source: https://docs.duvo.ai/user-guide/connections/available-connections/custom-mcp The Custom MCP connection lets you link Duvo to any system not covered by a built-in connection. You provide the URL of your own MCP-compatible server, and Duvo connects to it so your agents can use the tools that server exposes. ## Setup Custom MCP connections require a deployed MCP server that is accessible over the internet. Follow these steps to deploy your server and connect it to Duvo. Your MCP server must be accessible over the internet via a public HTTPS URL (localhost is not supported), and must support streamable HTTP transport (STDIO and HTTP/SSE are not supported). Build and deploy an MCP server that implements the tools you need. The server must be reachable at a public HTTPS endpoint. For guidance on building an MCP server, see [Building Custom Connections](/user-guide/connections/building-custom-connections). 1. Open the [Connections page](https://app.duvo.ai/integrations). 2. Click **Add custom connection** at the bottom of the available connections list. 3. Enter a **Connection name** that your team will recognize (for example, "Internal CRM" or "Warehouse API"). 4. Choose an **Authorization method**: * **None** — No authentication required. Use this for servers that handle auth at the network level or have no auth. * **Access token / API key** — Your server requires a static token or API key. Each teammate enters their own credentials when they connect. * **Custom headers** — Your server requires specific HTTP headers for authentication. Each teammate provides their own header values. * **OAuth** — Your server uses OAuth for authentication. See the OAuth section below for details. 5. Enter the **Server URL** — the public HTTPS URL of your deployed MCP server (for example, `https://example.com/mcp`). 6. Click **Create** to add the connection type to your team's catalog. After the connection type is created, each teammate clicks **Enable** on the new connection card and provides their own credentials based on the authorization method chosen in the previous step. ### OAuth setup When you select OAuth as the authorization method and enter a server URL, Duvo automatically checks whether the server supports OAuth and **dynamic client registration (DCR)**. * **If the server does not support OAuth:** An error message appears suggesting you use a different authorization method. * **If DCR is supported:** No additional credentials are needed. The connection is handled automatically. * **If DCR is not supported:** The **Advanced settings** section opens automatically with the Client ID and Secret fields marked as required. Enter your **OAuth Client ID** and **OAuth Client Secret**. This section also displays a redirect URI that you need to register in your OAuth provider. You can also provide a Client ID and Secret manually through **Advanced settings** if you prefer to use a pre-registered OAuth app instead of automatic registration. ## Capabilities * **Access proprietary systems** — Connect to internal tools, legacy platforms, or custom-built APIs that are not available as standard connections. * **Call custom tools** — Use any tools your MCP server exposes directly within agent workflows. * **Authenticate securely** — Support multiple authentication methods including API key, custom headers, and OAuth, depending on your server's requirements. * **Extend Duvo's reach** — Add domain-specific functionality tailored to your organization's needs without waiting for a built-in connection. ## Key Benefits * **Unlimited connection scope** — Connect to any system you can build an MCP server for, without waiting for a built-in connection to exist. * **Full control** — You own and manage the server, so you decide what tools are available and what data is exposed. * **Consistent workflow** — Custom tools work the same way as built-in connections. Your agents use them without special handling. * **Secure by design** — Credentials stay within Duvo's connection setup and are not exposed in agent instructions. * **Team-wide catalog** — Add a custom connection once and every teammate can connect with their own credentials. ## Works Well With Use a custom MCP server to pull data from a proprietary system, then use the Browser connection to enter that data into a web-based downstream tool. Retrieve records from an internal system via custom MCP and send automated email summaries. Retrieve records from an internal system via custom MCP and send automated email summaries. Fetch data from a proprietary operational system through custom MCP and combine it with warehouse queries for unified reporting. Fetch data from a proprietary operational system through custom MCP and combine it with warehouse queries for unified reporting. # Databricks Source: https://docs.duvo.ai/user-guide/connections/available-connections/databricks Databricks is a unified data lakehouse platform for analytics and AI. Connecting Databricks to Duvo lets your agents run SQL queries against your SQL Warehouse, explore your data catalog, and pull results into automated workflows. ## Setup A Databricks workspace with at least one running SQL Warehouse. A Databricks personal access token (PAT). To generate one, go to **User Settings > Developer > Access tokens** in your Databricks workspace and click **Generate new token**. Copy the token immediately — it cannot be retrieved later. The connection details for your SQL Warehouse. To find them, open your Databricks workspace, click **SQL Warehouses** in the sidebar, select your warehouse, and open the **Connection details** tab. Need a token? Follow [Databricks' personal access token guide](https://docs.databricks.com/aws/en/dev-tools/auth/pat) to generate one (AWS docs; Azure and GCP have equivalent pages). The Databricks account you connect must have: * **Databricks SQL entitlement** — your user account must have the Databricks SQL entitlement enabled in the workspace. * **CAN USE** permission on the target SQL Warehouse — this is the minimum access level required to connect and run queries. * **Data access** — your account must have SELECT (or higher) privileges on the catalogs, schemas, and tables you want to query. The account's privileges determine exactly what data the agent can reach. Grant SELECT (or higher) only on the catalogs, schemas, and tables the agent needs. On the [Connections page](https://app.duvo.ai/integrations), open Databricks and fill in these fields: Your Databricks workspace hostname (e.g., `dbc-abc123.cloud.databricks.com`). Found on the **Connection details** tab of your SQL Warehouse. The SQL Warehouse HTTP path (e.g., `/sql/1.0/warehouses/abc123`). Found on the **Connection details** tab of your SQL Warehouse. Your Databricks personal access token (starts with `dapi`). Generated from **User Settings > Developer > Access tokens** in your Databricks workspace. * [Generate a personal access token](https://docs.databricks.com/aws/en/dev-tools/auth/pat) — Step-by-step guide for creating PATs (AWS docs; Azure and GCP have equivalent pages). * [Get connection details for a compute resource](https://docs.databricks.com/aws/en/integrations/compute-details) — How to find your Server Hostname and HTTP Path (AWS docs; Azure and GCP have equivalent pages). * [SQL warehouse access control](https://docs.databricks.com/en/security/auth-authz/access-control/sql-endpoint-acl.html) — Managing CAN USE and other warehouse permissions. ## Capabilities * **Run SQL queries** — Execute analytical queries directly against your Databricks SQL Warehouse and retrieve results. * **Explore your data catalog** — Browse catalogs, schemas, and tables using discovery queries to understand available datasets. * **Inspect table structures** — View column definitions, data types, and metadata for any table in your lakehouse. * **Pull business metrics** — Extract KPIs, performance data, and aggregated insights for reports and downstream workflows. ## Key Benefits * **Lakehouse access** — Query your unified data platform directly from agents without manual SQL sessions. * **Familiar SQL interface** — Use standard SQL to retrieve exactly the data you need from structured and semi-structured sources. * **Secure authentication** — Connects through personal access tokens with scoped permissions, keeping your data access controlled. * **Large result handling** — Streams query results efficiently using Arrow format, supporting datasets with millions of rows. * **Data-driven automation** — Make intelligent workflow decisions based on live lakehouse data rather than stale exports. ## Works Well With Query Databricks for raw data, then push summarized results into a spreadsheet for stakeholder review. Query Databricks for raw data, then push summarized results into a spreadsheet for stakeholder review. Run scheduled analytical queries and deliver key metrics or alerts directly to your team's communication channels. Combine data from multiple warehouse platforms in a single agent to build cross-system reports. Combine data from multiple warehouse platforms in a single agent to build cross-system reports. # Deep Research Source: https://docs.duvo.ai/user-guide/connections/available-connections/deep-research Deep Research lets your agents conduct thorough, multi-source investigations on any topic and receive detailed findings as structured Markdown reports with sources. Powered by Google Gemini, it goes far beyond surface-level lookups to deliver comprehensive analysis your agents can act on. ## Setup No setup required. Deep Research is automatically available to every agent. ## Capabilities * **Comprehensive topic investigation** — Autonomously explores a topic across multiple sources, gathering and synthesizing information into a detailed report. * **Source-backed findings** — Returns structured Markdown reports with cited sources so your agents can verify and reference the underlying material. * **Asynchronous research** — Handles complex, time-intensive research in the background (up to 55 minutes for complex topics) while your agent continues other work. * **Workspace output** — Saves research results as Markdown files in `/workspace/deep_research/`, making them available for downstream processing and reference. ## Key Benefits * **Depth over speed** — Goes beyond quick lookups to deliver well-rounded, multi-angle analysis on complex subjects. * **Hands-off research** — Your agent provides the topic and instructions, then Deep Research runs autonomously and returns when finished. * **Decision-quality output** — Produces thorough background material that supports informed decision-making and detailed reporting. * **Structured and reusable** — Results are saved as Markdown files, ready for your agent to process, summarize, or include in deliverables. ## Works Well With Use Exa for quick factual lookups and real-time web searches, then hand off complex topics to Deep Research for deeper investigation. Research a topic with Deep Research, then have your agent compile and publish the findings into a Google Doc. Research a subject thoroughly, then draft and send an email summarizing the key findings to stakeholders. # Dynamics 365 Business Central Source: https://docs.duvo.ai/user-guide/connections/available-connections/dynamics-365-business-central Dynamics 365 Business Central is a cloud ERP system by Microsoft for small and mid-sized businesses, covering finance, sales, purchasing, and inventory. Connecting it to Duvo lets your agents access financial records, customer and vendor data, and operational information directly from your Business Central environment. ## Setup A Microsoft Entra ID (formerly Azure AD) app registration with the **Dynamics 365 Business Central** API permission (`API.ReadWrite.All`) and admin consent granted. Access to the Azure portal to retrieve the Tenant ID, Client ID, and generate a Client Secret for the app registration. The app registration must be added in Business Central under **Microsoft Entra applications** with **State** set to **Enabled** and the appropriate **User Permission Sets** assigned (for example, `D365 READ` for read-only access or `D365 BUS FULL ACCESS` for broader operations). A Business Central environment (production or sandbox) that the app registration can access. New to Entra ID app registrations? Follow [Microsoft's app registration quickstart](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) to register the app and generate a client secret. The Entra ID app registration must have: * The **Dynamics 365 Business Central** API permission `API.ReadWrite.All` with admin consent granted. * Registration inside Business Central under **Microsoft Entra applications** with appropriate permission sets assigned. The permission sets control which data the app can access (customers, vendors, companies). The permission sets assigned inside Business Central determine exactly what data the agent can reach. Assign only the sets the agent needs — for example, `D365 READ` for read-only access rather than `D365 BUS FULL ACCESS`. On the [Connections page](https://app.duvo.ai/integrations), open Dynamics 365 Business Central and fill in these fields: Your Microsoft Entra ID (Azure AD) tenant GUID. Find it in the Azure portal under **Microsoft Entra ID > Overview** or **App registrations**. The Application (client) ID from your Entra ID app registration that has Business Central API permissions. A client secret generated for the app registration. Found under **Certificates & secrets** in the Azure portal. The Business Central environment name to connect to. Defaults to `production` if left blank. The GUID of the specific Business Central company to use. Leave blank to auto-select when only one company exists. * [Register an application in Microsoft Entra ID](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-develop-connect-apps#register-your-application-in-azure-ad) — creating the app registration and granting Business Central API permissions. * [Set up Microsoft Entra applications in Business Central](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/automation-apis-using-s2s-authentication) — registering the app inside Business Central and assigning permission sets. * [Business Central API overview](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/api-reference/v2.0/) — available API endpoints and entity reference. * [Entra ID app registration quickstart](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) — general guide to registering apps and generating client secrets. ## Capabilities * **Query customers and vendors** — retrieve contact details, payment terms, balances, and aging data for customers and vendors, with filtering, sorting, and pagination. * **Look up full partner details** — get comprehensive information for a specific customer or vendor, including financial details, aging buckets, dimensions, and contact persons. * **Search across business partners** — run cross-entity searches across both customers and vendors to find the right records quickly. * **Discover companies** — list all companies available in your Business Central environment to identify the right data scope. ## Key Benefits * **Direct ERP access** — agents read from Business Central in real time instead of relying on manual data exports or screen-by-screen navigation. * **Secure credential handling** — Azure AD client credentials are encrypted at rest and never exposed in logs or API responses. * **Flexible scoping** — target a specific environment and company, or let the connection auto-select when your tenant has a single company. * **Finance-ready data** — pull customer balances, vendor records, and company information for reconciliation, reporting, and compliance workflows. ## Works Well With Pull Business Central customer or vendor data into spreadsheets for financial analysis, reconciliation, or reporting. Pull Business Central customer or vendor data into spreadsheets for financial analysis, reconciliation, or reporting. Pull customer or vendor details and include them in automated notification or follow-up emails. Pull customer or vendor details and include them in automated notification or follow-up emails. Post payment alerts, vendor updates, or financial summaries to the relevant business channels. Post payment alerts, vendor updates, or financial summaries to the relevant business channels. # EDI Source: https://docs.duvo.ai/user-guide/connections/available-connections/edi Exchange orders, invoices, and shipping documents with your trading partners over EDI. Electronic Data Interchange (EDI) is how trading partners exchange business documents — purchase orders, order confirmations, invoices, and shipping notices — in a structured format. The EDI connection lets your Agents work with those documents in Duvo. The Duvo team sets the connection up with your EDI provider, so your team doesn't take on the document mapping or transport. ## Setup EDI is set up by the Duvo team — there is no self-serve connect flow. Go to the [Connections page](https://app.duvo.ai/integrations) and open **EDI** under Duvo Business Connections. Select **Request setup**. The Duvo team is notified and will get in touch. We confirm the trading partners, document types, and the transport your EDI provider uses, then enable the connection for your team. ## Capabilities * **Exchange trading partner documents** — Work with orders, order confirmations, invoices, and shipping notices from your partners. * **Use your existing EDI provider** — Duvo connects to the EDI setup you already run, so partner agreements stay in place. * **Agent-driven handling** — Agents pick up incoming documents and act on them as part of a Run. ## Key Benefits * **No rekeying** — Agents process partner documents as they arrive instead of someone entering them by hand. * **Duvo handles the setup** — Mapping and transport are configured for you. * **Fits your existing process** — Works alongside the ERP and document Connections your Agents already use. ## Works Well With Post incoming orders and invoices into your ERP. Read partner documents that arrive as PDFs alongside your EDI flows. Notify your team when a partner document needs a human decision. # Email Attachments Reader Source: https://docs.duvo.ai/user-guide/connections/available-connections/email-attachments-reader Email Attachments Reader extracts text and data from files attached to emails, turning static attachments into information your agents can read and act on. It works alongside Gmail or Outlook to process Excel spreadsheets, PDFs, and images directly from your inbox. ## Setup No setup required. Email Attachments Reader is automatically available to every agent. ## Capabilities * **Excel file extraction** — Read and interpret data from `.xlsx` and `.xls` spreadsheets attached to emails. * **PDF processing** — Extract text and structured content from PDF attachments such as invoices, contracts, and reports. * **Image reading** — Use AI to read text and understand content in `.jpg`, `.jpeg`, and `.png` image attachments. * **Structured data extraction** — Go beyond raw text to understand document layout, tables, and context within attachments. ## Key Benefits * **Hands-free document processing** — Agents read attachment contents automatically without human intervention. * **Intelligent understanding** — AI interprets document structure and context, not just raw text, so agents can extract meaningful data from complex files. * **Multi-format support** — Handles the most common business file types (spreadsheets, PDFs, and images) in a single connection. * **End-to-end email automation** — Pairs naturally with email connections to process entire inbox workflows from message to attachment to action. ## Works Well With Retrieve emails and then read their attachments in a single workflow, enabling agents to process invoices, purchase orders, or reports that arrive by email. Retrieve emails and then read their attachments in a single workflow, enabling agents to process invoices, purchase orders, or reports that arrive by email. Extract data from an email attachment and write it into a live spreadsheet for tracking or further analysis. Extract data from an email attachment and write it into a live spreadsheet for tracking or further analysis. Summarize attachment contents and post key findings to a team channel for quick review. Summarize attachment contents and post key findings to a team channel for quick review. # EU Food Commodity Prices Source: https://docs.duvo.ai/user-guide/connections/available-connections/eu-food-commodity-prices The EU Food Commodity Prices connection gives your agents direct access to agricultural commodity prices published by the European Commission. It covers 19 commodity categories including beef, cereals, dairy, pigmeat, poultry, eggs, sheep and goat, rice, oilseeds, sugar, olive oil, wine, fruit and vegetables, fertiliser, and organic products. Use it to automate price monitoring, cost benchmarking, and market reporting without manual data downloads. ## Setup No setup required. The EU Food Commodity Prices connection is automatically available to every agent. ## Capabilities * **Retrieve current commodity prices** — Access up-to-date EU market prices across 19 categories sourced from the European Commission's Agridata API. * **Query historical price data** — Look up price trends over time by specifying date ranges or years for specific commodities. * **Discover available filters** — List available products, categories, regions, farming methods, and other filter values for any commodity before querying prices. * **Filter by commodity and product** — Narrow results by commodity category, EU member state, product code, and time period. * **Export results as CSV** — Price data is automatically saved as CSV files for further analysis in the sandbox. ## Key Benefits * **Official EU data source** — Prices come directly from the European Commission, a recognized and authoritative reference for European agricultural markets. * **No manual lookups** — Agents retrieve price data automatically, removing the need to visit government websites or download datasets. * **Broad commodity coverage** — Access prices across 19 categories including meat, cereals, dairy, oilseeds, sugar, wine, fertiliser, and more in a single connection. * **Historical context** — Retrieve trend data to understand price movements and inform procurement or pricing decisions over time. ## Works Well With Export commodity price data into spreadsheets for cost modeling, budgeting, or trend analysis. Export commodity price data into spreadsheets for cost modeling, budgeting, or trend analysis. Post price alerts or weekly market summaries to procurement or finance channels. Post price alerts or weekly market summaries to procurement or finance channels. Feed commodity price data into your data warehouse alongside internal cost and sales data for integrated analysis. Feed commodity price data into your data warehouse alongside internal cost and sales data for integrated analysis. # Exa Source: https://docs.duvo.ai/user-guide/connections/available-connections/exa Exa is an AI-powered search engine that gives your agents access to real-time web information. Instead of returning lists of links, Exa understands context and delivers precise, relevant content — supplier details, market data, company profiles, and more. ## Setup No setup required. Exa is a built-in connection, automatically available to every agent. ## Capabilities * **Web search** — Find current information across the web using natural language queries, from pricing data to news articles. * **Company research** — Look up detailed information about companies and organizations, including profiles, financials, and industry context. * **People search** — Search for people on LinkedIn and find their professional profiles and background information. * **Data enrichment** — Supplement your internal data with external sources such as product specs, market benchmarks, and competitor details. ## Key Benefits * **Context-aware results** — Goes beyond keyword matching to understand what your agent actually needs and returns focused, usable content. * **Real-time information** — Accesses current web data so your agents always work with up-to-date facts, not stale records. * **No manual research** — Eliminates the need to search, open tabs, and copy-paste findings into a workflow. * **Broad coverage** — Searches across the entire web, covering news, company directories, professional networks, product databases, and more. ## Works Well With Research supplier pricing or competitor data with Exa, then write structured results directly into a spreadsheet for analysis. Gather background information on a contact or company before drafting a personalized outreach email. Gather background information on a contact or company before drafting a personalized outreach email. Use Exa for quick, targeted lookups and pair it with Deep Research when you need a comprehensive, multi-source report on a topic. # Forecasting Source: https://docs.duvo.ai/user-guide/connections/available-connections/forecasting The Forecasting connection generates time series predictions from historical data, letting your agents produce data-driven projections for demand, revenue, inventory, and any other time-ordered metric. ## Setup No setup required. The Forecasting connection is automatically available to every agent. ## Capabilities * **Time series forecasting** — Predict future values based on historical trends and patterns in your data. Supports multiple time frequencies including hourly, daily, weekly, and monthly data. * **Anomaly detection** — Flag unusual data points in historical time series by fitting prediction intervals and identifying values that fall outside the expected range. * **Confidence intervals** — Return prediction ranges alongside point estimates so you can plan for best-case and worst-case scenarios. * **Exogenous variables** — Incorporate external factors (such as promotions, holidays, or weather) into forecasts for more accurate predictions. ## Key Benefits * **No data science required** — Get forecasts from historical data without building or maintaining statistical models. * **Built into any workflow** — Include forecasting as a step in any agent, combining it with data retrieval, analysis, and reporting. * **Range-based planning** — Confidence intervals give you a realistic spread of outcomes, not just a single number. * **Broad applicability** — Apply forecasting to demand planning, financial projections, inventory management, workforce scheduling, or any time-ordered dataset. ## Works Well With Query historical data from your data warehouse and feed it into the Forecasting connection to produce forward-looking projections. Query historical data from your data warehouse and feed it into the Forecasting connection to produce forward-looking projections. Query historical data from your data warehouse and feed it into the Forecasting connection to produce forward-looking projections. Pull forecast results into spreadsheets for planning, reporting, or sharing with stakeholders. Pull forecast results into spreadsheets for planning, reporting, or sharing with stakeholders. Post forecast summaries or alerts when projected values cross key thresholds. Post forecast summaries or alerts when projected values cross key thresholds. # GitHub Source: https://docs.duvo.ai/user-guide/connections/available-connections/github GitHub is a platform for hosting and collaborating on code repositories. Connecting GitHub to Duvo lets your agents read and manage repositories, issues, pull requests, and more using a Personal Access Token. ## Setup A GitHub account with access to the repositories your agent needs to work with. A Personal Access Token (PAT) generated from your GitHub account settings. Use a fine-grained token scoped to the specific repositories and permissions required. Need a token? Follow [GitHub's guide to creating a fine-grained personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token). The permissions your token needs depend on what the agent will do. Common scopes include: * **Contents** — Read or write files and code in repositories. * **Issues** — Read or manage issues and comments. * **Pull requests** — Read or create pull requests and reviews. * **Metadata** — Required for all fine-grained tokens; allows reading repository metadata. Grant only the permissions the agent needs. Avoid using a classic token with broad `repo` scope if a fine-grained token with narrower access is sufficient. On the [Connections page](https://app.duvo.ai/integrations), open GitHub and fill in these fields: A GitHub Personal Access Token with the permissions your agent needs. Generate one at **Settings → Developer settings → Personal access tokens** in your GitHub account. * [Creating a fine-grained personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) * [Token permission scopes reference](https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens) ## Capabilities * **Read repository content** — Access files, directories, branches, and commit history across your repositories. * **Manage issues** — Create, update, close, and search issues; add labels, assignees, and comments. * **Work with pull requests** — Open, review, merge, and comment on pull requests. * **Search code and repositories** — Find files, functions, or content across repositories using GitHub's search API. * **Retrieve repository metadata** — Read repository details, contributors, topics, and settings. ## Key Benefits * **Automate developer workflows** — Triage issues, generate release notes, or open pull requests as part of a repeatable agent. * **Connect code to business processes** — Link repository activity to project management, reporting, and communication workflows. * **Minimal setup** — A single Personal Access Token is all that is needed; OAuth app setup is not required, though organization policies may require admin approval. ## Works Well With Sync GitHub issues to a project management tool, or create GitHub issues automatically when new work items appear. Sync GitHub issues to a project management tool, or create GitHub issues automatically when new work items appear. Post pull request summaries or issue updates to team channels as part of a review or release workflow. Post pull request summaries or issue updates to team channels as part of a review or release workflow. Generate documentation or release notes from repository activity and publish them to your team wiki. Generate documentation or release notes from repository activity and publish them to your team wiki. # Gmail Source: https://docs.duvo.ai/user-guide/connections/available-connections/gmail Gmail is Google's email service used across most business workflows. Connecting Gmail to Duvo lets your agents read, send, and manage emails on your behalf — automating communication workflows that would otherwise require manual inbox work. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account. ## Capabilities * **Read and search emails** — Retrieve messages from your inbox using filters, search criteria, or specific senders. * **Send emails** — Compose and send messages directly from your connected account. * **Manage drafts** — Create, list, and send draft emails before they go out. * **Download attachments** — Pull files attached to emails for further processing. * **Organize your inbox** — Create and manage labels, move messages, and keep your inbox structured. * **Access account info** — Retrieve your Gmail profile information when needed for workflows. * **Inbox triggers** — Start a Run automatically when a new email arrives. See [Triggers](#triggers) for filter options. ## Triggers The Gmail trigger starts a Run when a new email arrives in the connected user's own inbox. | Field | What it does | | ------------------------- | -------------------------------------------------------------------------------- | | **Senders** | Only fire for email from matching senders. Leave empty to match any sender. | | **Subject keywords** | Only fire when the subject contains any listed keyword. | | **Email keywords** | Only fire when the email contains any listed keyword. | | **Recipients** | Only fire when the email was sent to or copied to matching recipients. | | **Labels** | Only fire when Gmail search matches any listed label name. | | **Has attachment** | Only fire when the email includes an attachment. | | **Attachment file names** | Narrow attachment matches by values like `pdf`, `xlsx`, or `invoice`. | | **Categories** | Only fire for selected Gmail categories such as Primary, Promotions, or Updates. | Filters are optional. When multiple filters are set, the trigger starts a Run only when the email matches all selected filter groups. The Gmail trigger monitors only the inbox of the account you connected. Shared or delegated Gmail inboxes are not currently supported as trigger sources. ## Key Benefits * **End-to-end email automation** — Handle full communication workflows from monitoring incoming messages to composing and sending replies. * **Attachment processing** — Extract and work with documents, spreadsheets, and other files sent via email. * **Your account, your control** — Emails are sent from your own address using your existing permissions. * **Event-driven workflows** — Use inbox triggers to kick off runs the moment a relevant email lands. * **Broad workflow coverage** — Supports reading, writing, drafting, labeling, and searching across your entire mailbox. ## Works Well With Extract data from incoming emails and log it into a spreadsheet for tracking orders, support requests, or leads. Save email attachments directly to Drive folders for organized document management. Notify a Slack channel when an important email arrives or after an automated reply is sent. ## Workflow Examples See [Gmail Workflows](/user-guide/examples/gmail-workflows) for step-by-step tutorials covering inbox triage, drafting replies to common inquiries, and extracting structured data from incoming emails. # Google Calendar Source: https://docs.duvo.ai/user-guide/connections/available-connections/google-calendar Google Calendar is Google's scheduling and time-management service. Connecting it to Duvo lets your agents manage events, schedule meetings, check availability, and keep calendars in sync — all without manual data entry. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account. ## Capabilities * **List events** — View existing calendar events filtered by date range, with details like attendees, location, and status. * **Create events** — Schedule new meetings, appointments, or reminders with a title, start/end times, and time zone. * **Update events** — Modify event details such as title, time, description, or location. * **Check availability** — List upcoming events for a date range to spot conflicts before scheduling. ## Key Benefits * **Automated scheduling** — Create calendar events automatically when workflow conditions are met, removing manual scheduling steps. * **Reliable follow-ups** — Ensure every customer call, check-in, or deadline gets a calendar entry without relying on memory. * **Conflict-free booking** — Agents check existing events before scheduling, reducing double-bookings. * **End-to-end coordination** — Combine scheduling with other agent actions so meetings, reminders, and agendas stay aligned with your processes. ## Works Well With Send meeting invitations or follow-up emails alongside newly created calendar events. Pull scheduling data into a spreadsheet for reporting, or read a sheet of appointments to batch-create calendar events. Post a channel notification whenever a new meeting is scheduled or an event is updated. # Google Docs Source: https://docs.duvo.ai/user-guide/connections/available-connections/google-docs Google Docs is Google's cloud-based document editor. Connecting it to Duvo lets your agents create, read, edit, and manage documents on your behalf — turning manual document work into automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account. ## Capabilities * **Create documents** — Generate new Google Docs documents with a given title. * **Read documents** — Retrieve document content as Markdown, or fetch metadata and structural information by document ID. * **Replace document content** — Overwrite an entire document's content with new Markdown-formatted text. * **Find and replace** — Search for specific text across a document and replace all occurrences in bulk. ## Key Benefits * **Automated document generation** — Produce polished reports, proposals, and communications without manual formatting. * **Consistent output** — Ensure every document follows the same structure and standards, every time. * **Hands-off maintenance** — Keep AOPs, process docs, and reference materials up to date automatically. * **End-to-end workflows** — Combine document creation with data from other connections so agents can research, analyze, and publish results in one run. ## Works Well With Pull data from a spreadsheet and format it into a readable document, such as a weekly summary or client report. Draft a document, then email it as a link or attachment to stakeholders. Organize newly created documents into the right folders and manage sharing permissions automatically. # Google Drive Source: https://docs.duvo.ai/user-guide/connections/available-connections/google-drive Google Drive is Google's cloud storage and file management platform. Connecting it to Duvo lets your agents browse, organize, upload, download, and share files and folders directly within your Drive. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account. ## Capabilities * **List and browse files** — View all files and folders in your Drive as an organized hierarchy, optionally filtered by folder. * **Create folders** — Build organized folder structures for projects, clients, or teams automatically. * **Upload files** — Save generated reports, processed documents, or other outputs to specific Drive locations. * **Download files** — Retrieve files from Drive for processing or analysis within an agent. * **Copy files** — Duplicate files within Drive, optionally to a different folder or with a new name. * **Move files and folders** — Reorganize your Drive by moving items between folders. * **Move to trash** — Remove files or folders by sending them to the trash, where they can be restored within 30 days. * **Share and manage permissions** — Control who can view, comment on, or edit specific files and folders. ## Key Benefits * **Automated file organization** — Agents create consistent folder structures and file naming without manual effort. * **Reliable storage** — Every output lands in the right location, every time, with no misfiled documents. * **Controlled sharing** — Permissions are set automatically based on your workflow rules, reducing access mistakes. * **Hands-free retrieval** — Agents find and pull the files they need without interrupting you. ## Works Well With Store generated documents and spreadsheets in organized Drive folders, creating a complete document workflow. Store generated documents and spreadsheets in organized Drive folders, creating a complete document workflow. Save email attachments to structured Drive locations, or attach Drive files to outgoing messages. Share Drive links in channels automatically when new reports or deliverables are ready. Share Drive links in channels automatically when new reports or deliverables are ready. # Google Sheets Source: https://docs.duvo.ai/user-guide/connections/available-connections/google-sheets Google Sheets is a cloud-based spreadsheet platform used across teams for tracking data, managing records, and collaborating on reports. Connecting it to Duvo lets your agents read, write, and manage spreadsheet data on your behalf, turning static sheets into dynamic data sources for automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account. ## Capabilities * **Create spreadsheets** — Generate new spreadsheets and add sheets to existing ones to organize data for your workflows. * **Read spreadsheet data** — Pull values from any sheet you have access to, including cell ranges, full sheets, and multi-tab workbooks. * **Update individual cells** — Modify specific cell values to keep records current as your agent processes information. * **Batch update and append rows** — Write or append large volumes of data efficiently, including CSV imports, without manual entry. * **Clear data ranges** — Remove values from specific cell ranges to reset sheets or prepare them for fresh data. * **Format cells** — Apply formatting such as number formats, text styles, and colors to keep spreadsheets readable and professional. * **Rename and organize sheets** — Rename, reorder, and delete tabs within a spreadsheet to reflect their contents or workflow stage. * **Row-change triggers** — Start a Run automatically when values change in watched columns of a spreadsheet row. See [Triggers](#triggers) for setup and limits. ## Triggers The Google Sheets trigger starts a Run when a row's watched values change in a connected spreadsheet — including when a value changes back to what it was before. | Field | What it does | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Spreadsheet** | Google Sheets URL or spreadsheet ID to watch. Native Google Sheets only — not `.xlsx` files uploaded to Google Drive. | | **Tab** | Sheet or tab name to watch. Leave empty to watch the first tab. | | **Columns** (required) | Columns to watch, for example `B:D` or `C:` (through column ZZ). Open-ended ranges must start at or before column ZZ. Watch only columns people edit, not columns Duvo writes to — otherwise every write starts another Run. | | **Row range** (required) | Rows to watch, for example `2:90` or `5:`. Watch windows cap at 5,000 rows. Row numbers can be up to 10,000,000. | | **Key column** | A stable, unique identifier column, for example a customer ID. Recommended when rows can be re-sorted or inserted — without it, the trigger falls back to row number, which shifts when rows move. | Both the columns and row range filters are required, so the trigger always watches a bounded area instead of the whole sheet. Columns and rows combined can cover up to 250,000 cells — a range that exceeds this budget is rejected when you try to save it, so you always know exactly what's being watched. The trigger checks the spreadsheet on a schedule (see [Scheduling Agents](/user-guide/assignment-features/scheduling-assignments)). It compares the current values in the watched columns against the last-seen values for each row and starts a Run for every row whose values changed, including a row that changes back to a previous value. Rows whose values have not changed since the last check do not start a Run. If more than 250 rows change between checks, Duvo processes the first 250 and catches up on the next check. Changing the trigger's settings — spreadsheet, tab, columns, row range, or key column — resets change tracking. The next check records a fresh baseline of the watched range and does not start Runs. Watch only the columns people edit, not the columns Duvo writes results into. A write into a watched column starts another Run — and can keep starting new Runs on every check if the value keeps changing. ## Key Benefits * **Central data hub** — Connect your agents to the spreadsheets your team already uses, with no migration required. * **Bulk operations** — Read or write hundreds of rows at once, including direct CSV imports, saving hours of manual data entry. * **Real-time record keeping** — Keep spreadsheets current with automated updates as your agents complete their work. * **Audit trails** — Log every agent action in a spreadsheet for complete transparency and easy review. * **No database required** — Use familiar spreadsheets as a lightweight data layer without standing up infrastructure. ## Workflow Examples See [Google Sheets Workflows](/user-guide/examples/google-sheets-workflows) for step-by-step tutorials covering the three most common patterns: logging data to a live tracker, driving bulk actions from a spreadsheet list, and enriching rows with information from external sources. ## Works Well With Pull data from incoming emails and log it in a tracking spreadsheet, or use spreadsheet data to personalize outgoing messages. Store exported spreadsheets or source files in Drive, and use Sheets for structured data processing alongside unstructured documents. Scrape data from web pages and write the results directly into a spreadsheet for analysis or reporting. ## Troubleshooting ### Error: "This operation is not supported for this document" If you encounter the error `MCP error -32603: Error listing sheets: This operation is not supported for this document`, this is likely because you're trying to access an imported `.xlsx` file rather than a native Google Sheet. MCP error when trying to access an imported .xlsx file **Why this happens**: The Google Sheets API has a limitation where certain operations are not supported on imported Excel files (`.xlsx`). When you upload an Excel file to Google Drive, it remains in `.xlsx` format by default, even though you can view it in the Google Sheets interface. You can identify these files by the `.xlsx` extension in the filename or the Excel icon in Google Drive. Native Google Sheet (Working) vs Imported .xlsx file (Not Working) **Solution**: Convert the imported file to a native Google Sheet format: Open the `.xlsx` file in Google Sheets. Go to **File** > **Save as Google Sheets**. Use the new Google Sheet URL for your agent. Save as Google Sheets option in the File menu After saving as a native Google Sheet, copy the new spreadsheet URL and use that in your agent. The Google Sheets connection will work correctly with the converted file. **Alternative solution**: If you need to preserve the `.xlsx` format (for compatibility with other systems), you can use the [Google Drive connection](/user-guide/connections/available-connections/google-drive) instead. With Google Drive, the agent can download the `.xlsx` file to its local workspace, read or modify it directly, and upload it back to Google Drive while keeping the original Excel format intact. # Granola Source: https://docs.duvo.ai/user-guide/connections/available-connections/granola Granola is an AI notepad for meetings that automatically captures notes, generates transcripts, and surfaces action items from your calls. Connecting Granola to Duvo lets your agents read meeting notes and pull action items into automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Granola account. ## Capabilities * **Access meeting notes** — Retrieve notes from past meetings stored in your Granola workspace. * **Read transcripts** — Pull full conversation transcripts for summarization, compliance, or follow-up tasks. * **Extract action items** — Surface tasks and commitments identified by Granola from meeting recordings. ## Key Benefits * **Automated follow-up** — Trigger workflows from meeting outcomes without manually copying notes or action items. * **Centralized record-keeping** — Move meeting insights into your project management tools or documentation systems automatically. * **Faster post-meeting handoff** — Let agents pick up action items from Granola and route them to the right people or systems. ## Works Well With Automatically create issues or tasks from meeting action items captured in Granola. Automatically create issues or tasks from meeting action items captured in Granola. Write meeting summaries and decisions directly into your team's documentation workspace. Write meeting summaries and decisions directly into your team's documentation workspace. Post meeting highlights and next steps to team channels immediately after calls. # HubSpot Source: https://docs.duvo.ai/user-guide/connections/available-connections/hubspot HubSpot is a CRM platform for managing contacts, deals, and customer support. Connecting HubSpot to Duvo lets your agents create and update CRM records, track deals through your pipeline, and handle support tickets automatically. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your HubSpot account. ## Capabilities * **Contact and company management** — Create, update, and look up contact and company records in your CRM. * **Deal tracking** — Create deals, move them through pipeline stages, and monitor sales progress. * **Support ticket handling** — Create, update, and resolve tickets for customer support workflows. * **Activity logging** — Record calls, emails, meetings, and notes against CRM records. * **CRM data retrieval** — Search and pull contact, company, deal, and activity data for reporting or downstream automation. ## Key Benefits * **Automated CRM hygiene** — Keep contact and deal records accurate without manual data entry. * **End-to-end sales workflows** — Bridge lead capture, deal tracking, and customer communication in a single automated process. * **Consistent activity history** — Ensure calls, emails, and meetings are logged against the right records every time. * **Cross-tool visibility** — Combine HubSpot data with other connections to power reporting and notifications. ## Works Well With Send emails to HubSpot contacts and log the communication back to their CRM record automatically. Send emails to HubSpot contacts and log the communication back to their CRM record automatically. Post deal updates, new lead alerts, or ticket notifications to sales or support channels. Post deal updates, new lead alerts, or ticket notifications to sales or support channels. Export contact or deal data into spreadsheets for pipeline analysis and reporting. Export contact or deal data into spreadsheets for pipeline analysis and reporting. # Human in the Loop Source: https://docs.duvo.ai/user-guide/connections/available-connections/human-in-the-loop Human in the Loop lets your agents pause and ask for your input before proceeding with decisions that need a human eye. It is automatically available for every agent — no setup or configuration required. ## Setup No setup required. Human in the Loop is a built-in connection that is automatically available for every agent. ## Capabilities * **Request approval before acting** — The agent pauses and presents you with a title and description of the proposed action so you can approve or reject before it proceeds. * **Gate sensitive communications** — Review outgoing emails, messages, or other external-facing actions before they are sent. * **Enforce AOP checkpoints** — Add approval steps to your AOP so the agent always pauses at the points you choose, rather than deciding on its own when to ask. ## Key Benefits * **Stay in control** — Maintain oversight over critical decisions without slowing down routine automation. * **Reduce risk** — Ensure important actions are reviewed before execution, preventing costly mistakes. * **Flexible oversight** — Add approval steps in your AOP wherever you want human involvement and let automation run freely everywhere else. * **Built-in governance** — Create natural approval workflows and audit trails for sensitive operations. ## How It Works When your agent reaches a Human in the Loop checkpoint, it pauses and presents you with the relevant information and a request for approval or input. **During live runs**: The prompt appears directly in the run window's session log. The agent stops and waits for you to review the information and tell it how to proceed through the run-time prompt. **For scheduled runs**: Pending approvals appear in [Requests](/user-guide/assignment-features/requests), where you can review and respond to all of them in one place. # Image Generation Source: https://docs.duvo.ai/user-guide/connections/available-connections/image-generation The Image Generation connection lets your agents create and edit images using Google's Gemini models. Generate visuals from text descriptions or restyle existing images, all within your workflow. ## Setup No setup required. Image Generation is available to every agent automatically. ## Capabilities * **Generate images from text** — Create visuals based on written descriptions, including product mockups, diagrams, illustrations, and more. * **Edit existing images** — Modify, restyle, or enhance images that are already part of your workflow. * **Control aspect ratio** — Generate images in a range of aspect ratios including square (1:1), landscape (16:9, 3:2), portrait (9:16, 2:3), and others to fit different formats. * **Create visual assets on demand** — Produce graphics inline without switching to separate design tools. ## Key Benefits * **No design tools required** — Generate and edit visuals directly within your agent's workflow without switching applications. * **On-demand creation** — Produce images exactly when and where they're needed in a process. * **Integrated output** — Visual content is generated as part of your agent's work, not as a separate step, so images flow naturally into documents, emails, and reports. ## Works Well With Generate images and include them directly in written documents or reports. Generate images and include them directly in written documents or reports. Create visual content for email communications, such as product mockups or summary graphics. Create visual content for email communications, such as product mockups or summary graphics. Generate charts or visual representations of spreadsheet data for reports. Generate charts or visual representations of spreadsheet data for reports. # Available Connections Source: https://docs.duvo.ai/user-guide/connections/available-connections/index Browse all pre-built connections that Duvo provides. Click any connection to learn more about its capabilities. ## Duvo Business Connections Built-in capabilities that extend what your agents can do. These are system-managed tools, most are automatically available without any setup. Navigate websites, fill forms, and interact with web applications. Control a Windows desktop to operate applications and automate workflows. Thorough investigation and comprehensive analysis. Exchange orders, invoices, and shipping documents with your trading partners. Extract text and data from email attachments. Access EU agricultural commodity prices from the European Commission. AI-powered web search for real-time information. Generate predictions from historical data using time series forecasting. Pause for human approval on critical decisions. Generate and edit images using AI models. Process PDFs, images, and scanned documents. Place and manage phone calls in workflows. Gather information from websites. Find, verify, and enrich collections of companies or people at scale. Control your own Windows machines via RDP for desktop automation. ## Microsoft 365 Connect to Microsoft's productivity suite. Requires authentication with your Microsoft account. Manage events, schedule meetings, and create Teams meetings in Outlook Calendar. Work with spreadsheets and data. Access and manage personal files and documents. Read, send, and manage emails. Access datasets, reports, and workspaces for analytics. Access document libraries and shared files. Send messages and post to channels. Create and edit documents. ## Google Workspace Connect to Google's productivity tools. Requires authentication with your Google account. Read, send, and manage emails. Manage events and schedules. Create and edit documents. Access and manage files. Work with spreadsheets and data. ## Productivity Connect to popular productivity and collaboration tools. Query product analytics, user behavior data, and experiment results. Run Apify Actors to scrape websites and pull structured data into any workflow. Manage tasks, projects, and workflows for team collaboration. Manage contacts, companies, deals, and tasks in your Attio CRM. Read and update employee records, time off, documents, and HR reports. Create, search, and manage documentation and knowledge bases. Access repositories, issues, and pull requests with a Personal Access Token. Access meeting notes, transcripts, and action items from Granola. Manage contacts, deals, tickets, and automate CRM workflows. Manage conversations, contacts, and automate customer messaging. Create and manage issues and projects. Manage pages, databases, and documentation. Manage deals, contacts, and sales pipeline data in Pipedrive CRM. Query, search, and manage CRM accounts, contacts, and opportunities. Manage products, orders, and customers in your Shopify store. Send messages and notifications to channels. Deep workspace integration with triggers and notifications. Manage support tickets, customers, and automate service workflows. ## Data Warehouses Connect to enterprise data platforms for querying and analysis. Run SQL queries against your data lakehouse. Query and analyze large datasets in Google Cloud. Query your data warehouse and retrieve business data. Query databases and manage project resources. ## Enterprise Connect to enterprise resource planning and operations systems. Access procurement data, supplier records, and spend visibility from Coupa. Access financial and business management data from Business Central. Access financial and operational data from your D365 F\&O environment. Manage financials, orders, inventory, and customer data via the NetSuite AI Connector. Access ERP data for finance, procurement, and operations. Read master data and operational records from classic on-premise SAP ECC ERP. Read process models, hierarchies, and dictionary entries from Signavio. Connect to remote servers to execute commands and retrieve system data. Access dashboards, workbooks, and data sources for analytics and reporting. Access customer, supplier, and financial records from your Workday environment. ## Logistics and Carriers Connect to carriers and freight providers for invoice and shipment data. Pull ocean invoice headers and per-container demurrage and detention charges. ## Custom Connections Connect to any system using your own MCP-compatible server. Connect to any MCP-compatible server with your own URL and credentials. # Intelligent Document Reader Source: https://docs.duvo.ai/user-guide/connections/available-connections/intelligent-document-reader The Intelligent Document Reader turns PDFs, Word files, and images into clean, structured text that Duvo can work with. It handles both text-based and scanned documents, extracting text and tables so your agents can process real-world paperwork automatically. ## Setup No setup required. The Intelligent Document Reader is available to every agent automatically. ## Capabilities * **PDF extraction** — Read and extract content from both text-based and scanned PDF documents. * **Word document processing** — Parse Word files and extract their text and structure. * **Image text recognition** — Use OCR to read text from photos, screenshots, and image files (JPG, PNG, GIF, WebP). * **Scanned document handling** — Convert scanned paperwork into usable text through optical character recognition. * **Table extraction** — Recognize and extract tabular data from documents while preserving structure. * **Complex layout handling** — Process documents with multiple columns, forms, and mixed content while preserving structure. ## Key Benefits * **Universal document reading** — Handle PDFs, Word files, images, and scanned paperwork through a single connection. * **No manual data entry** — Automate the extraction of text and tables from documents that would otherwise require manual processing. * **Scanned document support** — Process paper-based documents and photos just as easily as digital files, using built-in OCR. * **Structured output** — Get clean, organized text that your agents can immediately use for analysis, comparison, or reporting. Do not use the Intelligent Document Reader for spreadsheet files like XLSX, XLS, or CSV. These are structured data formats that should be handled by their dedicated connections (such as Google Sheets). ## Works Well With Extract data from PDF invoices or scanned forms and write the results into a spreadsheet for tracking. Process document attachments from emails automatically, extracting key information without opening each file manually. Process document attachments from emails automatically, extracting key information without opening each file manually. Download documents from web portals, then extract and analyze their contents in a single workflow. # Intercom Source: https://docs.duvo.ai/user-guide/connections/available-connections/intercom Intercom is a customer messaging platform for managing conversations, contacts, and support workflows. Connecting Intercom to Duvo lets your agents manage your messaging inbox, update contact records, and automate customer communication workflows on your behalf. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations), select the region where your Intercom workspace data is hosted (US, EU, or Australia), and authorize with your Intercom account. ## Capabilities * **Manage conversations** — Access, reply to, and update customer conversations across your inbox. * **Handle contact records** — Look up, create, update, and delete customer and lead profiles. * **Track conversation status** — Assign, close, and tag conversations as workflows progress. * **Manage companies and tickets** — Look up companies, configure ticket types and attributes, create and update support tickets, and search across them. * **Add notes and context** — Post internal notes on contacts. * **Search and read** — Search contacts, conversations, and tickets, and read help-center articles and admin details. ## Key Benefits * **Faster response times** — Handle routine replies and follow-ups automatically so customers hear back sooner. * **Consistent messaging** — Ensure standard replies and triage steps follow the same process every time. * **Up-to-date contact data** — Keep customer profiles current as interactions and workflow outcomes change. * **Reduced inbox backlog** — Let agents handle high-volume or repetitive conversations, freeing your team for complex issues. ## Works Well With Sync conversation outcomes back to customer records so your sales and support teams share the same view of each contact. Sync conversation outcomes back to customer records so your sales and support teams share the same view of each contact. Post conversation alerts, new lead notifications, or escalation triggers to the right channels in real time. Post conversation alerts, new lead notifications, or escalation triggers to the right channels in real time. Bridge email-based support with Intercom conversations to keep all customer communication in one place. Bridge email-based support with Intercom conversations to keep all customer communication in one place. # Linear Source: https://docs.duvo.ai/user-guide/connections/available-connections/linear Linear is a project management tool built for development teams to track issues, plan sprints, and coordinate work. Connecting Linear to Duvo lets your agents create, update, and manage issues directly in your Linear workspace as part of automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Linear account. ### Admin approval on Enterprise workspaces If your Linear workspace is on the Enterprise plan and has [third-party application approvals](https://linear.app/docs/third-party-application-approvals) enabled, a workspace admin needs to approve **Duvo** once before members can connect. When a non-admin clicks **Enable**, Linear prompts them to request approval instead of completing authorization — an admin then approves Duvo workspace-wide from Linear's settings. On Free, Standard, and Plus workspaces, or on Enterprise workspaces without approvals enabled, any member can connect their own account directly. ## Capabilities * **Create and update issues** — Open new issues with titles, descriptions, and priorities, or update existing ones as workflows progress. * **Manage comments and attachments** — Add context to issues by posting comments, attaching files, or downloading existing attachments. * **Organize with labels** — Create, apply, and remove labels to keep issues categorized and easy to find. * **Retrieve project and team data** — Pull issue details, list projects, view team members, and access cycle or sprint information. * **Run advanced queries** — Execute custom queries for reporting or specialized data retrieval. * **Linear triggers** — Start a Run automatically when a Linear issue is created, assigned, changes workflow state, or gets a new comment. See [Triggers](#triggers) for event types and filter options. ## Triggers Linear triggers fire in real time as activity happens in the Linear workspace you connected. Pick one event type per trigger, then narrow it down with optional filters. ### Event types | Event | Starts a Run when… | | ----------------------- | ------------------------------------------------------------------------------------------ | | **New issue** | A new issue is created. | | **Issue assigned** | An issue is assigned to someone. | | **Issue state changed** | An issue moves into a new workflow state (for example, from **Started** to **Completed**). | | **New comment** | A comment is posted on any issue. | ### Filters All filters are optional. Leave a filter empty to match everything. | Filter | Applies to | What it does | | --------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Teams** | All events | Only fire for issues in specific Linear teams. Add one or more team keys (for example, `ENG`, `DESIGN`). Leave empty to match every team in the workspace. | | **Assignee** | All events | Only fire when the issue is assigned to a specific person. Add one or more Linear user IDs, or use `me` to match whoever connected Linear to Duvo. | | **Workflow state** | New issue | Only fire when the new issue lands in one of the selected state categories: **Triage**, **Backlog**, **Unstarted**, **Started**, **Completed**, or **Canceled**. | | **Destination state** | Issue state changed | Only fire when the issue moves into one of the selected state categories: **Triage**, **Backlog**, **Unstarted**, **Started**, **Completed**, or **Canceled**. | Each matching Linear event starts its own Run, and the Run prompt includes the issue context (title, description, team, assignee, state) so the Agent can act on it without extra lookups. The trigger watches the entire Linear workspace you connected — activity from any team or user in that workspace can match, subject to the filters above. ## Key Benefits * **Automated issue creation** — Generate tickets automatically from workflow events, customer requests, or bug reports without manual entry. * **Event-driven automation** — Kick off Duvo workflows the moment a Linear event occurs — no polling, no manual triggers, no delays. * **Synchronized tracking** — Keep Linear updated in real time as your workflows execute and tasks complete. * **Consistent documentation** — Ensure every issue is created with complete, standardized information. * **Less context switching** — Let agents handle routine issue management while you focus on higher-value work. ## Works Well With Automatically create Linear issues from incoming support emails or customer requests, keeping your inbox and backlog in sync. Automatically create Linear issues from incoming support emails or customer requests, keeping your inbox and backlog in sync. Post issue updates to team channels when agents create or close Linear issues, keeping everyone informed without manual status reports. Generate project summaries or sprint reports in your documentation tool based on Linear issue data. Generate project summaries or sprint reports in your documentation tool based on Linear issue data. # Maersk Source: https://docs.duvo.ai/user-guide/connections/available-connections/maersk Pull ocean invoice headers and per-container demurrage and detention charges from your Maersk account. **Beta** — This connection is in beta and may change. It is enabled per team: if Maersk does not appear on your Connections page, ask Duvo to turn it on. Maersk is a global ocean carrier and logistics provider. Connecting Maersk to Duvo lets your agents pull invoice headers and per-container demurrage and detention charges straight from your Maersk account, so freight spend checks and charge disputes run against live data instead of manual portal exports. This connection returns invoice **headers** — invoice number, bill of lading, dates, amounts, currency, and status. Maersk's API does not expose charge line items or the invoice PDF. See [What this connection cannot do](#what-this-connection-cannot-do). ## Setup A Maersk account with a customer code. Your code starts with a two-letter country code, for example `DK00007951`. An account on the [Maersk Developer Portal](https://developer.maersk.com/). Registration is self-service — you do not need a sales representative to create the account. An app registered on the portal, which gives you a Consumer Key and Consumer Secret. Register the app before you need the connection. Access to each API product is approved manually by Maersk and bound to your customer code, and Maersk does not publish a turnaround time — starting early avoids a wait later. On the Developer Portal, request access for your app to both products this connection uses: * **Ocean Invoices** — invoice headers by customer code. * **Import Demurrage & Detention** — per-container free time and accrued charges. Each request is reviewed by Maersk and granted against a specific customer code. Requesting one does not grant the other. Until a product is approved, calls to it return `403` even though your credentials are valid. Duvo reports that as a distinct message so you can tell it apart from a bad Client ID or Secret. On the [Connections page](https://app.duvo.ai/integrations), open Maersk and fill in these fields: The Consumer Key of your app on the Developer Portal. Maersk also requires it as the `Consumer-Key` header on every call, which Duvo handles for you. The Consumer Secret of the same app. Your Maersk customer code, starting with a two-letter country code — for example `DK00007951`. Used as the default for both tools; individual requests can override it. Leave empty for production. Enter `pre-production` to target `api-stage.maersk.com` instead. Access to each environment is granted separately. Enter `true` if your country permits credit transfers for cancelled invoices. Leave empty for `false`. Affects how Maersk reports credits, and an agent can override it on an individual request if credits come back wrong. Maersk identifies a customer differently across the two APIs, and for some accounts the two values differ: * **Ocean Invoices** uses the country-prefixed form, such as `DK00007951`. * **Import Demurrage & Detention** uses a carrier customer code that is often all digits, such as `33100971688`. Enter the country-prefixed form as your Customer Code. If demurrage and detention lookups report an invalid customer code, pass the numeric form on the request instead — the charges tool accepts an override. Maersk allows **1,000 calls per hour and 60 calls per minute** per Consumer Key, shared across every API product. Duvo caches the access token between calls so a scheduled run over many bills of lading does not spend the quota re-authenticating, and reports a `429` with the quota named so it is clear what was hit. * [Maersk Developer Portal](https://developer.maersk.com/) — registration, app creation, and API product access requests. * [Maersk API Solutions](https://www.maersk.com/digital-services/data-integrations/api) — overview of the API programme and available products. * [MyFinance invoice help](https://www.maersk.com/support/faqs/view-invoices) — viewing, downloading, and disputing invoices, including the invoice PDFs this connection cannot retrieve. ## Capabilities * **List ocean invoices** — retrieve invoice headers for a customer code by category (open, paid, overdue, or credits), with invoice number, bill of lading, invoice and due dates, invoiced and open amounts, currency, and status. * **Filter by document or date** — narrow to specific bills of lading, invoice numbers, or payment receipt numbers, or to a date range. A date range is required when listing paid invoices without specific documents. * **Check demurrage and detention** — for a bill of lading, get per-container free days, free-time start and last free date, chargeable days, the accrued amount with its per-day rate tiers, and whether the charge is final or still an estimate. * **Work across Maersk brands** — Maersk A/S, Safmarine, Sealand Americas, Sealand Europe, Sealand Asia, and Maersk Line Limited, selected per request by carrier code. ## What this connection cannot do Being explicit here saves a wasted agent run: * **No charge line items.** Maersk's Ocean Invoices API returns header-level data only. To see what makes up an invoice total, open the invoice PDF in MyFinance on maersk.com, or use the demurrage and detention tool — that is where the per-container charge detail lives. * **No invoice PDF download.** The API has no document endpoint. Results flag whether a PDF exists on maersk.com, but retrieving it is a portal action. * **No pagination.** Maersk returns every matching invoice in one response. Duvo caps what it hands back and tells the agent how many were omitted, so broad queries should be narrowed with a date range or specific document numbers. * **Import shipments only, within a window.** Demurrage and detention are available from 10 days before vessel arrival to 250 days after. Outside that window Maersk returns nothing. ## Key Benefits * **Freight spend checks on live data** — agents read current invoice status instead of a stale portal export. * **Charge detail where disputes happen** — demurrage and detention are the most commonly disputed ocean charges, and the per-container breakdown is available directly. * **Clear failure messages** — an unapproved API product, a rejected credential, and a rate limit each report differently, so setup problems are quick to place. * **Scales across bills of lading** — token caching and result caps mean a scheduled run over many shipments stays inside Maersk's quota. ## Works Well With Build freight spend summaries or demurrage exposure trackers from invoice and charge data. Reconcile Maersk invoice headers against internal accruals in a spreadsheet. Extract charge line items from invoice PDFs the API does not return. Pull invoice PDFs that arrive by email, or send overdue and dispute follow-ups. Alert the team when demurrage starts accruing or an invoice goes overdue. Retrieve invoice PDFs and line-item detail from MyFinance when the API is not enough. # Microsoft Calendar Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-calendar Microsoft Calendar (Outlook Calendar) is Microsoft's scheduling and time-management service, available through both personal Microsoft accounts and Microsoft 365 work or school accounts. Connecting it to Duvo lets your agents manage events, schedule meetings, invite attendees, and attach Microsoft Teams links — all without manual data entry. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **List events** — View existing calendar events filtered by date range, with details like attendees, location, status, and online meeting links. * **Create events** — Schedule new meetings or appointments with a title, start and end times, time zone, attendees, and location. * **Update events** — Modify event details such as title, time, description, or location. * **Get a single event** — Fetch one event's full details by ID to review or take a follow-up action on it. * **Cancel events** — Delete events the agent created or has rights to remove. * **Schedule Teams meetings** — Opt into auto-attaching a Microsoft Teams join link when creating an event. Available on Microsoft 365 work or school accounts; personal Microsoft accounts will create the event without a Teams link. * **Dual account support** — Works with both personal Microsoft accounts and Microsoft 365 work or school accounts. ## Key Benefits * **Automated scheduling** — Create calendar events automatically when workflow conditions are met, removing manual scheduling steps. * **Reliable follow-ups** — Ensure every customer call, check-in, or deadline gets a calendar entry without relying on memory. * **Conflict-free booking** — Agents check existing events before scheduling, reducing double-bookings. * **Teams links built in** — Meeting join links land in the invite automatically, with no copy-paste from a separate tool. * **End-to-end coordination** — Combine scheduling with other agent actions so meetings, reminders, and agendas stay aligned with your processes. ## Works Well With Send meeting invitations or follow-up emails alongside newly created calendar events. Post a channel notification whenever a new meeting is scheduled or an event is updated. Read a sheet of appointments to batch-create calendar events, or pull scheduling data into a spreadsheet for reporting. # Microsoft Dynamics 365 Finance & Operations Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-dynamics-365 Microsoft Dynamics 365 Finance & Operations (F\&O) is an enterprise ERP platform by Microsoft covering finance, procurement, supply chain, and manufacturing. Connecting it to Duvo lets your agents query customers, vendors, legal entities, and other business data directly from your F\&O environment through its OData API. ## Setup A Microsoft Entra (Azure AD) app registration with the **Microsoft Dynamics ERP** API permission (listed as `Microsoft.ERP` in the Azure portal) and admin consent granted. A client secret generated for the app registration in the Azure portal under **Certificates & secrets**. The app registration mapped in your F\&O environment under **System administration > Setup > Microsoft Entra applications**, with the Client ID entered, a service account user assigned, and the State set to Enabled. The service account user in F\&O assigned security roles that grant at least read access to the data entities your agents need (for example, customers, vendors, and legal entities). New to app registrations? Follow [Register an application in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) to create the app registration and generate client secrets. * The Azure AD app registration must have **API permissions** for the **Microsoft Dynamics ERP** API (`Microsoft.ERP`) with admin consent granted at the tenant level. * The mapped F\&O application user must be assigned security roles that cover the data entities you plan to query. For read-only access to customers and vendors, a role such as **Accounts receivable clerk** and **Accounts payable clerk** (or a custom role with equivalent privileges) is sufficient. The F\&O security roles assigned to the service account user determine exactly which data entities the agent can reach. Scope them to only the entities the agent needs. On the [Connections page](https://app.duvo.ai/integrations), open Microsoft Dynamics 365 Finance & Operations and fill in these fields: Your F\&O environment base URL (for example, `https://your-instance.operations.dynamics.com`). Find it in Lifecycle Services or your browser address bar when logged into F\&O. Your Microsoft Entra tenant GUID. Find it in the Azure portal under **Microsoft Entra ID > Overview** or **App registrations**. The Application (client) ID from the Azure AD app registration that has F\&O API permissions. A client secret generated for the app registration. Found under **Certificates & secrets** in the Azure portal. A company code (dataAreaId) such as `USMF`. Scopes all queries to this company by default. If left blank and only one legal entity exists, Duvo selects it automatically. Override for the Microsoft token endpoint. Defaults to `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token`. Only change this if your tenant uses a custom authority. Override for the OAuth scope. Defaults to `{environmentUrl}/.default`. Only change this if your environment requires a non-standard scope. * [Register an application in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) — creating the app registration and generating client secrets. * [Service endpoints overview (Finance & Operations)](https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/services-home-page) — registering external applications and configuring Microsoft Entra applications in F\&O. * [OData service endpoints (Finance & Operations)](https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/odata) — available data entities and OData query capabilities. ## Capabilities * **Query customers** — list, filter, sort, and paginate customer records from the CustomersV3 entity, including contact details, payment terms, and addresses. * **Query vendors** — list, filter, sort, and paginate vendor records from the VendorsV2 entity with full supplier details. * **Look up full partner details** — retrieve comprehensive information for a single customer or vendor by account number, returned as a formatted record with all available fields. * **Search across business partners** — run a simultaneous search across both customers and vendors by name to quickly find matching records. * **Discover legal entities** — list all legal entities (company codes) in your F\&O environment to identify the right data scope for other queries. * **Run flexible OData queries** — execute custom OData queries against allowed data entities with filtering, field selection, sorting, and pagination for scenarios not covered by the built-in tools. ## Key Benefits * **Direct ERP access** — agents read from your F\&O environment in real time instead of relying on manual data exports or screen-by-screen navigation. * **Cross-company querying** — query across all legal entities at once or scope to a single company, without switching sessions in F\&O. * **Secure credential handling** — Azure AD client credentials are encrypted at rest and designed to avoid exposure in logs or API responses. * **Denormalized data** — F\&O data entities include related information (addresses, contacts, payment terms) as top-level fields, so agents get complete records in a single query. * **Finance-ready data** — pull customer credit limits, vendor records, and company information for reconciliation, reporting, and compliance workflows. ## Works Well With Pull F\&O customer or vendor data into spreadsheets for financial analysis, reconciliation, or reporting. Pull F\&O customer or vendor data into spreadsheets for financial analysis, reconciliation, or reporting. Retrieve business partner details and include them in automated notification or approval emails. Retrieve business partner details and include them in automated notification or approval emails. Post alerts and status updates based on F\&O data to the relevant business channels. Post alerts and status updates based on F\&O data to the relevant business channels. # Microsoft Excel Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-excel Microsoft Excel is a spreadsheet application within Microsoft 365. Connecting it to Duvo lets your agents read, write, and analyze spreadsheet data stored in OneDrive or SharePoint, turning static workbooks into dynamic data sources for automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **Create workbooks** — Generate new Excel workbooks to store reports, logs, or structured output. * **Manage worksheets** — Add new worksheet tabs, list existing tabs, and rename them to organize data across logical sections within a workbook. * **Read spreadsheet data** — Retrieve values from workbooks stored in OneDrive or SharePoint for use in agent workflows. * **Update cells** — Modify individual cell values to keep records current. * **Batch update cells** — Write to multiple cells in a single operation for efficient bulk data entry. * **Append rows** — Add new rows after the last occupied row in a table or range without overwriting existing content, keeping running logs and datasets growing cleanly. * **Import from CSV** — Overwrite a range of cells from a CSV file already in the agent workspace, replacing existing data in a single operation. * **Append rows from CSV** — Add rows from a workspace CSV file onto an existing table or range, merging new records without disturbing what is already there. * **Clear cells** — Remove values, formatting, or both from one or more ranges in a single operation — useful for resetting templates or wiping stale data before a fresh run. * **Format cells** — Apply number formats when writing data — currency symbols, thousands separators, percentages, date patterns, and more — so values display correctly without manual reformatting. ## Key Benefits * **Central data hub** — Connect agents to the Excel workbooks your team already relies on in OneDrive or SharePoint. * **Flexible data operations** — Read individual values or batch-update hundreds of cells in a single step. * **Real-time record keeping** — Keep workbooks current with automated data entry instead of manual updates. * **No database required** — Use familiar Excel workbooks as your agent's data source without standing up a separate database. ## Finding Workbooks Agents can open any Excel workbook you have access to — paste a URL or refer to the workbook by name, and Duvo locates the right file. Supported locations include personal OneDrive, SharePoint team sites, Microsoft Teams-connected sites, and root SharePoint libraries. Standard page links and "Copy link" share links from the Excel UI both work. ## Works Well With Pull data from incoming emails and log it directly into tracking spreadsheets, or send summary emails based on spreadsheet contents. Combine document management with spreadsheet data to maintain project dashboards and shared records in one ecosystem. Store and organize the workbooks your agents read from and write to, keeping file access seamless. # Microsoft Outlook Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-outlook Microsoft Outlook is a widely used email platform for personal and business communication. Connecting it to Duvo lets your agents read, send, and manage emails across both personal Microsoft accounts and work accounts through Microsoft 365, including shared and delegated mailboxes. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ### Prerequisites for shared mailbox access If you plan to use the connection with shared or delegated mailboxes (for example, a team inbox like `reservations@yourcompany.com`), two things must be in place on the Microsoft 365 side: * **Tenant admin consent.** A Microsoft 365 admin in your organization must approve Duvo's request for shared-mailbox permissions (`Mail.ReadWrite.Shared`, `Mail.Send.Shared`). This is a one-time approval per tenant. * **Per-mailbox delegation.** The user account you connected must be granted **Full Access** on each shared mailbox it needs to read, move messages in, or mark as read, and **Send As** (or **Send on Behalf Of**) if the agent will send from that mailbox. These are managed by your Exchange admin. See Microsoft's guide to [managing shared mailboxes in Exchange Online](https://learn.microsoft.com/en-us/exchange/recipients-in-exchange-online/manage-user-mailboxes/enable-or-disable-shared-mailboxes) for the admin steps. ## Capabilities * **Access account info** — Retrieve the connected mailbox profile (email address, display name) when needed for workflows. * **Read emails** — List and retrieve emails with search queries, folder filters, or specific message IDs. Download individual attachments directly into the workspace for processing without re-fetching the full message. * **View email threads** — Retrieve an entire conversation thread for any message, giving the agent full context on an ongoing exchange. * **Send emails** — Compose and send messages with support for CC/BCC, HTML formatting, importance levels, and file attachments. * **Create drafts** — Save a new email as a draft for review or editing before sending. Supports recipients, subject, body, attachments, and importance level. * **Draft replies** — Create a draft reply to an existing email thread, preserving context, without sending immediately. * **Draft forwards** — Create a draft forward of any email for review before delivering to new recipients. * **List drafts** — Browse drafts saved in the Drafts folder, with optional search and limit filters, so an Agent can review or resume a previously drafted message. * **Send a draft** — Send a message that was previously saved as a draft. * **Manage categories** — List, create, update, and delete categories in a mailbox. Change an email's category automatically to organize the inbox. * **Flag emails** — Flag or unflag messages for follow-up to track items that need attention. * **Set email importance** — Adjust the priority level of a message (high, normal, or low) so recipients can triage their inbox appropriately. * **Move emails** — Relocate messages to any folder in the same mailbox, including well-known folders (Archive, Drafts, Sent Items, Deleted Items, Junk Email) and nested folder paths (for example `Inbox/Receipts`). * **Delete emails** — Permanently remove messages from a mailbox when they are no longer needed. * **Mark as read** — Mark messages as read after the agent has processed them to keep an inbox tidy. * **Mark as unread** — Reset a message to unread so it stays visible as a pending item. * **List folders** — Retrieve the full folder hierarchy in a mailbox, including nested subfolders, so the agent can locate and navigate any folder by name or path. * **Manage folders** — Rename or delete folders to reorganize a mailbox structure as part of an automated workflow. * **Email triggers** — Start a Run automatically on email received or sent events. See [Triggers](#triggers) for event types and filter options. * **Dual account support** — Works with both personal Microsoft accounts and work accounts through Microsoft 365. * **Shared and delegated mailboxes** — Read, send, move, mark as read, and manage messages on behalf of shared or delegated mailboxes, once the prerequisites under Setup are in place. ## Triggers The Outlook trigger starts a Run when a matching email event occurs. When you enable the trigger, choose an **Event type** from the dropdown: | Event type | What it does | | ------------------ | ------------------------------------------------------- | | **Email received** | Fires when a new email arrives in the inbox. | | **Email sent** | Fires when an email is sent from the connected account. | Each event type has its own set of optional filters: **Email received filters** | Field | What it does | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Emails from** | Only fire for emails from a specific sender. Leave empty to match any sender. | | **Folder** | Only fire for emails in a specific folder, including nested paths using `/` (for example `Inbox/Receipts`). Subfolders are not included automatically. Leave empty to monitor the whole mailbox. | | **Shared mailboxes** | Monitor one or more shared or delegated mailboxes (for example `reservations@yourcompany.com`) instead of the connected user's own inbox. Add multiple addresses to monitor several mailboxes with a single trigger. The folder filter applies to all mailboxes. Requires the prerequisites under [Setup](#prerequisites-for-shared-mailbox-access). | **Email sent filters** | Field | What it does | | -------------------- | --------------------------------------------------------------------------------------------------- | | **Emails to** | Only fire for emails sent to a specific recipient address. Leave empty to fire for all sent emails. | | **Shared mailboxes** | Monitor one or more shared or delegated mailboxes instead of the connected user's own sent folder. | ## Working with multiple shared mailboxes Some teams operate many shared inboxes — for example, one per hotel, store, or client — and want a single Agent to handle new emails across all of them. ### Trigger setup Add multiple addresses to the **Shared mailboxes** field in the trigger settings. Each address is a shared mailbox that Duvo will monitor for new emails. If you set a **Folder** filter, it applies to all mailboxes — name the folder the same across your shared mailboxes (for example `Inbox/Incoming`). Each incoming email triggers a separate Run. The Run prompt tells the Agent which shared mailbox the email arrived in, so Outlook tools (`read`, `send`, `move`, `mark as read`, etc.) automatically target the correct mailbox. ### Using shared mailboxes in the AOP If your Agent needs to work with shared mailboxes beyond the one that triggered it — for example, checking a second inbox or sending from a different address — list those mailboxes in the AOP. The Outlook tools all accept a mailbox parameter, so the same Agent can operate across any number of inboxes. Example AOP snippet: ```text theme={"dark"} After processing the triggering email, also check the following mailboxes for any related unread emails and process them the same way: - team-a@yourcompany.com - team-b@yourcompany.com ``` ## Key Benefits * **Full email automation** — Automate end-to-end email workflows from monitoring incoming messages to sending responses. * **Your account, your control** — Emails are sent from your address using your permissions, so recipients see messages from you. * **Flexible inbox management** — Search, filter, categorize, move, and respond to emails without manual effort. * **Event-driven workflows** — Use inbox triggers to kick off Runs the moment relevant emails arrive, including on shared mailboxes. * **Shared mailbox support** — Manage team or departmental inboxes without requiring each member to connect their individual account. ## Works Well With Extract data from incoming emails and populate spreadsheets, or send summary reports based on spreadsheet contents. Notify a Teams channel when an important email arrives, or send follow-up emails after a Teams conversation. Save email attachments to SharePoint or send emails linking to shared documents. # Microsoft SharePoint Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-sharepoint Microsoft SharePoint is the document management backbone for many organizations. Connecting SharePoint to Duvo lets your agents access, organize, and manage files across your organization's SharePoint sites — bringing enterprise document workflows into your automations. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **Search and discover sites** — Find SharePoint sites across your organization by name or keyword. * **Browse files and folders** — List items in document libraries to see what content is available on a site. Use recursive listing to walk nested folder hierarchies and produce a full directory tree in one step. * **Download documents** — Pull files from SharePoint into your agent's workspace for processing. * **Upload files** — Push documents from your agent's workspace into SharePoint libraries. * **Create folders** — Set up new folder structures within document libraries to keep content organized. * **Move items** — Relocate files and folders to different locations within SharePoint or OneDrive. * **Copy files and folders** — Duplicate files or entire folder trees to the same or a different location. Copies use Microsoft's native async operation, so there is no file size limit. * **Delete items** — Move files or folders to the recycle bin, where they can be restored if needed. * **Share files and folders** — Generate shareable links (public or restricted to your organization) or send invitations to specific people by email or to Microsoft Entra groups, with control over view or edit access. * **Review access** — List who currently has access to a file or folder, including which permissions are inherited from a parent. * **Revoke access** — Remove a previously granted permission when someone no longer needs it. * **Create sharing links** — Generate view or edit links scoped to your organization or to anyone with the link. ## Key Benefits * **Enterprise document access** — Work with files stored in your organization's existing SharePoint infrastructure without manual downloads. * **Cross-site operations** — Search and interact with documents across multiple SharePoint sites in a single workflow. * **Two-way file sync** — Both read from and write to SharePoint, enabling full document lifecycle automation. * **Organizational structure** — Create folders, move files, and maintain document libraries programmatically. * **Automated access management** — Grant, audit, and revoke access to files and folders as part of your workflows, without manual handoffs to an admin. ## Works Well With Download spreadsheets from SharePoint, process or update data, and upload the results back. Pull Word documents from SharePoint for review, editing, or content extraction. Combine document management in SharePoint with team notifications and channel updates. # Microsoft Teams Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-teams Microsoft Teams is the collaboration hub within Microsoft 365, used by organizations for messaging, meetings, and file sharing. Connecting it to Duvo enables two things: your Agents can read and send Teams messages, manage channels, and schedule meetings — and you can trigger Agents directly from Teams by mentioning @Duvo in any channel or chat. ## Setup Microsoft Teams has a three-step setup: installing the Duvo app in your organization's Teams catalog, approving it in the Teams Admin Center, then linking your personal Teams account. This step adds the Duvo bot to your organization's Teams app catalog. A Duvo team admin starts the process. 1. Go to the [Connections page](https://app.duvo.ai/integrations) and open **Microsoft Teams**. 2. Click **Add to Teams** under the Organization section. 3. Sign in with your Microsoft work account when prompted. 4. If your Microsoft organization allows it, the Duvo app is submitted to your Teams catalog automatically. **If your organization requires admin approval:** Some organizations restrict which apps can be added. If you see a "Need admin approval" screen from Microsoft: * Click **Request access** on the Microsoft screen. * Your Microsoft admin will receive the request and can approve it in the Azure portal. * Once approved, come back and click **Add to Teams** again. After Step 1, the Duvo app may need approval from a Teams administrator before it becomes available. * The Duvo connection page shows **Pending admin approval** while waiting. * A Teams administrator approves the app in the **Teams Admin Center** under **Manage apps**. * Once approved, the status updates to **Connected** automatically the next time anyone visits the connection page. After the organization app is approved, each user links their own Teams account to enable Duvo to act on their behalf. 1. On the Teams connection detail page, click **Enable** under the Your Account section. 2. Sign in with your Microsoft work account and grant the requested permissions. 3. Your account status changes to **Connected** with your email shown. ### Enabling the Teams trigger for an Agent Once both steps are complete, you can enable the Teams trigger on individual Agents: 1. Open the Agent you want to trigger from Teams. 2. Go to the **Schedule** tab and open the **Microsoft Teams** trigger settings. 3. Toggle **Enable Teams trigger** on and save. Now you can mention **@Duvo** in any Teams channel or chat to start that Agent. ## Capabilities * **Channel messaging** — Send messages, replies, and notifications to specific Teams channels as Duvo. Read message history from channels. * **Chat conversations** — Read and send messages in individual and group chats as Duvo. Create new chats and manage chat membership. * **Message management** — Edit, delete, pin, and react to messages. Mark messages as important. Search messages across chats and channels. * **Channel management** — Create and delete channels, view channel details, and manage channel membership. * **Meetings** — Schedule, update, cancel, and list online meetings with attendees. * **File operations** — Upload, list, and delete files in Teams channel file folders. * **Team discovery** — Browse joined teams and channels, search users by name or email, and look up team rosters. * **@Duvo trigger** — Start any enabled Agent by mentioning @Duvo in a Teams channel or chat. Duvo responds in the conversation with results. ## How Messages Appear When an Agent sends a message in Teams, the message comes from **Duvo** (the bot account), not from the personal account you used to connect. This keeps automated messages visually distinct from messages sent by individual team members. Read operations (browsing message history, searching, looking up team members) continue to use your connected account. ## Key Benefits * **Start work from where your team already works** — Mention @Duvo in Teams to trigger Agents without switching to the Duvo app. * **Automated team updates** — Agents post results, alerts, and status reports directly to the channels where your team collaborates. * **Two-way communication** — Read incoming messages and respond in context, enabling interactive workflows. * **Meeting coordination** — Schedule and manage online meetings as part of automated processes. * **Enterprise-grade access** — Works with business Microsoft 365 accounts and respects your organization's permissions. ## Troubleshooting The Duvo app was submitted to your Teams catalog but hasn't been approved yet. Ask a Teams administrator to approve it in the **Teams Admin Center** under **Manage apps**. The status updates automatically once approved. Your Microsoft organization restricts app consent. Click **Request access** on the Microsoft screen, then ask your Microsoft admin to approve the request in the **Azure portal** under admin consent requests. Check that: 1. The Teams connection shows **Connected** (not pending) on the Connections page. 2. Your personal account is linked (Step 3 above). 3. The Teams trigger is enabled on the specific Agent you're trying to use. ## Works Well With Monitor emails for action items, then post summaries or follow-ups to a Teams channel for team visibility. Pull documents from SharePoint and share them in Teams conversations with relevant context. Generate reports in Excel and distribute highlights or key metrics to Teams channels automatically. # Microsoft Word Source: https://docs.duvo.ai/user-guide/connections/available-connections/microsoft-word Microsoft Word connects your agents to Word documents stored in OneDrive or SharePoint. Create, download, and update documents directly from your automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **Create documents** — Create new Word documents in OneDrive or SharePoint, specifying the folder or site where they should live. * **Find documents** — Search for Word documents by keyword, document URL, or document ID across OneDrive and SharePoint. Scope searches to a specific site or drive when needed. * **Download documents** — Retrieve Word files from OneDrive or SharePoint for processing within your workflows. * **Download as PDF** — Fetch a Word document as a PDF rendition directly from Microsoft's servers, saving the result to your agent's workspace for further processing or sharing. * **Update documents** — Upload a modified document back to OneDrive or SharePoint, replacing the existing version with conflict detection to prevent overwriting others' changes. * **Get document metadata** — Check a document's name, size, author, last-modified date, and web URL without downloading the full file. ## Key Benefits * **Automated document generation** — Produce polished reports, proposals, and correspondence without manual effort. * **Seamless Microsoft 365 integration** — Work directly with documents stored in OneDrive and SharePoint, keeping everything in your existing ecosystem. * **End-to-end document workflows** — Combine reading, editing, and saving documents into a single automated process. * **Enterprise-ready** — Works with business Microsoft 365 accounts and respects your existing permissions and sharing settings. ## Works Well With Pull data from spreadsheets and generate formatted Word reports from the results. Draft documents and send them as email attachments in a single workflow. Manage document libraries, create files in team sites, and keep shared folders up to date automatically. # NetSuite Source: https://docs.duvo.ai/user-guide/connections/available-connections/netsuite Oracle NetSuite is a cloud-based ERP platform that manages financials, order management, inventory, CRM, and business operations. Connecting NetSuite to Duvo lets your Agents read and manage enterprise data directly through the NetSuite AI Connector MCP, eliminating manual navigation of NetSuite screens. ## Setup If you connected NetSuite before this setup flow was introduced, that connection never completed authorization and cannot read or write data. Delete the old connection and create a new one following the steps below. In NetSuite, go to **Setup > Company > Enable Features > SuiteCloud** and turn on: **OAuth 2.0** **Server SuiteScript** **REST Web Services** These are account-level features required for the NetSuite AI Connector MCP, not OAuth scopes — you'll choose scopes separately when you create the Integration Record. Your NetSuite account ID is visible in your NetSuite URL (`https://.app.netsuite.com`); you'll need it later when entering the MCP Server URL in Duvo. The NetSuite role you use to authorize the connection (in a later step) must not be Administrator — NetSuite blocks the OAuth authorization flow for that role. Create or reuse a role that has the AI Connector MCP permissions assigned, and assign it to the user who will complete the OAuth consent. Do not use the Administrator role for this connection. NetSuite's AI Connector explicitly rejects Administrator-role sessions. Go to **Setup > Integration > Manage Integrations > New**. * Give the integration a name (for example, `Duvo`). * Under **Authentication**, enable **Authorization Code Grant (OAuth 2.0)**. * Under **OAuth 2.0 Scopes**, select only **NetSuite AI Connector Service**. * NetSuite requires the **Public Client** checkbox for the AI Connector MCP scope — check it. With **Public Client** checked, NetSuite does not issue a Client Secret; that's expected, since the Client Secret is optional in Duvo. * Add Duvo's redirect URI as an allowed redirect URI. You can find this URI in the Duvo connection form under **How to set up your OAuth app**. * Save the record. NetSuite displays the **Client ID** (and **Client Secret**, if you didn't check Public Client) once — copy them immediately. Need help with the Integration Record? See [NetSuite Integration Records](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771281.html) for creating and managing OAuth 2.0 Integration Records. On the [Connections page](https://app.duvo.ai/integrations), open NetSuite and fill in these fields: A custom name to help you identify this connection (for example, `NetSuite Production`). Your NetSuite AI Connector MCP endpoint. See **MCP Server URL formats** below for the exact form to use. The Client ID shown when you saved the Integration Record in NetSuite. The Client Secret shown when you saved the Integration Record in NetSuite. Only required for confidential-client Integration records — leave this blank for the standard Public Client setup above. Select **Continue to NetSuite**. You're redirected to NetSuite to sign in and approve access, then returned to Duvo with the connection active. ### MCP Server URL formats Replace `` with your NetSuite account ID: * `https://.suitetalk.api.netsuite.com/services/mcp/v1/all` — the account-wide endpoint, exposing the full NetSuite AI Connector MCP catalog. * `https://.suitetalk.api.netsuite.com/services/mcp/v1/suiteapp/` — scopes the connection to a single SuiteApp. Sandbox account IDs shown with an underscore (for example `1234567_sb1`) must use a hyphen in the hostname instead: `1234567-sb1.suitetalk.api.netsuite.com`. ### Reconnecting and troubleshooting If NetSuite revokes or expires the connection's tokens, select **Reconnect** on the NetSuite connection card. Duvo reuses the stored Client ID and Client Secret from the Integration Record automatically — you don't need to re-enter them. If an Agent's NetSuite tool calls fail, open the Integration Record in NetSuite and check its **MCP Execution Log** for the underlying OAuth or tool-call error. * [NetSuite AI Connector MCP](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_1563541660.html) — Oracle's guide to enabling and configuring the AI Connector MCP service. * [NetSuite Integration Records](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771281.html) — How to create and manage OAuth 2.0 Integration Records. * [NetSuite AI Connector connection URLs](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_0714082142.html) — The `/services/mcp/v1/all` and per-SuiteApp URL formats. * [MCP Standard Tools](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_0902023450.html) and [MCP Standard Tools SuiteApp](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_143403258.html) — What the AI Connector exposes and how to install a scoped SuiteApp. ## Capabilities * **Financial record management** — Read and manage accounts, general ledger entries, journal entries, and financial transactions. * **Customer and vendor management** — Access customer and vendor records including contact details, payment terms, and transaction history. * **Order and fulfillment tracking** — Retrieve sales orders, purchase orders, and fulfillment records across your operations. * **Inventory visibility** — Look up inventory items, stock levels, and warehouse data. * **Reporting and analytics** — Run saved searches and retrieve structured data for business reporting. ## Key Benefits * **Direct ERP access** — Agents query NetSuite data in real time, so reports and workflows reflect current records without manual exports. * **Broad operational coverage** — A single connection spans financials, CRM, inventory, and order management across your NetSuite environment. * **Secure OAuth authentication** — Uses NetSuite's standard OAuth 2.0 Authorization Code flow. Duvo stores the Client ID and Client Secret you supply in encrypted form, using them only to complete authorization and to refresh or reconnect the connection later. * **No NetSuite expertise required after setup** — Once connected, Agents translate natural-language requests into the correct NetSuite queries, so business users do not need to know NetSuite navigation paths. ## Works Well With Pull NetSuite financial data, vendor lists, or order summaries into spreadsheets for analysis and reporting. Pull NetSuite financial data, vendor lists, or order summaries into spreadsheets for analysis and reporting. Retrieve NetSuite records and include them in automated notifications, approval emails, or customer follow-ups. Retrieve NetSuite records and include them in automated notifications, approval emails, or customer follow-ups. Post NetSuite order updates, financial alerts, or inventory changes to team channels automatically. Post NetSuite order updates, financial alerts, or inventory changes to team channels automatically. # Notion Source: https://docs.duvo.ai/user-guide/connections/available-connections/notion Notion is a collaborative workspace for docs, databases, and project management. Connecting Notion to Duvo lets your agents create, update, and organize pages and databases in your workspace automatically. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Notion account. ## Capabilities * **Create and update pages** — Draft new pages, edit existing content, archive outdated pages, and duplicate templates to keep your workspace current. * **Manage databases** — Insert rows, update entries, query records, and modify database schemas to maintain structured data. * **Add structured content** — Append formatted content blocks, build out page layouts, and organize information with consistent structure. * **Search and retrieve information** — Find pages across your workspace, fetch database properties, and pull content into other workflows. * **Track comments and discussions** — Read and manage comments on pages to stay aligned with team conversations. * **List workspace members** — Retrieve user information for mentions, agents, and access management. ## Key Benefits * **Automated documentation** — Keep your Notion workspace up to date without manual page edits or copy-pasting between tools. * **Consistent structure** — Generate pages with proper formatting and organization every time, reducing drift across team docs. * **Living databases** — Maintain project trackers, contact lists, and inventories with entries that reflect real-time workflow results. * **Centralized knowledge** — Bridge your operational workflows with your team's single source of truth in Notion. ## Works Well With Summarize Slack discussions into Notion pages, or post Notion updates to channels so the team stays informed. Extract key details from emails and log them in Notion databases for tracking and follow-up. Sync project status between Linear issues and Notion roadmaps to keep planning docs accurate. # Microsoft OneDrive Source: https://docs.duvo.ai/user-guide/connections/available-connections/onedrive Microsoft OneDrive is the personal cloud storage layer of Microsoft 365. Connecting it to Duvo lets your agents access, organize, and manage files and folders stored in your OneDrive directly within automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **Browse files and folders** — List items in your OneDrive, navigate directory structures, and view file metadata such as size, type, and last-modified date. Use recursive listing to walk nested folder hierarchies and produce a full directory tree in one step. * **Download files** — Pull files from OneDrive into the agent workspace for processing, analysis, or transformation. * **Upload files** — Save new or updated files from the workspace back to OneDrive, with the option to specify a custom filename or destination folder. * **Create folders** — Set up new folder structures in OneDrive to keep outputs organized. * **Move and copy items** — Reorganize your OneDrive by moving files or folders to different locations, or copying files and folders to a new destination. Copies use Microsoft's native async operation, so there is no file size limit. * **Delete items** — Remove files or folders that are no longer needed. * **Share files and folders** — Generate shareable links (public or restricted to your organization) or send invitations to specific people by email or to Microsoft Entra groups, with control over view or edit access. ## Key Benefits * **Hands-free file management** — Agents can retrieve, process, and store files without manual uploads or downloads. * **End-to-end document workflows** — Combine file retrieval, transformation, and storage in a single agent. * **Microsoft 365 ecosystem** — Works alongside Outlook, Excel, Word, SharePoint, and Teams connections for unified Microsoft workflows. * **Secure OAuth access** — Uses Microsoft OAuth so your credentials are never shared directly with Duvo. ## Works Well With Download spreadsheets from OneDrive, run analysis or updates, and upload the results back. Pull document templates from OneDrive, generate or edit content, and save finished documents. Combine personal OneDrive storage with team-level SharePoint sites for workflows that span individual and organizational files. # Outbound Calls Source: https://docs.duvo.ai/user-guide/connections/available-connections/outbound-calls The Outbound Calls connection enables your Duvo agents to place and manage phone calls to vendors, partners, and internal contacts as part of automated workflows. Powered by ElevenLabs Conversational AI and Twilio, agents can dial numbers, follow dynamic call scripts, capture outcomes, and update your systems automatically. ## Setup An [ElevenLabs](https://elevenlabs.io) account with Conversational AI access. A [Twilio](https://www.twilio.com) account with an active phone number. Your Twilio phone number imported into ElevenLabs. See [Twilio native integration](https://elevenlabs.io/docs/eleven-agents/phone-numbers/twilio-integration/native-integration) for setup steps. At least one AI agent created in ElevenLabs with the imported phone number assigned. Make sure to enable all Overrides in the agent's Security tab. Setting up the phone number? Follow [Twilio native integration with ElevenLabs](https://elevenlabs.io/docs/eleven-agents/phone-numbers/twilio-integration/native-integration) to import your Twilio number into ElevenLabs. On the [Connections page](https://app.duvo.ai/integrations), open Outbound Calls and fill in these fields: Your ElevenLabs API key. Go to [ElevenLabs](https://elevenlabs.io), click **Developers** in the left sidebar, then select **API Keys**. Create a new key and copy it immediately — the full key is only shown once on creation. * [ElevenLabs API authentication](https://elevenlabs.io/docs/api-reference/authentication) * [Twilio native integration with ElevenLabs](https://elevenlabs.io/docs/eleven-agents/phone-numbers/twilio-integration/native-integration) * [ElevenLabs outbound calling via Twilio](https://elevenlabs.io/docs/conversational-ai/phone-numbers/twilio-integration/outbound-calling) ## Capabilities * **Place outbound phone calls** — Automatically dial vendors, partners, and internal contacts using an ElevenLabs voice agent and a Twilio phone number. Optionally override the agent's first message and prompt per call. * **Run text-based agent conversations** — Start a synchronous text conversation with an ElevenLabs agent without placing a phone call, useful for testing scripts or gathering information without voice. * **Monitor call status** — Track call progress in real time with status polling (in progress, completed, failed, no answer). * **Retrieve call transcripts** — Access the full conversation transcript after a call completes for audit trails and downstream processing. * **List and inspect voice agents** — Browse all ElevenLabs agents in your account and view details for a specific agent to choose the right one for each call. * **List available phone numbers** — See which phone numbers are available for outbound calls so agents can select or verify the correct caller ID. ## Key Benefits * **Reduce manual call volume** — Automate repetitive, process-driven calling scenarios that consume hours of team time. * **Shorten time-to-resolution** — Accelerate supplier and partner issue resolution with automated follow-ups triggered by data thresholds or report outputs. * **Standardize communication** — Ensure consistent messaging across markets and teams through governed, configurable scripts. * **Unlock call data** — Convert phone conversations into structured data that flows back into your systems for measurement, reporting, and optimization. * **Maintain a complete audit trail** — Track all calls, outcomes, transcripts, and system updates for full transparency and compliance. ## Works Well With Pull contact lists and call parameters from your spreadsheets, then write call outcomes back as structured records. Pull contact lists and call parameters from your warehouse, then write call outcomes back as structured records. Send follow-up emails after calls with summaries, next steps, or escalation details captured during the conversation. Send follow-up emails after calls with summaries, next steps, or escalation details captured during the conversation. Create tickets when calls surface issues that need human attention or cross-team coordination. Send notifications when calls surface issues that need human attention or cross-team coordination. # Pipedrive Source: https://docs.duvo.ai/user-guide/connections/available-connections/pipedrive Pipedrive is a sales CRM built around pipeline management. Connecting it to Duvo lets your agents manage deals, contacts, organizations, and sales activities directly inside your CRM. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Pipedrive account. ## Capabilities * **Deal management** — Create, update, and move deals through pipeline stages as workflows progress. * **Contact and organization records** — Retrieve, create, and update person and organization records in your CRM. * **Lead management** — Create and update leads, track them through qualification, and convert them into deals. * **Sales activity logging** — Log calls, meetings, and tasks against the right deals and contacts automatically. * **Pipeline data queries** — Search deals, pull activity history, and access pipeline metrics for reporting. ## Key Benefits * **Automated CRM updates** — Keep deal stages and contact records current without manual data entry after each sales interaction. * **Consistent activity logging** — Ensure every call, meeting, and task is recorded against the correct record. * **Pipeline visibility** — Surface deal status and sales progress in reports or downstream workflows. * **Less context switching** — Let agents handle routine CRM updates so your team stays focused on selling. ## Works Well With Send emails to Pipedrive contacts and log the communication back to their CRM record. Send emails to Pipedrive contacts and log the communication back to their CRM record. Post deal update alerts, new lead notifications, or pipeline summaries to sales channels. Post deal update alerts, new lead notifications, or pipeline summaries to sales channels. Export deal and pipeline data into spreadsheets for sales analysis and forecasting. Export deal and pipeline data into spreadsheets for sales analysis and forecasting. # Microsoft Power BI Source: https://docs.duvo.ai/user-guide/connections/available-connections/power-bi Microsoft Power BI is a business intelligence platform for building dashboards, reports, and data models. Connecting it to Duvo lets your agents access datasets, reports, and workspaces directly — pulling analytics data into automated workflows without manual dashboard checks. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Microsoft account. ## Capabilities * **Browse workspaces and content** — Discover available workspaces, datasets, and reports across your Power BI environment. * **Inspect dataset schemas** — Retrieve table names, column names with data types, and measures from any dataset before querying. * **Run DAX queries** — Execute DAX queries against your datasets and export the results as CSV for further analysis. ## Key Benefits * **Automated analytics access** — Pull Power BI data into workflows without manually checking dashboards or exporting files. * **Real-time metrics** — Access current analytics data rather than relying on periodic exports or screenshots. * **Your permissions, your control** — Uses your Microsoft credentials with your existing Power BI permissions and access levels. * **Business intelligence in every workflow** — Bring analytics data into automated workflows for smarter, data-driven decisions. ## Works Well With Pull Power BI metrics and include them in automated email reports to stakeholders. Pull Power BI metrics and include them in automated email reports to stakeholders. Query Power BI data and post performance summaries to team channels. Query Power BI data and post performance summaries to team channels. Export Power BI data into spreadsheets for further analysis or custom reporting. Export Power BI data into spreadsheets for further analysis or custom reporting. # Salesforce Source: https://docs.duvo.ai/user-guide/connections/available-connections/salesforce Salesforce is the leading CRM platform for managing customer relationships across sales, service, and marketing. Connecting Salesforce to Duvo lets your agents query, create, and update CRM records — accounts, contacts, opportunities, and custom objects — so your workflows always operate on live customer data. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Salesforce account. ## Capabilities * **Record management** — Create, read, update, and delete records across standard and custom objects, including accounts, contacts, and opportunities. * **SOQL queries** — Run Salesforce Object Query Language queries to retrieve and aggregate records matching specific criteria. * **SOSL search** — Use Salesforce Object Search Language to search across multiple objects at once. * **Schema exploration** — List all objects in your org and inspect their field metadata to understand your data model. * **Custom object support** — Work with any SObject in your org, not just standard Salesforce objects. ## Key Benefits * **Automated CRM hygiene** — Keep account, contact, and opportunity records current without manual data entry. * **End-to-end sales workflows** — Bridge lead capture, opportunity tracking, and customer communication in a single automated process. * **Custom object support** — Work with your unique Salesforce configuration, not just standard objects. * **Full query power** — Use SOQL and SOSL to retrieve exactly the data your workflows need, including cross-object searches and aggregations. ## Works Well With Send emails to Salesforce contacts and log the communication back to their CRM record automatically. Send emails to Salesforce contacts and log the communication back to their CRM record automatically. Post deal updates, new lead alerts, or stage-change notifications to sales channels. Post deal updates, new lead alerts, or stage-change notifications to sales channels. Export opportunity or account data into spreadsheets for pipeline analysis and forecasting. Export opportunity or account data into spreadsheets for pipeline analysis and forecasting. # SAP ECC Source: https://docs.duvo.ai/user-guide/connections/available-connections/sap-ecc SAP ECC (ERP Central Component) is SAP's classic on-premise ERP suite, the predecessor to S/4HANA. Connecting SAP ECC to Duvo lets your Agents read master data and operational records — customers, vendors, application logs, change documents, background jobs, and ERP tables — straight from your SAP system. SAP ECC is **read-only** in Duvo. Agents read from SAP ECC but never create, edit, or delete anything in your system. ## Setup This is a credential-based connection. You provide your SAP ECC host, client number, and a service-account login so Duvo can read data over the SAP RFC/SOAP bridge. A reachable SAP ECC system with the SOAP-RFC service (`/sap/bc/soap/rfc`) enabled. A SAP service account (for example, a dedicated `ZAPI_MCP` user) authorized for the function modules and tables you want to read. Your SAP **client (mandant) number** (for example, `800`). If your SAP ECC host is reachable only over plain HTTP, credentials are sent unencrypted in transit. For production, front your SAP system with TLS (HTTPS). On the [Connections page](https://app.duvo.ai/integrations), open SAP ECC and fill in these fields: Base URL of your SAP ECC system, including port (for example, `http://your-ecc-host:8000`). Your SAP client (mandant) number. Optional — defaults to `800` if left blank. The SAP service-account username. The password for that SAP service account. ## Capabilities This connection is **read-only** — Duvo reads from SAP ECC but never creates, edits, or deletes anything in your system. * **Read customers and vendors** — Retrieve master data such as customer (KNA1) and vendor (LFA1) records. * **Inspect operational records** — Read application logs, change documents, background jobs, and RFC error records. * **Query ERP tables** — Read from a curated set of whitelisted SAP tables for analysis and reporting. ## Key Benefits * **Reach classic SAP ERP** — Connect on-premise SAP ECC, not just S/4HANA, so teams still running ECC can put their ERP data to work. * **No manual extracts** — Read SAP data in place instead of exporting spreadsheets by hand. * **Read-only by design** — The connection only reads, so connecting it can't change or remove anything in SAP. ## Works Well With Pull SAP customer, vendor, or table data into a spreadsheet for analysis and reporting. Pull SAP customer, vendor, or table data into a spreadsheet for analysis and reporting. Answer "what's the status of this vendor / customer / job?" questions in chat from live SAP data. Answer "what's the status of this vendor / customer / job?" questions in chat from live SAP data. # SAP S/4HANA Source: https://docs.duvo.ai/user-guide/connections/available-connections/sap-s4hana SAP S/4HANA is a core enterprise resource planning (ERP) system that manages finance, procurement, supply chain, and operations data. Connecting SAP S/4HANA to Duvo enables your agents to query and retrieve live enterprise data directly from your SAP environment, eliminating manual data extraction and SAP transactions. SAP S/4HANA is **read-only** in Duvo. Agents can search and retrieve records but cannot create, update, or delete data in your SAP system. ## Setup Connecting SAP S/4HANA to Duvo requires three setup steps in your SAP system — creating a technical user, activating the required OData services with OAuth enabled, and registering an OAuth 2.0 client. Once complete, enter the credentials in Duvo to enable the connection. In your SAP system, run transaction `SU01` and create a technical user. * Set **User Type** to **System**. * Save the password — this becomes the `Client Secret` in Duvo. * Assign authorizations: * **Sandbox / testing:** `SAP_ALL` (validate connectivity only — never use in production). * **Production:** `SAP_BC_OAUTH2_API` plus the SAP-delivered specialist role for each API you plan to use — for example, `SAP_BR_BUPA_MASTER_SPECIALIST` (Business Partner), `SAP_BR_PRODMASTER_SPECIALIST` (Product), `SAP_BR_PRICING_SPECIALIST` (Pricing), `SAP_EWM_*` (Warehouse). Role names vary by S/4HANA release — check PFCG for your system's equivalents. `SAP_ALL` is a highly privileged profile that grants full access to the SAP system. Use it only to validate connectivity in a sandbox, never in production. For production, assign least-privilege roles: `SAP_BC_OAUTH2_API` plus the SAP-delivered specialist role per activated API. Run transaction `/IWFND/MAINT_SERVICE`. For each service below, add it with **System Alias** = `LOCAL` and check **Enable OAuth for Service**: * `API_BUSINESS_PARTNER` — Business partner, customer, and vendor data * `API_PRODUCT_SRV` — Product and material master data * `API_SLSPRICINGCONDITIONRECORD_SRV` — Sales pricing conditions * `API_WAREHOUSE` — Extended Warehouse Management (EWM) data Run transaction `SOAUTH2` and register a new OAuth 2.0 client. * **Client Type:** Confidential. * **Client ID** must match the technical user's username from the first step. * **Grant Type:** Client Credentials (uncheck all others). * Assign scopes for every service activated in the previous step. * After creating the client, edit it and check **Scope parameter may be omitted**. * Copy the **Token Endpoint URL** — you'll enter this as the `Token URL` in Duvo. On the [Connections page](https://app.duvo.ai/integrations), open SAP S/4HANA and fill in these fields: Any name to help you identify this connection later. Your SAP S/4HANA host URL (for example, `https://your-sap-host.com`). This is the base URL for all OData API calls. The OAuth 2.0 token endpoint copied in the previous step (for example, `https://your-sap-host.com/sap/bc/sec/oauth2/token`). Your technical user's username from the first step (for example, `MCP_DUVO`). Your technical user's password from the first step. SAP Client Number defaults to `100`. If your system uses a non-standard client number, contact your Duvo representative. * [SAP Help Portal — Activate and Maintain Services](https://help.sap.com/docs/SAP_S4HANA_CLOUD) — Guide for `/IWFND/MAINT_SERVICE` and OData service activation. * [SAP Help Portal — OAuth 2.0 configuration](https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_752/916a7da9481e4265809f28010a113a6a/cdb122d5c82e4b4da48e7c6f18535dfa.html) — Setting up OAuth clients and scopes in `SOAUTH2`. A step-by-step version of the setup above, with screenshots from a live SAP system. Use this if you're new to SAP administration or want to verify each screen before moving on. #### Step 1 — Create the technical user The technical user represents the Duvo connection in your SAP system. Already have one? Skip this step. If you don't know the password, reset it and note the new value. 1. Run transaction `SU01`. SU01 initial screen 2. Enter a username (e.g. `MCP_DUVO`) and click **Technical User**. Entering technical user name in SU01 3. On the **Logon Data** tab, set **User Type** to **System**. 4. Generate or set a password. Save it securely — this is the `client_secret` you'll enter in Duvo. Generating a password for the technical user 5. On the **Profiles** (or **Roles**) tab, assign authorizations. Assigning profiles or roles to the technical user > Role and profile agents depend on your specific SAP system. Always prefer least-privilege roles. > > * **Sandbox / testing only:** you can temporarily use `SAP_ALL` to validate connectivity. `SAP_ALL` is a highly privileged profile that grants full access to the SAP system — never use it in production. > * **Production:** ask your administrator to assign least-privilege roles. At minimum, this should include: > * `SAP_BC_OAUTH2_API` — OAuth plumbing (always required) > * The SAP-delivered role per activated API, for example `SAP_BR_BUPA_MASTER_SPECIALIST` (Business Partner), `SAP_BR_PRODMASTER_SPECIALIST` (Product), `SAP_BR_PRICING_SPECIALIST` (Pricing), `SAP_EWM_*` (Warehouse). > > Role names vary by S/4HANA release — check PFCG for your system's equivalents. 6. Save (`Ctrl+S`). #### Step 2 — Activate the OData services Four services need to be active with OAuth enabled: * `API_BUSINESS_PARTNER` * `API_PRODUCT_SRV` * `API_SLSPRICINGCONDITIONRECORD_SRV` * `API_WAREHOUSE` If they are already activated, skip this step. If a service is active but OAuth is not enabled, select it in the list and click the **OAuth** button in the toolbar. OAuth button in the /IWFND/MAINT_SERVICE toolbar Repeat the steps below for each service. 1. Run transaction `/IWFND/MAINT_SERVICE`. /IWFND/MAINT_SERVICE initial screen 2. Click **Add Service**. Add Service button in /IWFND/MAINT_SERVICE 3. Enter **System Alias** = `LOCAL` and the **Technical Service Name** (for example `API_BUSINESS_PARTNER`). Click **Get Services** (or press Enter). 4. Select the service from the results and click **Add Selected Services**. Selecting the service and clicking Add Selected Services 5. In the **Add Service** dialog: * **Package Agent:** click **Local Object** for `$TMP` (sandbox), or enter a transport request (production). * Check **Enable OAuth for Service**. * Leave **ICF Node** and **System Alias** at their defaults. * Click **Continue**. Add Service dialog with Enable OAuth checked 6. Verify the service appears in the list with OAuth enabled (checkbox column on the right). Verifying OAuth enabled for the service #### Step 3 — Register the OAuth 2.0 client Create an OAuth 2.0 client bound to the technical user from Step 1, with Client Credentials grant and the scopes from Step 2. 1. Run transaction `SOAUTH2`. SOAUTH2 initial screen 2. In **OAuth 2.0 Administration**, click **Create**. Clicking Create in OAuth 2.0 Administration 3. **Client ID** (wizard step 1): * **Client Type:** Confidential * **OAuth 2.0 Client ID:** must match your technical user's username (for example `MCP_DUVO`) * **Description:** any description * Keep **Token Lifetime** at `3600`. * Click **Next**. Wizard step 1 — Client ID configuration 4. **Client Authentication** (wizard step 2): leave defaults. Click **Next**. Wizard step 2 — Client Authentication defaults 5. **Grant Type Settings** (wizard step 3): check **Grant Type Client Credentials Active**, uncheck all others. Click **Next**. Wizard step 3 — Grant Type Client Credentials Active 6. **Scope Agent** (wizard step 4): add all the scopes for the OData services activated in Step 2. You can also assign scopes after creating the client. Wizard step 4 — Scope Agent 7. **Summary** (wizard step 5): review and click **Finish**. 8. Select the new client from the list, click **Edit** and check **Scope parameter may be omitted**, then click **Save**. 9. Copy the **Token Endpoint URL** — you'll need it for Duvo. Copying the Token Endpoint URL You now have everything you need to enable S/4HANA in Duvo. Return to the top of this page and fill out the **Connection Fields** with the values you collected. ## Capabilities * **Business partner management** — Search, filter, and retrieve detailed records for customers, vendors, and organizations, including addresses, bank accounts, tax numbers, and roles. * **Product and material lookup** — Query the product master for materials, finished goods, services, and raw materials with descriptions, plant-level data, and inventory valuations. * **Sales pricing analysis** — Look up base prices, discounts, and surcharges for products, filter by customer or sales organization, and review pricing validity periods. * **Warehouse visibility** — List EWM warehouses and inspect storage types and warehouse details. * **Flexible OData queries** — Run advanced queries across the Business Partner, Product, Pricing, and Warehouse OData APIs when standard searches are not sufficient. ## Key Benefits * **Live enterprise data** — Agents read directly from your SAP system, so reports and decisions reflect current data without manual exports. * **Secure OAuth authentication** — Uses the standard OAuth 2.0 Client Credentials flow with automatic token caching and refresh, keeping credentials safe and minimizing token endpoint calls. * **Cross-functional coverage** — A single connection spans finance, procurement, supply chain, pricing, and warehouse data across four SAP APIs. * **No SAP expertise required after setup** — Once your administrator completes the initial setup, agents translate natural-language questions into the correct OData queries, so business users do not need to know SAP transaction codes or API structures. ## Works Well With Pull SAP business partner lists, pricing tables, or inventory valuations into spreadsheets for analysis and stakeholder reporting. Pull SAP business partner lists, pricing tables, or inventory valuations into workbooks for analysis and stakeholder reporting. Retrieve SAP records and include them in automated notification or compliance reporting emails. Retrieve SAP records and include them in automated notification or compliance reporting emails. Query SAP data and post operational summaries, procurement alerts, or pricing updates to team channels. Query SAP data and post operational summaries, procurement alerts, or pricing updates to team channels. # Shopify Source: https://docs.duvo.ai/user-guide/connections/available-connections/shopify Shopify is an e-commerce platform for managing online stores. Connecting Shopify to Duvo lets your agents manage products, process orders, handle customer data, and automate store operations directly from your workflows. ## Setup Shopify offers two ways to connect: through Duvo's own Shopify app, or with your own custom app created in the Shopify Dev Dashboard. ### Connect with Duvo This method is temporarily unavailable while Shopify reviews Duvo's app. Use **Use your own Shopify app** below to connect in the meantime. On the [Connections page](https://app.duvo.ai/integrations), click **Enable** next to Shopify. Enter your store domain in the format `your-store.myshopify.com`, then click **Enable** to be redirected to Shopify's authorization screen. Authorize Duvo to access your store — you will be returned to Duvo with the connection active. ### Use your own Shopify app Create a custom-distribution app in your Shopify Dev Dashboard, then connect it to Duvo with its client ID and client secret. Sign in to the [Shopify Dev Dashboard](https://dev.shopify.com/dashboard) with a staff account that has the App development permission (store owners have it automatically). On the **Apps** page, click **Create app** at the bottom of the page and choose **Start from Dev Dashboard** — you do not need the Shopify CLI. Name the app and click **Create**. Open the app's **Versions** tab and create a version. Set **App URL** to `https://shopify.dev/apps/default-app-home` (the app has no interface of its own) and leave **Embed app in Shopify admin** off. Paste **all** of the following Admin API access scopes into the **Scopes** field. Duvo verifies them when you connect, and the connection fails if any are missing: ```text theme={"dark"} read_products,write_products,read_orders,write_orders,read_customers,write_customers,read_inventory,write_inventory,read_fulfillments,write_fulfillments,read_assigned_fulfillment_orders,write_assigned_fulfillment_orders,read_merchant_managed_fulfillment_orders,write_merchant_managed_fulfillment_orders,read_third_party_fulfillment_orders,write_third_party_fulfillment_orders,read_draft_orders,write_draft_orders,read_discounts,write_discounts,read_returns,write_returns,read_locations,read_files,write_files ``` In the same version, add Duvo's redirection URL to the **Redirect URLs** field, then release the version: ```text theme={"dark"} https://platform.duvo.ai/v1/oauth/callback/shopify ``` The same URL is shown on the Duvo connect form with a copy button. Open the app's **Settings** to find its **Client ID** and **Client secret**. Apps created from your store's account use custom distribution automatically — if your organization also has a Shopify partner account, select **Custom distribution** in the **Distribution** section of the app's Home page instead. On the [Connections page](https://app.duvo.ai/integrations), open Shopify, choose **Use your own Shopify app**, enter your store domain and the app credentials, then click **Continue to Shopify** to authorize. Shopify may warn that the app isn't verified — this is expected for a custom app you created yourself. ## Capabilities * **Product and variant management** — List, create, update, and delete products and their variants. Upload product images directly from a URL. * **Collection management** — Create collections, list and retrieve collection details, and add or remove products from collections. * **Order management** — List and retrieve orders, cancel, close, or reopen orders, and create refunds with optional suggested-refund calculation. * **Draft orders** — Create, update, complete, and send invoices for draft orders. * **Customer management** — List, create, update, and search customers by name, email, or phone. Customer and draft-order tools require [Protected Customer Data access](https://shopify.dev/docs/apps/launch/protected-customer-data) to be approved for your app. Custom apps created in the Shopify Dev Dashboard have Level 1 and Level 2 access available by default, with no Shopify app review required. * **Inventory** — Retrieve inventory levels across locations, adjust quantities, and set inventory to a specific value. * **Fulfillment** — List fulfillment orders, create and cancel fulfillments, and update tracking information. * **Discounts** — View active discount codes and create new code-based discounts in a single step, with no separate price rule required. * **Metafields** — Read and write metafields on any Shopify resource. * **Store and locations** — Retrieve shop details and list all fulfillment locations. * **Bulk export** — Run a bulk GraphQL export to download large data sets as a JSONL file written directly to the assignment's workspace. ## Key Benefits * **Hands-off store management** — Automate repetitive Shopify tasks so your team can focus on merchandising strategy and growth. * **Real-time data access** — Work with live store data instead of manual exports or scheduled reports. * **Cross-system workflows** — Combine Shopify data with other connections to drive end-to-end business processes. * **Consistent operations** — Ensure store updates follow the same process every time, reducing errors and missed steps. ## Works Well With Pull order and product data into spreadsheets for analysis, reporting, or inventory planning. Pull order and product data into spreadsheets for analysis, reporting, or inventory planning. Send order summaries, customer follow-ups, or inventory alerts based on Shopify data. Send order summaries, customer follow-ups, or inventory alerts based on Shopify data. Post order notifications, low-stock alerts, or daily sales summaries to team channels. Post order notifications, low-stock alerts, or daily sales summaries to team channels. # SAP Signavio Source: https://docs.duvo.ai/user-guide/connections/available-connections/signavio SAP Signavio is SAP's business process management suite for modeling, documenting, and governing how work gets done across an organization. Connecting Signavio to Duvo lets your Agents read your documented processes, model hierarchies, and dictionary definitions, so automations can ground their work in your organization's source-of-truth process knowledge. You can also export a process you've mapped in Clarity into Signavio as a new diagram. This is a credential-based connection. You provide your Signavio editor URL, tenant, and a Signavio account login so Duvo can read process content from your workspace and create new diagrams in it when you export from Clarity. ## Setup An SAP Signavio workspace, and an administrator who can manage users and access rights in it. The **API Edition license** assigned to the account you connect with (free from SAP — see the walkthrough). On workspaces with SSO enforced, this means a dedicated **non-SSO technical user**, because API-licensed users are the only ones who can sign in with a local password when SSO is on. Your Signavio **Workspace ID** (also shown as "Tenant ID") and the **editor base URL** for your region (for example, `https://editor.signavio.com`). **Your Signavio account must have API access (the API Edition license) enabled before this connection will work.** A normal web login is not enough: the connection saves, but every Run fails to read or export process content with an authorization error. The API Edition license is free but must be requested from SAP. Follow the **Detailed setup walkthrough** below to request the license, create the recommended technical user, and find your Workspace ID. Grant the connecting account access to the folder(s) whose processes Duvo should use. Duvo both **reads** process content **and exports** Clarity processes as new diagrams, so grant **Read + Write** (codes `R` + `W`) on the target folder. Read-only (`R`) access is enough if you only want Duvo to read processes, but the Clarity → Signavio export will fail without Write (`W`). Publish (`P`) is only needed if you want exports published into the Collaboration Hub. On the [Connections page](https://app.duvo.ai/integrations), open SAP Signavio and fill in these fields: The base URL of your Signavio editor for your region (for example, `https://editor.signavio.com`; US workspaces use `https://app-us.signavio.com`). Your Signavio Workspace ID — the `t=` value in your Signavio URL, or find it under **Help → Workspace information**. The username (usually an email) of the API-enabled account — the technical user is recommended. The local Signavio password for that account. ### Detailed setup walkthrough A step-by-step version of the setup above. Use this if you're new to Signavio administration or want to verify each step before moving on. The Workspace ID (shown as "Tenant ID" in Duvo) identifies your Signavio workspace. You'll need it when you request the API Edition license and when you fill out the connection fields. * **Easiest:** it's the `t=` query parameter in your Signavio URL on any hub page — for example `https://editor.signavio.com/p/hub?t=`**``**. * **Alternatively:** in the Process Manager **Explorer**, open the top menu **Help → Workspace information**. API access is governed by the **API Edition** license. It is free, does not consume a paid seat, and is API-only (an API Edition user cannot sign in to the Signavio web editor). It must be requested from SAP once per workspace. Open a support case in [SAP for Me](https://me.sap.com/) on component **`BPI-SIG-CA-API`** ("REST-API for SAP Signavio"), asking SAP to add the **API Edition license** to your workspace. Include your **Workspace ID** and your **region** (for example, EU / `editor.signavio.com`). SAP adds the license to the workspace at no charge — once it's available, it can be assigned to a user in the next step. SAP recommends a single non-personal technical user per integration, rather than reusing a person's login. This keeps the integration working when people leave and is required when SSO is enforced. 1. In the Process Manager **Explorer**, open **Setup → Manage users & access rights** (user management). 2. Invite a new user with a role-based email you control (for example, `signavio-integration@yourcompany.com`). 3. The technical user sets a **local Signavio password** via the registration email link. This local password — not an SSO login — is what you enter in Duvo. On workspaces with SSO enforced, only users holding the API Edition license can sign in with a local password. That is why a dedicated API technical user is the supported pattern for SSO tenants — a normal SSO-provisioned user has no usable local password for the API. 1. In user management, open the technical user and assign **only** the **API Edition** license from the license dropdown (no other license is needed). 2. Grant the technical user access to the folder(s) whose processes Duvo should use. Duvo both **reads** process content **and exports** Clarity processes as new diagrams, so grant **Read + Write** (codes `R` + `W`) on the target folder. Read-only (`R`) access is enough if you only want Duvo to read processes, but the Clarity → Signavio export will fail without Write (`W`). Publish (`P`) is only needed if you want exports published into the Collaboration Hub. You now have everything you need to enable Signavio in Duvo. Return to the top of this page and fill out the **Add the connection in Duvo** fields with the technical user's login, your Base URL, and your Workspace ID. * [SAP for Me](https://me.sap.com/) — open a support case on component `BPI-SIG-CA-API` to request the API Edition license. ## Capabilities This connection reads process knowledge from Signavio and can export a process mapped in Clarity into your workspace as a new diagram. * **Read process models** — Retrieve BPMN process diagrams and their details from your Signavio workspace. * **Browse the process repository** — Explore the folder and collection hierarchy to see how processes are organized. * **Look up dictionary entries** — Read Signavio Dictionary items: the reusable terms, roles, systems, and documents referenced across your processes. * **Export a Clarity process to Signavio** — Turn a process you've mapped in Clarity into a new BPMN 2.0 diagram in your Signavio workspace, matching your existing modeling conventions. Each export creates a fresh diagram in your repository's Preview view, ready to review and refine. ## Key Benefits * **Ground automations in real processes** — Agents work from your documented, approved processes instead of guessing how a workflow should run. * **Bring Clarity processes into Signavio** — Export a process Duvo helped you map as a ready-to-review BPMN diagram, without redrawing it by hand. * **One source of truth** — Every Agent references the same process models and definitions your team already maintains in Signavio. ## Works Well With Turn a documented Signavio process into a written AOP or runbook for your team. Turn a documented Signavio process into a written AOP or runbook for your team. Publish process summaries and definitions pulled from Signavio into your team's knowledge base. Answer "how does this process work?" questions in chat using the current model from Signavio. Answer "how does this process work?" questions in chat using the current model from Signavio. # Slack Source: https://docs.duvo.ai/user-guide/connections/available-connections/slack Slack is the communication hub where teams coordinate, share updates, and stay aligned. Connecting Slack to Duvo lets your agents send messages, manage channels, share files, and keep your team informed automatically. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Slack account. This installs a Duvo app in your workspace and links your personal Slack account. By default, messages and actions appear from the Duvo app in your workspace. Some actions (sending messages, reactions, editing, and deleting messages) can optionally act as you when configured in your agent's AOP. ## Capabilities * **Send messages** — Post updates to channels, send direct messages, reply to threads, and schedule messages for later delivery. * **Edit and delete messages** — Update or remove previously sent messages. * **React to messages** — Add and remove emoji reactions on messages. * **Manage channels** — Create, archive, unarchive, rename channels, set channel topics and purposes, and join public channels. * **Upload and download files** — Send documents, reports, images, and other files to channels and conversations, or download files from Slack to your workspace. * **Search and retrieve information** — Find past messages, pull conversation history, retrieve a specific message by channel and timestamp, and look up channel and user details. * **Coordinate team members** — Find users, look up user profiles, list all members of a channel, and invite or remove people from channels. ## Message Formatting Agents can write messages using standard Markdown, which is automatically converted to Slack's native formatting: * **Bold**, *italic*, and ~~strikethrough~~ text * Bullet and numbered lists * `Inline code` and multi-line code blocks * [Links](https://example.com) formatted as clickable Slack links * Headings rendered as bold text (Slack does not support native headings) * **Tables** — Markdown tables are rendered as native Slack tables, preserving rows and columns exactly as written Write your agent's AOP using standard Markdown. The formatting conversion happens automatically before the message is sent. ## Key Benefits * **Automated team updates** — Keep everyone informed with status reports, alerts, and workflow results posted directly to the right channels. * **Rich formatting and file sharing** — Share formatted messages, documents, spreadsheets, and images without manual uploads. * **Centralized notifications** — Route workflow outputs, alerts, and reports to the channels where your team already works. * **Seamless coordination** — Create channels, invite members, and manage channel topics as part of automated workflows. ## Works Well With Monitor incoming emails and post summaries or alerts to a Slack channel so your team stays informed without checking their inbox. Pull data from spreadsheets and share formatted reports or status updates in Slack on a regular schedule. Post project updates, new issue notifications, or sprint summaries to dedicated Slack channels to keep engineering and product teams aligned. ## Outcome Examples A team member mentions the Duvo app in any enabled channel with a question ("how many orders are stuck in pending?"). The agent queries your data source and posts a formatted answer back in the thread. No dashboards. No analyst required. Requests that arrive in #helpdesk, #ops-requests, or any shared channel are read, classified, and routed to the right person or ticketing system. The requester gets an acknowledgment in the thread; the right team gets a ticket or DM. Covers IT help, HR questions, finance approvals, and general ops. An agent polls your data warehouse or CRM every hour and posts a Slack notification only when a condition is met — inventory below reorder point, fraud rate above threshold, error count spiking. No noise when everything is fine. Every Monday morning, a structured summary of last week's key metrics is posted to your team's channel, pulled from live warehouse or CRM data. No manual preparation. See [Slack Mention Workflows](/user-guide/examples/slack-mention-workflows) for step-by-step setup for all of these patterns. # Slack Workspace Source: https://docs.duvo.ai/user-guide/connections/available-connections/slack-workspace The Slack Workspace connection installs the Duvo app into your Slack workspace, enabling notifications, human-in-the-loop interactions, and the ability to trigger agents directly from Slack. Unlike the personal [Slack connection](/user-guide/connections/available-connections/slack), which gives agents broader Slack actions and can optionally act as you for some steps, the Slack Workspace connection operates as the **Duvo app** for team-level notifications and Slack-triggered runs. ## Setup This is a **team-level** connection. A team admin installs the Duvo app once per Slack workspace from the Connections page, and each team member links their own Slack account from **Settings > Notifications** so Duvo can reach them individually. 1. Go to the [Connections page](https://app.duvo.ai/integrations). 2. Find **Slack Workspace** and click **Enable**. 3. Authorize the Duvo app to access your Slack workspace. 1. Go to **Settings**. 2. Open **Notifications**. 3. Link your Slack user account. This tells Duvo which Slack user to message when your agents need attention. ## How It Differs from the Slack Connection | | **Slack Connection** | **Slack Workspace Connection** | | --------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------- | | **Set up from** | Connections page (per user) | Connections page (per team) | | **Identity** | Duvo bot by default; some actions can act as you | Messages appear as the Duvo app | | **Purpose** | Send messages, manage channels, upload files as you | Notifications, human-in-the-loop requests, trigger agents from Slack | | **Scope** | Per user | Per team (one installation per Slack workspace), plus each user links their Slack account | ## Capabilities * **Human-in-the-loop notifications** — When an agent needs your approval or input, the Duvo app sends you a direct message. You can approve, deny, or answer questions directly in Slack, or click through to handle the request in Duvo. Multiple requests during a single run are grouped into one DM thread. * **Trigger agents from Slack** — Tag the Duvo app in any channel to start a run. The agent runs and posts results back to the same thread. Useful for on-demand reports, quick actions, and team-accessible automation without leaving Slack. * **File and image support** — When an agent is triggered from a Slack thread, any files or images attached to messages in that thread are automatically downloaded and made available to the agent for processing. * **Bot and third-party app message reading** — Agents capture the full content of all messages in a thread, including structured messages from bots and third-party Slack apps like Jira, GitHub, and PagerDuty. Titles, field values, and descriptions are extracted automatically. * **Live status updates** — While a Run is in progress, Duvo posts live progress messages in the Slack thread showing what the agent is currently doing. Updates clear when a human-in-the-loop request pauses the Run and resume when work continues. * **Formatted output delivery** — Agent output is posted back to the Slack thread with Markdown converted to Slack's native format. Long messages are split at paragraph boundaries, and tables are converted to a key-value format for readability. ## Key Benefits * **Respond without leaving Slack** — Handle approvals, answer questions, and review agent output directly in your team's communication hub. * **Team-wide access** — One installation covers the entire team. Any linked team member can trigger agents and receive notifications. * **Real-time visibility** — Live status updates keep everyone in the thread informed about run progress without switching to Duvo. * **Context-rich triggers** — Agents triggered from Slack threads automatically receive files, images, and bot messages as context, so requests can include supporting documents. * **Clear bot identity** — Messages from agents are clearly labeled as the Duvo app, keeping automated communication distinct from personal messages. ## Works Well With Use both connections together: the Slack connection for agents that need broader Slack actions or optional act-as-you behavior, and the Slack Workspace connection for bot notifications and Slack-triggered runs. Trigger an agent from Slack to process an email thread, then have results posted back to the Slack channel for team discussion. Ask the Duvo app in Slack to generate a report, and have the agent write results to a spreadsheet while posting a summary back to the thread. ## Notification Preferences You can enable or disable Slack notifications in **Settings > Notifications**. When enabled, the Duvo app sends you: * Human-in-the-loop requests (approvals, questions, input needed) * Error alerts when a run fails ## Troubleshooting * Verify the Slack workspace is connected on the [Connections page](https://app.duvo.ai/integrations) * Confirm your Slack user account is linked to your Duvo profile * Check that Slack notifications are enabled in Settings > Notifications * Make sure the Duvo app is not muted in Slack * Confirm you have admin permissions in your Slack workspace * Allow browser popups for the authorization flow * Check for network restrictions blocking OAuth * Verify the agent has Slack triggers enabled * Confirm you are tagging the Duvo app correctly * Ensure the agent is active and has a published build # Snowflake Source: https://docs.duvo.ai/user-guide/connections/available-connections/snowflake Snowflake is a cloud data warehouse used to store and analyze large volumes of structured data. Connecting Snowflake to Duvo lets your agents query your warehouse directly, pulling metrics, exploring tables, and using live data to inform decisions and reports. Snowflake is **read-only** in Duvo. Agents can run `SELECT`-style queries but cannot modify your data. ## Setup A Snowflake account with key-pair authentication enabled for the connecting user. An RSA key pair generated for the user, with the public key registered in Snowflake. You provide the private key to Duvo. A compute warehouse available for the role you plan to use. New to key-pair auth? Follow [Snowflake's key-pair authentication guide](https://docs.snowflake.com/en/user-guide/key-pair-auth) to generate the keys and register the public key. The Snowflake role you specify must have: * `USAGE` on the target warehouse, database, and schema * `SELECT` on any tables or views your agents need to read The role determines exactly what data the agent can reach. Scope it to only the databases, schemas, and tables the agent needs. On the [Connections page](https://app.duvo.ai/integrations), open Snowflake and fill in these fields: The RSA private key for authentication, in PEM format. Include the full key with the `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines. Your Snowflake account identifier, either `orgname-accountname` (e.g. `myorg-myaccount`) or the legacy locator (e.g. `xy12345.us-east-1`). Find it in your account URL or under **Admin > Accounts**. The Snowflake user configured with your public key. The default database to connect to. The default schema within the database. The compute warehouse to use for queries. The Snowflake role to assume for the session. This determines what data the agent can access. Optional. The passphrase used to decrypt the private key, if the key is encrypted. * [Snowflake key-pair authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth) — generating RSA keys and assigning the public key to a user. * [Snowflake account identifiers](https://docs.snowflake.com/en/user-guide/admin-account-identifier) — how to find your account identifier. * [Snowflake access control](https://docs.snowflake.com/en/user-guide/security-access-control-overview) — roles, privileges, and granting SELECT access. ## Capabilities * **Run read-only SQL queries** — execute SELECT, WITH (CTEs), SHOW, DESCRIBE, and EXPLAIN statements against your warehouse. Write operations are not permitted. * **Discover tables and schemas** — list all tables in a given database and schema, including row counts and comments, so agents can understand the data landscape before querying. * **Verify connection details** — check the active user, role, database, schema, and warehouse to confirm the session is configured correctly. * **Export large result sets** — query results exceeding 5,000 rows are automatically exported as CSV files for downstream analysis rather than returned inline. ## Key Benefits * **Live warehouse data** — agents read directly from Snowflake instead of relying on stale exports or manual data pulls. * **Safe by design** — only read-only operations are allowed, so your data cannot be modified through Duvo. * **Role-scoped access** — the Snowflake role you specify controls exactly which databases, schemas, and tables the agent can reach. * **Large-scale results** — automatic CSV export handles result sets of any size without truncation. * **Key-pair authentication** — no passwords are stored; authentication uses RSA key pairs for stronger security. ## Works Well With Query Snowflake and write the results into a spreadsheet for stakeholder review or recurring reports. Pull warehouse metrics and include them in automated email summaries or alerts. Monitor key business thresholds and post a notification to a channel when values change. ## Outcome Examples Every Monday, a summary of last week's revenue, order volume, and exception count is posted to your team's Slack channel or emailed to stakeholders. The agent queries your warehouse, calculates week-over-week changes, and distributes the formatted result automatically. No one needs to open Snowflake or prepare a report manually. An agent polls Snowflake every hour and fires a Slack notification when inventory drops below the reorder point, a fraud rate crosses a limit, or any other condition is met. It stays silent when everything is within bounds, so alerts stay signal, not noise. A stakeholder needs a fresh customer list, transaction export, or regional breakdown. The agent runs the query and writes the results into a named Google Sheet, including a "last refreshed" timestamp. Run on demand or on a schedule. See [Snowflake Workflows](/user-guide/examples/snowflake-workflows) for step-by-step tutorials covering all three patterns. # SSH Server Source: https://docs.duvo.ai/user-guide/connections/available-connections/ssh-server The SSH Server connection lets your agents connect to remote Linux or Unix servers and execute shell commands over SSH. Provide your server credentials, and Duvo handles the connection so agents can retrieve data, run scripts, and check system health without manual logins. ## Setup An SSH-accessible server (Linux, Unix, or any host running an SSH daemon). A user account on the target server with the permissions your agent needs. Either a password or a PEM-encoded private key for authentication. If connecting through a bastion host, credentials for the jump server (these can differ from the target server's credentials). * The SSH user account must have shell access on the target server. * Grant only the minimum permissions the agent needs. Avoid using root or highly privileged accounts unless the workflow specifically requires it. * If using key-based authentication, the public key must be added to the user's `authorized_keys` file on the server. The SSH user determines exactly what the agent can do on the server. Scope it to the minimum permissions the workflow needs, and avoid root or highly privileged accounts unless they are specifically required. On the [Connections page](https://app.duvo.ai/integrations), open SSH Server and fill in these fields: Hostname or IP address of the target server. SSH user account to authenticate with. SSH port on the target server (defaults to 22). Password for the user account (provide either password or private key). PEM-encoded private key (provide either password or private key). Passphrase to decrypt an encrypted private key. Hostname or IP of a bastion/jump server for two-hop connections. SSH port on the jump host (defaults to 22). User account on the jump host (required when a jump host is set). Password for the jump host (provide either password or private key). PEM-encoded private key for the jump host. Passphrase to decrypt the jump host private key. ## Capabilities * **Execute shell commands** — Run any shell command on the remote server and capture stdout, stderr, and exit codes. * **Read server data** — Retrieve logs, configuration files, and system status information directly from the source. * **Trigger remote processes** — Start scripts, batch jobs, or server-side operations as part of an end-to-end workflow. * **Check system state** — Query running processes, disk usage, service availability, or any other system metric. * **Connect through bastion hosts** — Reach servers behind firewalls by routing through a jump host with two-hop SSH tunneling. ## Key Benefits * **Replace manual SSH sessions** — Governed, repeatable automation instead of ad-hoc terminal logins. * **Access data at the source** — Pull logs, configs, and system metrics directly from servers without intermediate exports. * **Flexible server coverage** — Works with any server that exposes an SSH endpoint, regardless of operating system or cloud provider. * **Secure credential handling** — Supports both password and key-based authentication, with optional passphrase protection for private keys. * **Bastion host support** — Reach servers in private networks through jump hosts without exposing them directly. ## Works Well With Post command output, log excerpts, or system alerts to team channels after SSH commands run. Post command output, log excerpts, or system alerts to team channels after SSH commands run. Write retrieved server data into spreadsheets for tracking, analysis, or reporting. Write retrieved server data into workbooks for tracking, analysis, or reporting. Send automated notifications with server output or status summaries via email. Send automated notifications with server output or status summaries via email. # Supabase Source: https://docs.duvo.ai/user-guide/connections/available-connections/supabase Supabase is an open-source backend platform built on PostgreSQL. Connecting it to Duvo lets your agents query your database, browse table structures, and work with your project resources directly within automated workflows. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Supabase account. ## Capabilities * **Query databases** — Run SQL queries against your Supabase PostgreSQL database to retrieve, filter, and aggregate data. * **Manage tables** — Create, alter, and browse table structures, columns, and schemas in your project. * **Access project resources** — Interact with your Supabase project settings, storage, and configuration. ## Key Benefits * **Direct database access** — Query your Supabase data without manual exports or custom API calls. * **Secure authorization** — Uses OAuth so your credentials and project-level permissions are respected. * **Flexible querying** — Retrieve exactly the data your workflow needs from any table in your project. * **Current data** — Access live database records rather than relying on periodic exports or snapshots. ## Works Well With Pull Supabase data into spreadsheets for stakeholder reporting or further analysis. Pull Supabase data into spreadsheets for stakeholder reporting or further analysis. Query database records and include the results in automated notification or summary emails. Query database records and include the results in automated notification or summary emails. Retrieve data from Supabase and post updates or alerts to team channels. Retrieve data from Supabase and post updates or alerts to team channels. # Tableau Source: https://docs.duvo.ai/user-guide/connections/available-connections/tableau Tableau is a business intelligence platform for publishing and sharing interactive dashboards, workbooks, and data visualizations. Connecting Tableau to Duvo lets your agents access published analytics, query data sources, and incorporate live BI insights into automated workflows. Tableau connects through a **Connected App** using OAuth via JWT. This Duvo connection currently supports Connected App credentials only, so you create a Connected App in your Tableau site settings and provide those credentials to Duvo. ## Setup A Tableau Cloud or Tableau Server account with site role **Explorer** or higher. A site admin must [create and enable a Connected App](https://help.tableau.com/current/online/en-us/connected_apps_direct.htm) (Direct Trust) for Duvo. The app is disabled by default after creation and must be explicitly enabled. **VizQL Data Service** must be enabled on the site for data source schema and query capabilities. Available on Tableau Cloud by default; Tableau Server requires version **2025.1+**. **Data Management license** at the site level for Metadata API access (used for data source field enrichment). To create the Connected App: 1. Sign in to Tableau as a site admin. 2. Go to **Settings** > **Connected Apps**. 3. Click **New Connected App** > **Direct Trust**. 4. Enter a name (e.g., `Duvo Integration`). 5. Click **Create**. 6. Copy the **Client ID** displayed on the app page. 7. Click **Generate New Secret**. Copy both the **Secret ID** and **Secret Value** (the secret value is shown only once). 8. **Enable the Connected App** — it is disabled by default. Click the three-dot actions menu next to the app and select **Enable**. Authentication will fail until the app is enabled. For details on enabling these features, see the [Connected Apps documentation](https://help.tableau.com/current/online/en-us/connected_apps_direct.htm) and [VizQL Data Service configuration](https://help.tableau.com/current/api/vizql-data-service/en-us/docs/vds_vizql_data_service_config.html). The Tableau account you connect must have: * Site role of **Explorer**, **Explorer (Can Publish)**, **Creator**, **Site Administrator Explorer**, or **Site Administrator Creator**. Viewer is not sufficient. * **View** capability on workbooks and views that Duvo should access. * **View** and **Connect** capabilities on data sources that Duvo should access. * **API Access** capability on data sources for schema and query operations. This is not granted by default and must be explicitly assigned by an admin per data source or via project default permissions. The connected account's site role and per-content capabilities determine exactly what the agent can reach. Note that **API Access** is not granted by default, so an admin must assign it per data source or through project default permissions before schema and query operations will work. On the [Connections page](https://app.duvo.ai/integrations), open Tableau and fill in these fields: The Client ID shown when you create the Connected App in Tableau. The UUID generated when you click Generate New Secret in the Connected App settings. The secret value shown once when the secret is generated. Copy and store it securely. The Tableau username to act as. Use the user's email address for Tableau Cloud, or their Tableau username for Server. The base URL of your Tableau Cloud or Tableau Server site (e.g., `https://dub01.online.tableau.com`). The site name from your Tableau URL after `/site/`. For Tableau Server default site, leave this blank. * [Connected Apps (Direct Trust)](https://help.tableau.com/current/online/en-us/connected_apps_direct.htm) — creating and managing Connected Apps. * [REST API Authentication](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_auth.htm) — overview of Tableau authentication methods. * [VizQL Data Service Configuration](https://help.tableau.com/current/api/vizql-data-service/en-us/docs/vds_vizql_data_service_config.html) — enabling data source queries. ## Capabilities * **Browse published content** — List and discover workbooks, dashboards, views, and projects across your Tableau site. * **Inspect data source schemas** — Retrieve field names, types, and metadata for any connected data source. * **Run read-only queries** — Execute queries against published data sources and return results, without modifying any data in Tableau. ## Key Benefits * **Direct access to live analytics** — Query dashboards and data sources without manual logins or CSV exports. * **Automated data-driven workflows** — Use real-time Tableau data to trigger actions, populate reports, or inform decisions. * **Consistent source of truth** — Agents always reference the same published dashboards and data sources your team relies on. * **No data duplication** — Query data in place rather than exporting and re-importing between tools. ## Works Well With Pull data from Tableau data sources into spreadsheets for further analysis or distribution. Post dashboard summaries or metric alerts to channels based on Tableau data. Include Tableau-derived insights in automated email reports sent to stakeholders. # Web Scraper Source: https://docs.duvo.ai/user-guide/connections/available-connections/web-scraper The Web Scraper connection lets your agents scrape, crawl, and extract structured data from websites. Use it to pull content from individual pages or crawl entire sites, feeding live web data into your automated workflows. ## Setup No setup required. Web Scraper is available to every agent automatically. ## Capabilities * **Scrape web pages** — Extract text, tables, structured content, or screenshots from any publicly accessible URL, including JavaScript-rendered pages. * **Crawl websites** — Follow links across multiple pages to gather data from an entire site or section. * **Extract structured data** — Pull specific data points such as product listings, pricing tables, or contact details from one or more pages in a single operation. * **Discover URLs** — Map a website's structure to find relevant page URLs before scraping, useful for large sites where the exact page location is unknown. ## Key Benefits * **Live web data on demand** — Access current information from websites without manual copy-paste or browser work. * **Scale across pages** — Crawl dozens or hundreds of pages in a single run, far faster than manual collection. * **Structured output** — Get clean, organized data ready for spreadsheets, CRMs, or further analysis. * **No credentials required** — Works out of the box with publicly accessible sites, so you can start scraping immediately. ## Works Well With Use Web Scraper to pull raw content from specific pages, then hand it to Deep Research for synthesis and a structured summary. Write scraped data directly into a spreadsheet for reporting, comparison, or sharing with your team. Write scraped data directly into a spreadsheet for reporting, comparison, or sharing with your team. Feed company or contact data extracted from websites into your CRM to keep records current without manual data entry. Feed company or contact data extracted from websites into your CRM to keep records current without manual data entry. # Websets Source: https://docs.duvo.ai/user-guide/connections/available-connections/websets Websets lets your agents find, verify, and enrich structured collections of web entities at scale. Powered by Exa's Websets API, it automates building curated datasets of companies, people, or custom entity types — gathering matching results from the web and enriching them with additional information automatically. ## Setup No setup required. Websets is available to every agent automatically. ## Capabilities * **Build entity collections** — create websets of companies, people, or custom entities by specifying a search query and verification criteria. Exa finds matching entities from across the web automatically. * **Enrich items** — add enrichments to a webset that extract additional data points from each entity, such as contact details, funding stage, or product focus. * **Retrieve and inspect results** — list all items in a webset, retrieve individual item details including evaluations and enrichment results, and save results as JSON files for downstream processing. * **Manage websets** — update metadata, cancel running operations, or delete websets and their associated data. ## Key Benefits * **Scale** — search and enrich thousands of entities in a single run, far beyond what manual research can achieve. * **Structure** — results are returned as structured data, ready to load into spreadsheets, CRMs, or downstream automation. * **Verification** — each entity is evaluated against your criteria, with reasoning and source references, so you can trust the results. * **Accuracy** — Exa's semantic search finds entities by meaning and context, not just keyword matching, reducing irrelevant results. ## Works Well With Load enriched entity lists into a spreadsheet for review, scoring, or distribution. Load enriched entity lists into a workbook for review, scoring, or distribution. Push verified prospects directly into your CRM to trigger outreach sequences or update existing records. Push verified prospects directly into your CRM to trigger outreach sequences or update existing records. Go deeper on individual companies or people identified by a Webset search. # Windows Remote Desktop Source: https://docs.duvo.ai/user-guide/connections/available-connections/windows-remote-desktop The Windows Remote Desktop connection lets your agents control Windows machines in your own environment over RDP. Unlike Computer Use (which provides a Duvo-managed Windows sandbox), this connection targets your existing Windows servers, cloud VMs, or terminal servers, giving agents access to your internal systems, installed software, and network resources. **Beta** — This feature is currently in beta and may change. ## Setup A Windows machine accessible via RDP (Remote Desktop Protocol). RDP enabled on the target machine (port 3389 by default). A Windows user account with permissions to log in via RDP. Network connectivity between Duvo and your Windows machine. For private networks, contact your Duvo account team to set up VPN access. The Windows user account used for the connection needs: * **Remote Desktop Users** group membership (or equivalent) * Permissions for the applications and files the agent will access * **PowerShell execution policy** that permits the automation scripts to run — prefer a least-privilege scope (for example, `-Scope Process` or `-Scope CurrentUser`, and signed scripts) rather than relaxing the policy machine-wide * **Win+R (Run dialog) enabled** in Group Policy (required for UI automation) Scope the connecting account to only what the agent needs. Prefer a least-privilege PowerShell execution policy (for example, `-Scope Process` or `-Scope CurrentUser`, with signed scripts) rather than relaxing the policy machine-wide. On the [Connections page](https://app.duvo.ai/integrations), open Windows Remote Desktop and fill in these fields. Secrets are encrypted using Google Cloud KMS. A custom name for this connection to help you identify it later. RDP host address — the IP address or hostname of the Windows machine. Windows username used for RDP authentication. Windows password used for RDP authentication. RDP port — leave blank to use the default (3389). Windows domain, if the machine is domain-joined. Hostname or IP of a bastion/jump server for two-hop connections. SSH port on the jump host (defaults to 22). User account on the jump host (required when a jump host is set). Password for the jump host (provide either password or private key). PEM-encoded private key for the jump host. Passphrase to decrypt the jump host private key. ## How It Works Duvo connects to your Windows machine using the standard Remote Desktop Protocol (RDP) over port 3389 by default (configurable). The connection is secured with TLS encryption and CredSSP authentication. For machines on private networks, Duvo routes traffic through a site-to-site VPN tunnel to your infrastructure. RDP is a bidirectional protocol — it transmits keyboard and mouse input to the remote machine while streaming the desktop display back. From the Windows perspective, input from Duvo looks identical to input from a local user, which is why desktop applications work seamlessly. The agent can launch programs, click through menus, and type into fields exactly as a person would at that machine. ## Capabilities * **Control Windows applications** — Click, type, and navigate Windows applications installed on the target machine, subject to the connected user's permissions. * **UI Automation** — Interact with UI elements by name and type, not just pixel coordinates, making automation more reliable for thick-client applications. * **Sign in with stored Logins** — Use saved logins from [Logins and Secrets](/user-guide/resources/my-logins) to sign in to applications on the remote machine, including one-time 2FA codes, without exposing passwords to the agent. * **Run PowerShell scripts** — Execute PowerShell commands and scripts directly on the remote machine. * **Clipboard access** — Read from and write to the Windows clipboard for data transfer between applications. * **Access network resources** — Reach internal file shares, databases, and services available from the target machine. * **Live desktop view** — Watch the remote desktop in real-time as your agent works. ## Key Benefits * **Your environment, your data** — Work directly on your existing Windows infrastructure, with access to installed software and internal resources based on the connected user's permissions. * **Thick-client automation** — Automate legacy Windows applications, custom business software, and systems that only run on Windows. * **UI-aware interaction** — The UI Automation feature finds and interacts with UI elements by their properties, not just screen positions, making automations more robust. * **Enterprise integration** — Connect to Windows machines behind your firewall, on your VPN, or in any cloud or on-premises environment. * **Full visibility** — Watch the session live and review screenshots of every action for compliance and debugging. ## Works Well With Pull data from your warehouse or ERP, then enter it into a Windows-only application. Process files in desktop applications and send results by email. ## Limitations * Elevated (administrator) processes cannot be automated if the RDP user runs at a lower privilege level. # Workday Source: https://docs.duvo.ai/user-guide/connections/available-connections/workday Workday is a cloud-based enterprise platform for human capital management, financial management, and business planning. Connecting Workday to Duvo lets your agents read customer and supplier records and look up financial details directly from your Workday tenant without manual navigation. This is a credential-based connection. You will need a Workday administrator to configure an API client and integration system user before connecting. ## Setup A Workday tenant with SOAP Web Services enabled (enabled by default on most tenants). An **Integration System User (ISU)** configured in Workday. Your Workday administrator creates this under the *Create Integration System User* task. An **API Client** registered in Workday via the *Register API Client for Integrations* task, with the **Non-Expiring Refresh Tokens** option selected and appropriate scopes assigned. A **refresh token** generated for the ISU through *Manage Refresh Tokens for Integrations* on the registered API client. The Integration System User must have domain security policies granted for the Workday services your agents will access: * **Revenue Management** domain — required for reading customer records and balances. * **Resource Management** domain — required for reading supplier records. Your Workday security administrator assigns these through *Integration System Security* and then activates the pending security policy changes. The ISU's domain security policies determine exactly what the agent can access, so agents can only read what the ISU is authorized to see. Grant only the domains the agent needs, and remember to activate the pending security policy changes after assigning them. On the [Connections page](https://app.duvo.ai/integrations), open Workday and fill in these fields: Your Workday service hostname (for example, `wd2-impl-services1.workday.com`). Found in your browser address bar when logged into Workday. Your Workday tenant identifier (for example, `mycompany`). Your Workday administrator can confirm this value. The OAuth2 client ID shown after registering the API client in Workday. The OAuth2 client secret shown after registering the API client in Workday. This value is only displayed once — copy it during registration. The OAuth2 refresh token generated for your Integration System User. Generate this through *Manage Refresh Tokens for Integrations* on your API client. * [Workday Web Services (WWS) Directory](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html) — SOAP API reference for all Workday web services. * [Integration Security — Workday Community](https://community.workday.com/node/393246) — guide on configuring domain security policies for integration users. ## Capabilities * **List and search customers** — retrieve paginated customer records including name, category, payment terms, currency, status, credit limit, and contact details. * **View customer balances** — pull total balance, overdue balance, year-to-date sales, and last-twelve-month sales for any customer. * **List and search suppliers** — retrieve paginated supplier records including name, category, group, payment terms, currency, status, and contact details. * **Look up individual records** — get full details for a specific customer or supplier by ID, including address, phone, email, and bank information. * **Cross-entity partner search** — search customers and suppliers simultaneously when you need to find a business partner without knowing their entity type. ## Key Benefits * **Unified data access** — read customer records, supplier details, and financial data from a single Workday connection without switching between Workday modules. * **Automated data retrieval** — pull customer balances, supplier details, and partner records into your workflows automatically instead of exporting reports manually. * **Secure, scoped access** — uses your Integration System User credentials with domain-level security policies, so agents can only access what the ISU is authorized to see. * **No manual Workday navigation** — agents query Workday data directly, eliminating the need to log in and run reports by hand. ## Works Well With Pull Workday customer and supplier data into spreadsheets for financial analysis, vendor reviews, or stakeholder reporting. Retrieve Workday records and include them in automated notifications, approval requests, or follow-up emails. Post supplier updates, overdue balance alerts, or customer status changes to the relevant team channels. # Zendesk Source: https://docs.duvo.ai/user-guide/connections/available-connections/zendesk Zendesk is a customer service platform for managing support tickets, customer interactions, and service workflows. Connecting Zendesk to Duvo lets your agents create, update, and resolve tickets, look up customer information, and automate support operations directly within your existing helpdesk. ## Setup Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Zendesk account. ## Capabilities * **Ticket management** — Create, update, resolve, and escalate support tickets across your queue. * **Customer lookup** — Find and search customer profiles to pull the context an agent needs while handling a ticket. * **Ticket routing and triage** — Assign tickets to agents, set priorities, and apply tags based on content or customer attributes. * **Comments and internal notes** — Post public replies or internal notes on existing tickets, and read the full conversation history to understand what was already said. * **Organization lookup** — Retrieve or search organizations to understand which company a requester belongs to and pull company-level context. * **Group and field discovery** — List the groups used for ticket routing and assignment, and discover the custom ticket fields configured in your account so agents can read and set the right values. * **Tag management** — Add or remove individual tags on a ticket without overwriting its existing tag set. * **Support data retrieval** — Search tickets, count search matches to gauge volume before paging through results, pull activity history, and access resolution details for reporting or downstream workflows. ## Key Benefits * **Automated ticket creation** — generate tickets from workflow events without manual entry, keeping your queue current in real time. * **Consistent triage** — route and categorize incoming requests the same way every time, reducing human error. * **Always up-to-date records** — keep ticket status, context, and notes current as workflows progress across tools. * **Reduced manual work** — free your support team from routine data entry so they can focus on resolving issues. * **Cross-tool visibility** — combine Zendesk data with other connections to drive notifications, escalations, and reporting. ## Works Well With Monitor inbound support emails and automatically create or update Zendesk tickets from their content. Monitor inbound support emails and automatically create or update Zendesk tickets from their content. Post ticket updates, new request alerts, or escalation notifications to the right support channels. Post ticket updates, new request alerts, or escalation notifications to the right support channels. Export ticket data and resolution metrics for team reporting and trend analysis. Export ticket data and resolution metrics for team reporting and trend analysis. # Building Custom Connections Source: https://docs.duvo.ai/user-guide/connections/building-custom-connections Integrate systems Duvo does not support out of the box by building and connecting your own MCP server. Custom connections let you integrate systems that Duvo does not support out of the box, so you can automate work across proprietary tools. Building custom connections requires software development and deployment experience. ## What are Custom Connections? Custom connections allow you to connect Duvo to systems that aren't covered by a standard Duvo connection. Think of them as custom-built bridges between Duvo and your proprietary or specialized software. ## Building A Custom Connection Duvo uses the Model Context Protocol (MCP) open standard to connect with external systems—it's not a Duvo product. To build your own MCP server to create custom tools for your agents, you'll need technical expertise in software development. If you're not familiar with MCP, visit the [official MCP documentation](https://modelcontextprotocol.io/docs/getting-started/intro). This resource provides documentation, tutorials, and examples for building MCP servers in various programming languages. Once you have built, tested, and deployed an MCP server, you can connect it to Duvo using the steps outlined in [How to Add a Connection](/user-guide/connections/how-to-add-connection). ## Requirements for Custom Connections For your MCP server to connect to Duvo, it must meet these technical requirements: * **Cloud accessibility**: The MCP server must be accessible via the internet (cloud-hosted). Duvo needs to reach it over the web to communicate. * **Streamable HTTP**: The MCP server must support streamable HTTP communication. MCP servers that only support STDIO (standard input/output) or HTTP/SSE won't be able to connect to Duvo's agents. ## Setting Up OAuth for Custom MCP Connections If your MCP server requires OAuth authentication, Duvo automatically detects whether the server supports **dynamic client registration (DCR)**. When DCR is supported, no Client ID or Secret is needed — the connection is handled automatically. If the server does not support DCR, or if you prefer to use your own pre-registered OAuth app, expand the **Advanced settings** section when adding the connection. There you will find the **How to set up your OAuth app** guide, which provides step-by-step guidance and a one-click copy button for the redirect URI you need to register. **Steps (when providing your own OAuth credentials):** Register an OAuth app with your MCP provider (refer to the provider's developer documentation). Add Duvo's redirect URI as an allowed redirect URI in your OAuth app settings. The redirect URI is `https://platform.duvo.ai/v1/oauth/mcp/callback` (also displayed in the **Advanced settings** section with a copy button). Enter your Client ID and Client Secret in the **Advanced settings** fields and complete the connection setup. # Computer Use Source: https://docs.duvo.ai/user-guide/connections/computer-use-overview Let your agents operate Windows desktop applications via a Duvo-managed sandbox or your own machines over RDP. **Beta** — This feature is currently in beta and may change. Computer Use lets your agents operate Windows desktop applications, automating workflows that go beyond what browsers and APIs can reach. Duvo offers two ways to access Windows desktops, depending on whether you need a managed sandbox or access to your own infrastructure. ## Two Options | | [Computer Use](/user-guide/connections/available-connections/computer-use) | [Windows Remote Desktop](/user-guide/connections/available-connections/windows-remote-desktop) | | ----------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | **Environment** | Duvo-managed Windows sandbox | Your Windows machines | | **Setup** | None — automatically available | Provide RDP host, username, and password | | **Best for** | General desktop automation, testing workflows, processing files | Accessing internal systems, installed software, network resources | | **Data location** | Runs in Duvo's cloud | Runs on your infrastructure | | **Persistence** | Session state preserved within a run | Connects to your persistent environment | ## When to Use Each Use Computer Use when: * You need a clean Windows environment to process files or test workflows * The agent doesn't require access to your internal network or proprietary software * You want zero-config desktop automation Use Windows Remote Desktop when: * The agent needs your installed applications (custom ERP, industry software, licensed tools) * You need access to internal file shares, databases, or network resources * Compliance requires data to remain on your infrastructure ## How It Works Both connections give agents the ability to control a Windows desktop — clicking buttons, typing text, navigating menus, and reading screen content. The agent interacts with applications exactly as a person would, which means any Windows software can be automated regardless of whether it has an API. Computer Use provisions a fresh Windows sandbox for each session, managed entirely by Duvo. Windows Remote Desktop connects to your existing Windows machines over the standard RDP protocol, secured with TLS encryption. ## Shared Capabilities Both Computer Use options support: * **Desktop control** — Open, navigate, and operate Windows applications * **Click and type** — Interact with UI elements, forms, and dialogs * **Screen reading** — Capture and interpret what's displayed * **Live view** — Watch the desktop in real-time as your agent works * **Full audit trail** — Every action is captured for review Computer Use also supports **file transfer** between the sandbox and your agent, which is not available with Windows Remote Desktop. ## Related Pages Duvo-managed Windows sandbox Connect to your own Windows machines # Connections Overview Source: https://docs.duvo.ai/user-guide/connections/connections-overview Connect Duvo to Gmail, Slack, Google Sheets, Salesforce, and 40+ other tools. All connections are built on the Model Context Protocol (MCP). ## Introduction The Connections section is where you connect Duvo to the external services and tools your agents need to complete their tasks. Before an agent can access systems like Gmail, Microsoft Outlook, Google Sheets, or your CRM, you must first enable those connections. This gives your agents the ability to read data, perform actions, and automate workflows across all your essential business platforms. Connections ## How Connections Work Connections in Duvo are built on the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro). Whether you're using a standard connection like Gmail or Google Sheets, or connecting your own custom connection, they're all MCP servers under the hood. ## Connections and users Connections are configured per user. Each user needs to connect the connections they want their agents to use, using their own logins. This ensures that: * Agents act on your behalf using your permissions and access levels * Security is maintained through your existing authentication * Actions taken by agents are logged under your user account * Each team member can customize which connections they need ## Choosing the Right Pattern If you're not sure whether to use a hosted connection, browser automation, a custom MCP server, or Computer Use, see [Choosing the Right Connection Pattern](/user-guide/connections/integration-patterns) for a decision tree and trade-offs table. ## Connection Types Duvo offers two connection types: * **Standard Connections**: Pre-built connections to popular business tools like Microsoft 365, Google Workspace, and other common platforms. These are ready to connect with just a few clicks. * **Custom Connections**: These allow you to connect Duvo to systems that aren't covered by a Duvo Standard Connection. Details on how to build a custom connection for Duvo can be found in [Building Custom Connections](/user-guide/connections/building-custom-connections). ### Available Connections The Available Connections section displays all the pre-built connections that Duvo provides and maintains for popular business tools. Browse through categories like Microsoft 365 and Google Workspace to find the services you need. Each connection card shows the service name, icon, a brief description of its capabilities. Click the **"Connect"** button on any connection to authenticate and enable it for your agents, or click **"More Information"** to learn about what actions that connection supports before connecting. Use the search bar in the top right to quickly find specific connections. Available Connections **Microsoft 365** – Microsoft Outlook, Microsoft Excel, Microsoft Word, Microsoft Teams, Microsoft SharePoint, Microsoft OneDrive **Google Workspace** – Gmail, Google Calendar, Google Sheets, Google Docs, Google Drive **Duvo Business Connections** – Browser, Human in the Loop, Exa, Deep Research, Email Attachments Reader, Intelligent Document Reader, Web Scraper, Outbound Calls **Productivity** – Slack, Slack Workspace, Linear, Notion, Confluence **Data Warehouses** – Snowflake, Google BigQuery, Databricks ### My Connections This tab displays all the connections you've already connected. These are the services that are available for any agent within your team to use. Once a connection appears here, your agents can access it according to their AOP. My Connections ### Reviewing Connection Usage Each connection in **My Connections** shows how many agents currently use it, along with how many of those agents run on a schedule, a trigger, or a queue. Select the summary on a connection to open a panel listing every agent that uses it, whether each is directly connected to that account or simply uses the same service, and each agent's schedule, trigger, and queue details. This lets you gauge the impact before you disconnect. The disconnect confirmation also states how many agents will lose access, so you know exactly what a disconnect affects before it happens. ## Multiple Accounts per Connection You can connect more than one account for the same service. For example, if you manage two Gmail inboxes or need to access multiple Slack workspaces, you can add each account as a separate connection. Each connected account appears as its own entry and can be individually assigned to different agents. When building an agent, you can pick which specific account it should use for each connection. This lets you build workflows that act on behalf of a particular account without mixing credentials across tasks. ## Automatic Connection Selection When an agent requires a connection and you have exactly one personal account connected for that service, Duvo automatically uses it — no manual selection needed. If you have multiple accounts for the same service, a picker appears so you can choose which one to use for the Run. # How to Add a Connection Source: https://docs.duvo.ai/user-guide/connections/how-to-add-connection Connect standard and custom connections to Duvo, and manage connection credentials. ## Standard Connections The **Available Connections** tab displays the standard connections supported by Duvo. Each connection card provides details on the connection's capabilities. Click "Connect" on the desired connection. Click Connect on the connection card Complete the authentication steps for the application you're connecting to. The connection will appear in the "My Connections" tab making its tools available to your agents. ## Custom Connections These can be connected to Duvo in the "Available Connections" tab: Click "+ Add Custom MCP" button. Add Custom MCP **Name**: Choose a descriptive name that identifies what system the connection is supporting. **MCP URL**: Enter the web address where your MCP server is hosted (e.g., `https://mcp.yourcompany.com/mcp`). **Authorization**: Choose how Duvo should authenticate: * None: No authentication required * API Key: Provide an API key for authentication * OAuth: Use OAuth flow for authentication. Duvo automatically detects whether the MCP server supports **dynamic client registration (DCR)**. If it does, no Client ID or Secret is needed — the connection is handled automatically. If the server does not support DCR, or if you prefer to use your own pre-registered OAuth app, you can provide a Client ID and Client Secret in the **Advanced settings** section. Click "Save". Once configured, the custom connection will appear in your "My Connections" tab, making its tools available to your agents. ## Editing Connection Credentials To update a connection's credentials, open the connection from your "My Connections" tab and click **Edit**. Sensitive fields such as API keys, passwords, and service account credentials are write-only. When you open an existing connection to edit it, these fields will appear empty — the stored credentials are not displayed for security reasons. Leave a field empty to keep the existing value, or enter a new value to replace it. # Choosing the Right Connection Pattern Source: https://docs.duvo.ai/user-guide/connections/integration-patterns A decision tree and trade-offs comparison of the five ways to connect Duvo to an external system, plus how to combine them. When you need Duvo to interact with an external system, there are five distinct ways to connect. Picking the right one upfront saves significant setup time and avoids reliability problems down the line. This page walks through each pattern, a decision tree to choose between them, their trade-offs, and how to combine them. ## The Five Connection Patterns Pre-built, OAuth-authenticated connections maintained by Duvo. Examples: Gmail, Google Sheets, Slack, HubSpot, Salesforce, Snowflake, Microsoft 365. * No server to deploy or maintain. * Authentication is handled through a standard OAuth or credential flow in the Connections page. * Duvo keeps the connection current as APIs change. * Best for services that have a stable, public API and are already in Duvo's catalog. Duvo controls a real browser to interact with a web application, using credentials stored via [Logins and Secrets](/user-guide/resources/my-logins). Examples: legacy portals, internal dashboards, procurement systems that don't expose APIs. * No API needed on the target system. * Works with any website a human can navigate. * Slower and less reliable than an API at high volumes. * Subject to breaking when the target site changes its UI. * Best for low-to-medium volume workflows against web UIs that lack APIs. You deploy and maintain your own MCP server that exposes the tools your agent needs, then register it in Duvo. See [Custom MCP](/user-guide/connections/available-connections/custom-mcp) and [Building Custom Connections](/user-guide/connections/building-custom-connections). * Full control over what tools are exposed and how they authenticate. * Works with internal APIs, proprietary systems, and anything reachable over HTTPS. * Requires technical expertise to build, deploy, and maintain. * Best when you control the target system's API and need custom logic or access patterns not available in hosted connections. Duvo controls a Windows desktop environment — either a Duvo-managed cloud sandbox or your own Windows machine via RDP. See [Computer Use](/user-guide/connections/computer-use-overview). * Automates any Windows application regardless of whether it has an API or a web UI. * Works with installed desktop software, SAP GUI, Citrix, and Windows-only ERPs. * Slowest pattern; screen-reading adds latency. * Best for desktop applications that cannot be reached any other way. Receive structured input from external systems through email attachments, file drops, webhooks, or Duvo's Intelligent Document Reader. Examples: invoices arriving by email, reports uploaded to a shared folder, form submissions. * Passive intake — the external system pushes data to Duvo rather than Duvo polling. * Often paired with another pattern to take action after the intake step. * Best for document-heavy or event-driven workflows where a human or system sends Duvo something to process. ## Decision Tree Answer these questions in order. Stop at the first match. ```mermaid theme={"dark"} flowchart TD Q1{Is the system already in
Duvo's connections catalog?} Q1 -->|Yes| P1[Pattern 1
Hosted Connection] Q1 -->|No| Q2 Q2{Does the workflow start when
someone sends Duvo a file,
email, or document?} Q2 -->|Yes| P5[Pattern 5
Event and File Intake
then chain to Pattern 1 or 3] Q2 -->|No| Q3 Q3{Is the target system a
Windows desktop application
no web UI, no API?} Q3 -->|Yes| P4[Pattern 4
Computer Use /
Windows Remote Desktop] Q3 -->|No| Q4 Q4{Do you control the target
system's API and have technical
resources to build a server?} Q4 -->|Yes| P3[Pattern 3
Custom MCP] Q4 -->|No| Q5 Q5{Does the target system have a
web UI that a human can log into?} Q5 -->|Yes| P2[Pattern 2
Browser Automation] Q5 -->|No| SUP[Contact Duvo support about
adding a new hosted connection] ``` **1. Is the system already in Duvo's connections catalog?** * Yes → Use **Pattern 1 (Hosted Connection)**. Connect it from the [Connections page](https://app.duvo.ai/integrations) and move on. **2. Does the workflow start when someone sends Duvo a file, email, or document?** * Yes → Start with **Pattern 5 (Event and File Intake)**, then chain to Pattern 1 or 3 for downstream actions. **3. Is the target system a Windows desktop application (no web UI, no API)?** * Yes → Use **Pattern 4 (Computer Use / Windows Remote Desktop)**. * Need access to your own installed software or internal network? Use **Windows Remote Desktop**. * Need a clean sandbox without your own infrastructure? Use **Computer Use**. **4. Do you control the target system's API and have technical resources to build a server?** * Yes → Use **Pattern 3 (Custom MCP)**. You get the most reliability, the most control, and the cleanest tool interface for your agents. **5. Does the target system have a web UI that a human can log into?** * Yes → Use **Pattern 2 (Browser Automation)**. Store credentials as a Login in Duvo and point the agent at the site. **6. None of the above fit?** * Contact Duvo support to discuss whether a new hosted connection can be added to the catalog. ## Trade-offs at a Glance | | Hosted Connection | Browser Automation | Custom MCP | Computer Use / RDP | Event & File Intake | | ---------------------------- | ------------------- | ------------------- | ------------------ | ------------------ | ------------------- | | **Reliability** | High | Medium | High | Medium | High | | **Latency** | Low | Medium | Low | High | Low | | **Setup effort** | Minimal | Low | High | Low–Medium | Low | | **Maintenance burden** | None | Medium (UI changes) | High (your server) | Low | None | | **Auth complexity** | Low (OAuth managed) | Low (stored login) | Medium–High | Low (RDP creds) | None | | **Auditability** | Full | Full | Full | Full | Full | | **Suitable for high volume** | Yes | No | Yes | No | Yes | | **Requires API** | Yes | No | Yes | No | No | ## When to Combine Patterns Most real-world workflows use more than one pattern. The common combinations: An order form or legacy portal doesn't have an export API, so the agent reads it via browser automation (Pattern 2). It then writes the extracted data to a CRM using a hosted connection (Pattern 1). This is common in procurement and logistics workflows. A supplier emails an invoice as a PDF attachment. The agent receives it via Email Attachments Reader or Intelligent Document Reader (Pattern 5), extracts line items, then posts the result to NetSuite or SAP using a custom MCP server (Pattern 3). A Windows ERP like SAP GUI holds operational data with no API surface. The agent logs in via Windows Remote Desktop (Pattern 4), extracts the data, and writes a formatted report to Google Sheets using a hosted connection (Pattern 1). This is the standard pattern for SAP reporting workflows. Inbound customer requests arrive by email. The agent reads the email via Gmail (Pattern 1 — hosted), classifies the request, updates the relevant record in Salesforce or HubSpot (also Pattern 1), and sends a reply. No additional patterns needed because everything is in the catalog. An internal system exposes a partial API. The agent reads structured records from it via custom MCP (Pattern 3) and then uses browser automation (Pattern 2) to submit those records into a legacy web portal that accepts no API calls. ## Related Pages How connections work in Duvo Step-by-step for hosted connections How to build and deploy your own MCP server Connecting a custom MCP server to Duvo Desktop automation options Storing credentials for browser automation Processing files from email Extracting structured data from documents # Slack bot identity Source: https://docs.duvo.ai/user-guide/connections/slack-bot-identity Choose whether Duvo acts as itself or as you in Slack — and when each option matters. When an agent sends a Slack message, the message can appear in two ways: * **As Duvo** — a bot message from the Duvo app, clearly labelled with a "APP" badge. * **As you** — a message posted on behalf of your authenticated Slack account, indistinguishable from something you typed yourself. Which one you get depends on how you configure the agent's Slack steps. This guide explains the difference, when to use each, and how to set it up. ## How it works Connecting Slack installs two tokens at once: | Token type | Visible as | Scope of access | | ---------------------- | --------------------------- | ------------------------------------------ | | **Bot token** (xoxb-) | "Duvo" app with APP badge | Channels and DMs the bot has been added to | | **User token** (xoxp-) | Your personal Slack account | Every channel and DM you can access | Both tokens are stored securely when you connect Slack via **Connections**. Duvo selects the right token per action based on your configuration. The bot token is workspace-wide. Every member of your Duvo team that connects to the same Slack workspace shares one bot identity. User tokens are personal — each Duvo user who connects gets their own xoxp- token. ## Connect Slack If you haven't connected Slack yet, open **Connections** in the Duvo dashboard and click **Add connection → Slack**. Complete the OAuth flow — Slack authorises both the bot and your personal account in one step. You can connect multiple Slack workspaces by repeating the flow. ## Default behaviour: Duvo posts as the bot Read operations (listing channels, fetching messages, searching) always use your user token — the bot can only see channels it has been added to, whereas your user account has full visibility. Write operations (sending messages, reacting, uploading files) default to the **bot token**, so posts appear as Duvo: ``` Duvo APP 10:42 AM Your invoice report is ready. 3 new invoices require approval. ``` This is the right default for most automations — it makes automated messages easy to distinguish from human conversation. ## Post as yourself instead Set `as_user: true` on any write step in the agent prompt or tool configuration: ``` Send a Slack message to @emma in #account-ops: message: "The Q2 close checklist is done." as_user: true ``` With `as_user: true`, the message appears under your name and avatar, with no APP badge. Use this when: * You want a DM to feel like a personal follow-up. * A downstream recipient only trusts messages from a known person, not a bot. * Your Slack admin has restricted bot posting in certain channels. Messages sent `as_user` are indistinguishable from messages you typed manually. Make sure your team understands that some messages may be AI-generated if you use this mode broadly. ## Private channels and DMs The bot token only works in channels it has been explicitly added to. If an agent needs to post to a private channel: In Slack, open the private channel and run `/invite @Duvo`. This adds the bot as a member so its token can read and post there. In the Duvo dashboard, open the agent and confirm the Slack connection selected for that step is the one whose bot was just invited. For DMs, no invitation is needed — the bot can open direct messages with any workspace member once the app is installed. If you prefer the DM to appear from you personally, use `as_user: true` as described above. ## Triggering agents from Slack Agents can be started when a message is posted to a specific Slack channel. To set this up, go to the agent's **Triggers** tab and add a **Slack channel message** trigger. Because the trigger listener uses the bot token, the bot must be a member of the channel you select. Private channels require the `/invite @Duvo` step above before the trigger will fire. You can further narrow which messages fire the trigger: | Match rule | When it fires | | -------------------- | ------------------------------------------------------- | | **All messages** | Every message in the channel | | **Contains keyword** | Only messages that include one of the specified phrases | ## Multiple Slack workspaces If your agent needs to post to two different Slack workspaces, add a separate Slack connection for each workspace and reference the correct connection in each step of your agent prompt. Duvo resolves the token per connection, not per workspace automatically. ## Troubleshooting The bot has not been invited to the channel. Run `/invite @Duvo` in Slack. Check whether `as_user` is set for that step. If `as_user: true`, messages post as the user whose token was used at connect time. Re-connect Slack under a different user account to change this. You may have authorised user scopes only. Disconnect the connection and reconnect — make sure to click **Allow** on the Slack app installation screen (which grants bot scopes) as well as the personal authorisation prompt. The bot requires the `channels:join` or `chat:write.public` scope for public channels and an explicit invite for private ones. Both scopes are included in the default Slack connection. If you installed a custom Slack app, verify both scopes are present in your app's OAuth & Permissions settings. # Calendar Summary Source: https://docs.duvo.ai/user-guide/examples/calendar-summary Build a Duvo agent that summarizes your upcoming week from Google Calendar and emails you a formatted report. **Time to complete:** 10 minutes **Difficulty:** Beginner **Prerequisites:** Google Calendar connection, Gmail connection **You'll build:** An agent that summarizes your upcoming week and sends you a report ### Why Automate This? **The Problem**: Monday mornings start with scrambling through your calendar, trying to remember what's coming up this week. Important meetings get forgotten. Prep time gets missed. And you never have a clear view of your week until you've spent 15 minutes clicking through each day. **The Solution**: A Duvo agent that analyzes your calendar, identifies important meetings, and sends you a nicely formatted weekly summary—delivered to your inbox before your week begins. **Expected Results**: * Start each week fully prepared * Never miss an important meeting * Identify schedule conflicts in advance * Know which meetings need prep time * Save 15+ minutes of calendar review each week *** ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Pulls all events from your calendar for the upcoming week 2. Identifies high-priority meetings 3. Highlights meetings with important contacts 4. Creates a formatted summary with key details 5. Sends the report to your email *** ### Before You Start Make sure you have these ready: **Google Calendar connection** - Connect your calendar. [Connect connection](/user-guide/connections/how-to-add-connection) **Gmail connection** - For sending the summary report. [Connect connection](/user-guide/connections/how-to-add-connection) *** 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder: ``` Summarize calendar events for the upcoming week and send a report via email. Highlight important meetings. Steps: 1. Get all events from my Google Calendar for the next 7 days 2. For each event, extract: - Event title - Date and time - Duration - Location or video call link - Attendees - Description/agenda 3. Categorize events as: - High Priority: meetings with executives, clients, or 5+ attendees - Prep Needed: interviews, presentations, or events with "review" in title - Recurring: 1:1s, standups, team meetings - Other: everything else 4. Create a summary report with: - Total number of meetings this week - Total hours in meetings - Day-by-day breakdown - High priority meetings highlighted at the top - Meetings that need prep time flagged - Any scheduling conflicts noted 5. Send the report to my email with subject "Your Week Ahead - [Date Range]" ``` Click **"Generate"** to create the agent AOP. Review to ensure: * Your calendar is correctly identified * Priority criteria match your preferences * Report format meets your needs Click **"Connections"** and connect: 1. **Google Calendar** - To read your events 2. **Gmail** - To send the summary report 1. Click **"Run Agent"** 2. Review the generated summary 3. Check your email for the report Agent Running **What to check**: * Did it capture all your meetings? * Are high-priority meetings correctly identified? * Is the formatting easy to read? * Did the email arrive? Set up automatic Sunday evening delivery: 1. Go to **Agent Settings** > **Schedule** 2. Select **Weekly** on **Sunday** at **6:00 PM** 3. Save settings Your weekly summary will be waiting in your inbox every Monday morning. *** ### Expected Results When your agent runs successfully, you should see: **In your inbox**: * Formatted weekly summary email * High-priority meetings at the top * Day-by-day breakdown * Meeting stats (total meetings, hours) * Links to video calls **Example report format**: ``` YOUR WEEK AHEAD: Nov 18-22 Overview: 23 meetings | 18.5 hours HIGH PRIORITY - Mon 10am: Q4 Board Review (3hr) - Prep needed - Wed 2pm: Client Demo - Acme Corp (1hr) - Fri 11am: Executive Sync (1hr) MONDAY (6 meetings, 4.5 hrs) - 9:00 AM: Team Standup (30min) - 10:00 AM: Q4 Board Review (3hr) ... ``` **In Duvo**: * Execution log showing events processed * Any conflicts or issues flagged *** ### Troubleshooting * **Re-authorize**: Google permissions may have expired * **Correct calendar**: Ensure agent is reading the right calendar (work vs personal) * **Calendar visibility**: Check that calendar isn't set to private * **All-day events**: May need separate handling in AOP * **Recurring events**: Verify recurring events are being expanded * **Time zone**: Ensure calendar and agent use same timezone * **Refine criteria**: Adjust what constitutes "high priority" in AOP * **Add VIP list**: Create a list of important contacts in Files * **Keywords**: Add more keywords that indicate important meetings * **Gmail connection**: Re-authorize if needed * **Spam folder**: Check if summary went to spam * **Send permission**: Verify agent has permission to send email * **HTML rendering**: Some email clients display differently * **Long events**: May need truncation for readability * **Links**: Ensure video call links are clickable *** ### Take It Further Once your basic agent is working, consider these enhancements: ``` I have important contacts I always want highlighted: - Sarah Chen (CEO) - Mike Rodriguez (key client) - Jennifer Park (board member) Any meeting with these people should be marked as High Priority regardless of other criteria. ``` ``` For meetings marked as "Prep Needed": - List the event 2 days before - Identify what materials might be needed - Suggest blocking 30 min prep time before Include a "This Week's Prep List" section in the report. ``` ``` For in-person meetings: - Look up the location - Estimate travel time from my office - Flag if back-to-back meetings have location conflicts - Suggest departure time ``` ``` Include events from both my work calendar and personal calendar. Mark personal events in a separate section. Flag any conflicts between work and personal events. ``` ``` For each meeting, also include: - Last time I met with these attendees - Summary of previous meeting notes (if in email) - Any relevant emails from attendees in past week ``` Personalize your summary. [Learn about Agent Memory](/user-guide/assignment-features/assignment-memory) * *"Always highlight meetings with anyone from the sales team. I consider any meeting over 1 hour as potentially prep-needed. Send my summary at 5 PM Sunday Pacific time."* *** ### Related Resources Customize priority criteria and VIP lists Teach the agent which meetings are important to you Connect Google Calendar and Gmail Upload VIP contact lists # Customer Response Emails Source: https://docs.duvo.ai/user-guide/examples/customer-response-emails Build a Duvo agent that drafts and sends professional customer emails with a consistent brand voice. **Time to complete:** 15 minutes **Difficulty:** Beginner **Prerequisites:** Email connection, CRM access (optional) **You'll build:** An agent that drafts and sends professional customer emails with consistent tone *** ### Why Automate This? **The Problem**: Customer support teams spend hours crafting individual email responses. Response quality varies by team member. Customers wait too long for answers. Important context from previous interactions gets missed. And maintaining a consistent brand voice across dozens of daily emails is nearly impossible. **The Solution**: A Duvo agent that monitors incoming customer emails, gathers relevant context from your CRM and files, and drafts professional responses that maintain your brand voice—ready to send or review before sending. **Expected Results**: * Reduce average response time from 4 hours to under 30 minutes * Ensure 100% consistent brand voice and formatting * Automatically include relevant context from customer history * Free up 3-4 hours per support person per day * Improve customer satisfaction scores *** ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Monitors your inbox for new customer inquiries 2. Categorizes emails by type (support, sales, billing, etc.) 3. Pulls customer history and context from your CRM 4. Drafts professional responses using your brand voice 5. Sends automatically or queues for your review 6. Logs all interactions back to your CRM *** ### Before You Start Make sure you have these ready: **Email connection** - Connect Gmail or Outlook. [Add a connection](/user-guide/connections/how-to-add-connection) **CRM access** (recommended) - For customer context and history. [Set up logins](/user-guide/resources/my-logins) **Email templates** (optional) - Upload to Files for consistent formatting **FAQ/Documentation** (optional) - For the agent to reference when answering questions *** 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder: ``` Monitor the support@company.com inbox for new customer emails. For each new email: 1. Extract customer name, email address, company name, and message content 2. Look up the customer in our CRM to get account history and previous interactions 3. Categorize the inquiry as: Support request, Sales inquiry, Billing question, General feedback, or Complaint For Support requests and General feedback: - Draft a helpful response using information from our files - Use a professional but friendly tone - Include relevant documentation links - Send automatically For Sales inquiries: - Draft a response and forward to sales team - Include customer's account details and history For Billing questions: - Draft a response with account status - If it involves refunds or credits over $100, queue for my review before sending For Complaints: - Draft an empathetic response acknowledging their concern - Always queue for my review before sending - Flag as high priority in CRM After sending any email: - Log the interaction in CRM with summary and resolution - Set follow-up reminder if no response in 48 hours ``` Click **"Generate"** to create the agent AOP. Review the generated AOP to ensure: * Email categorization logic matches your needs * Approval rules align with your policies * Tone and style guidelines are captured Upload resources the agent should reference: 1. Go to **Agent Settings** > **Files** 2. Upload your FAQ documents, product guides, and email templates 3. These will be used to craft accurate, helpful responses **Recommended uploads**: * Product FAQ document * Troubleshooting guides * Email signature template * Refund/return policy * Brand voice guidelines Click **"Connections"** and connect: 1. **Email** - Connect the inbox to monitor (Gmail or Outlook) 2. **CRM** - Connect Salesforce, HubSpot, or your CRM system 3. **Slack** (optional) - For notifications when emails need review Configure which emails need your review before sending: 1. Go to **Agent Settings** > **Approvals** 2. Enable **"Review before sending"** for: * Complaints * Billing issues over \$100 * Any email you want to personally review Send test emails to verify each category works: 1. Send a support question from a test account 2. Send a billing inquiry 3. Send a complaint 4. Verify responses are appropriate and routed correctly Agent Running **What to check**: * Is the tone professional and friendly? * Did it pull correct customer context from CRM? * Did complaints get queued for review? * Were interactions logged to CRM? Set the agent to monitor emails continuously: 1. Go to **Agent Settings** > **Schedule** 2. Select **"Continuous"** for real-time responses 3. Save settings Your agent will now automatically respond to customer emails as they arrive. *** ### Expected Results When your agent runs successfully, you should see: **In customer inboxes**: * Fast, professional responses (under 30 minutes) * Consistent formatting and brand voice * Relevant links to documentation * Personalized with their account details **In your inbox**: * Complaints and sensitive issues queued for review * Draft emails ready for your approval * Significant time savings on routine responses **In your CRM**: * All interactions logged automatically * Follow-up reminders set * Complete customer communication history **In Duvo**: * Categorization accuracy metrics * Response time tracking * Review queue for pending approvals *** ### Troubleshooting * **Inbox connection**: Re-authorize email connection * **Folder monitoring**: Ensure agent is watching the correct folder (Inbox, not a subfolder) * **Filters**: Check if emails are being auto-filtered before agent sees them * **Refine AOP**: Add more specific keywords for each category * **Add examples**: Include sample emails for each type in your AOP * **Use Learning**: Mark correct categorizations to improve over time * **Email matching**: CRM may have different email than the one they're writing from * **Company domain**: Try matching by company domain instead of exact email * **Create new contact**: Add instruction to create CRM contact if not found * **Upload guidelines**: Add brand voice document to Files * **Provide examples**: Include sample responses showing desired tone * **Refine AOP**: Be more specific about tone (e.g., "friendly but professional, never use slang") * **CRM fields**: Ensure agent has access to relevant CRM fields * **Files**: Upload more comprehensive documentation * **Previous emails**: Enable access to email thread history *** ### Take It Further Once your basic agent is working, consider these enhancements: **Add sentiment analysis** ``` Analyze the customer's email sentiment (positive, neutral, negative, angry). If sentiment is "angry", immediately escalate to senior support. Adjust response tone based on sentiment—more empathetic for negative, more enthusiastic for positive. ``` **Implement smart routing** ``` For technical issues, check if customer has premium support. If premium, route to senior technical team and CC their account manager. If standard, add to regular support queue. Include customer's subscription tier in all internal communications. ``` **Create auto-responses for common questions** ``` If the question matches one of our top 10 FAQs with 90%+ confidence: - Send the pre-approved response immediately - Log as "Auto-resolved" in CRM Otherwise, draft a custom response for review. ``` **Add multilingual support** ``` Detect the language of incoming emails. If not English, translate the email for my review. Draft response in the customer's language. Note the original language in CRM. ``` **Personalize with Agent Memory** Team members can customize their communication style. [Learn about Agent Memory](/user-guide/assignment-features/assignment-memory) * Account Manager: *"Always use a warm, conversational tone. Include my direct phone number in the signature. CC me on all customer correspondence."* * Technical Support: *"Keep responses concise and technical. Include links to our documentation. Don't CC me unless it's urgent."* *** ### Related Resources Configure review workflows for sensitive emails Personalize communication style per team member Upload FAQs and email templates Improve categorization accuracy over time # Expense Report Approval Source: https://docs.duvo.ai/user-guide/examples/expense-report-approval Build a Duvo agent that routes submitted expense reports to managers for approval every Monday. **Time to complete:** 15 minutes **Difficulty:** Beginner **Prerequisites:** Expense system access, Email connection **You'll build:** An agent that routes expense reports to managers every Monday ### Why Automate This? **The Problem**: Finance teams spend 5-10 hours weekly manually reviewing submitted expense reports, identifying the right approver, and sending email notifications. Reports sit in queues, approvals get delayed, and employees wait longer for reimbursements. **The Solution**: A Duvo agent that automatically processes submitted expense reports every Monday morning—extracting details, identifying the correct manager, and sending approval requests with all necessary information attached. **Expected Results**: * Reduce approval cycle from 3-5 days to same-day * Eliminate 5+ hours of manual routing per week * Zero missed or forgotten expense reports * Complete audit trail of all approvals ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Checks your expense system for submitted reports from the past week 2. Extracts employee details, amounts, and receipts 3. Looks up each employee's manager in your HR system 4. Sends a formatted approval email with the report attached 5. Updates the expense system status to "Pending Approval" ### Before You Start Make sure you have these ready: **Expense management system** - You'll need login credentials. [Set up logins](/user-guide/resources/my-logins) **Email connection** - Connect Gmail or Outlook. [Connect connection](/user-guide/connections/how-to-add-connection) **HR system access** (optional) - For automatic manager lookup. Otherwise, you can specify managers manually. 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder: ``` Every Monday morning, check our expense management system for expense reports submitted in the past 7 days that have status "Submitted". For each report: 1. Extract the employee name, email, report ID, total amount, submission date, and all line items with receipts 2. Look up the employee's direct manager in the HR system 3. Send an email to the manager with subject "Expense Report Approval Required - [Employee Name] - [Report ID]" 4. Include the report summary and total amount in the email body 5. Attach the expense report PDF 6. Update the report status to "Pending Manager Approval" If a manager can't be found, escalate to the department head. If the expense system is unavailable, retry after 30 minutes. ``` Click **"Generate"** to create the agent AOP. Duvo will generate structured AOP based on your description. Review it to ensure: * All systems are correctly identified (expense system, HR system, email) * The approval workflow matches your process * Error handling covers your edge cases You can edit the AOP directly if you need to adjust any details. The agent needs access to your systems. Click **"Connections"** and ensure: 1. **Expense system** - Add logins for your expense management platform 2. **Email** - Connect your Gmail or Outlook account 3. **HR system** (if using) - Add logins for manager lookup Before scheduling, run a test: 1. Click **"Run Agent"** 2. Watch the agent execute each step in real-time 3. Review the session log to verify correct behavior Agent Running **What to check**: * Did it find the correct expense reports? * Did it identify the right managers? * Did the email look correct? (Check your sent folder) * Did the status update in your expense system? Once testing is successful, set up the Monday schedule: 1. Go to **Agent Settings** > **Schedule** 2. Select **Weekly** on **Monday** at **8:00 AM** 3. Save the schedule Your agent will now automatically process expense reports every Monday morning. ### Expected Results When your agent runs successfully, you should see: **In your expense system**: * All "Submitted" reports now show "Pending Manager Approval" * Activity log shows the agent's actions **In manager inboxes**: * Formatted approval emails with report summaries * PDF attachments with full expense details * Clear approve/reject call-to-action **In Duvo**: * Complete session log showing each step * Audit trail of all emails sent and status updates ### Troubleshooting * **Check filters**: Verify the status filter matches your system (e.g., "Submitted" vs "Pending") * **Check date range**: Ensure the 7-day lookback is correct for your timezone * **Check permissions**: Confirm the logins have read access to all reports * **HR system connection**: Verify logins are correct and not expired * **Missing manager data**: Some employees may not have managers assigned—add a fallback in your AOP * **Field mapping**: Check that employee IDs match between systems * **Email connection**: Re-authorize if token expired * **Spam filters**: Check if emails are being blocked * **Rate limits**: If processing many reports, add delays between emails * **Write permissions**: Confirm logins can update report status * **Field name**: Verify the status field name matches your system exactly ### Take It Further Once your basic agent is working, consider these enhancements: ``` If total amount exceeds $5,000, also CC the finance director. If total amount exceeds $10,000, require VP approval. ``` ``` Before routing for approval, check that all line items over $25 have receipt images attached. If receipts are missing, return the report to the employee with a note. ``` ``` After sending the approval email, also post a summary to #finance-approvals in Slack. ``` ``` If the report is more than 5 days old, mark the email as high priority. ``` Different users can set their own thresholds. [Learn about Agent Memory](/user-guide/assignment-features/assignment-memory) * Finance Manager: *"Auto-approve reports under \$500 from employees in my department."* * Director: *"Auto-approve all reports under $2,000. Flag anything over $2,000 for my review."* ### Related Resources Add approval steps before emails are sent Personalize approval thresholds per user Upload your expense policy for the agent to reference Improve agent performance over time # Gmail Workflows Source: https://docs.duvo.ai/user-guide/examples/gmail-workflows Build Duvo agents that triage your Gmail inbox, draft replies, and extract structured data from incoming emails. **Time to complete:** 15–25 minutes **Difficulty:** Beginner to Intermediate **Prerequisites:** Gmail connection **You'll build:** Agents that triage inboxes, draft replies, and extract data from incoming emails *** ## Why Automate Gmail? **The Problem**: Most business inboxes are a source of constant interruption. Teams manually sort, classify, and respond to emails that follow predictable patterns—inbound leads, support requests, order confirmations, approval requests. This work is repetitive, error-prone, and steals time from higher-value tasks. **The Solution**: Duvo agents can monitor your Gmail inbox and take action the moment an email arrives—routing inquiries to the right people, drafting replies in your voice, extracting structured data, and logging everything to your existing systems. **What you can achieve**: * Triage incoming emails by category before you open your inbox * Draft replies to routine inquiries so you only need to review and send * Extract order numbers, lead details, or approval requests from email bodies automatically * Route likely escalations to the right person without manual handling * Keep a spreadsheet, CRM, or Slack channel updated with relevant emails *** ### Before You Start Make sure you have these ready: **Gmail connection** — Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account **Google Sheets connection** (optional) — for logging data to a spreadsheet **Google Drive connection** (optional) — for saving invoice attachments **Slack connection** (optional) — for escalation notifications **CRM connection** (optional) — HubSpot, Salesforce, or Pipedrive for lead logging *** ### Use Case 1: Inbox Triage **Outcome**: Your inbox arrives pre-sorted. High-priority emails are flagged and forwarded. Many routine requests can be handled automatically. You spend more time on what matters. This workflow classifies incoming emails, applies Gmail labels, and routes each category based on your AOP—reducing manual inbox triage. 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** ``` Monitor my Gmail inbox for new emails. For each incoming email, determine its category: - Support request: asking for help with a product or service - Lead inquiry: a potential customer asking about pricing or capabilities - Internal: from a colleague (same company domain as mine) - Newsletter or marketing: bulk email, promotional content, or newsletters - Invoice or receipt: a financial document or transaction record - Other: anything that does not fit the above Then take the appropriate action: For Support requests: - Apply the Gmail label "Support" - Forward to support@company.com with a summary: "New support request from [Name]: [one-line summary of their question]" For Lead inquiries: - Apply the Gmail label "Leads" - Log the sender's name, company, email address, and their question in the "Inbound Leads" Google Sheet - Save a draft reply: "Thanks for reaching out! I'll have someone get back to you within 1 business day." For Invoices and receipts: - Apply the Gmail label "Finance" - If there is a PDF attachment, save it to the "Invoices" folder in Google Drive For Newsletters and marketing: - Apply the Gmail label "Newsletters" - Archive the message For Internal and Other: - No action. Leave as-is. ``` To start a Run automatically when a new email arrives: 1. Open your agent settings 2. Go to **Triggers** 3. Select **Gmail** as the trigger source 4. Leave the "Emails from" field empty to match any sender, or enter a specific address to filter See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for full setup details. Under **Connections**, enable: * **Gmail** — required * **Google Sheets** — for logging lead inquiries * **Google Drive** — for saving invoice attachments #### Expected Results * Incoming emails are typically labeled and routed quickly * The "Inbound Leads" spreadsheet is updated automatically for each lead inquiry * Invoice PDFs are stored in Google Drive without manual downloads * Your inbox shows mostly emails that need your attention *** ### Use Case 2: Drafting Replies to Common Inquiries **Outcome**: You arrive at your inbox to find draft replies already written for routine emails. Drafts use your preferred tone and reference information from your files, then wait for your approval before sending. This workflow drafts replies for you but does not send anything until you review. You stay in control; the agent handles the writing. Go to **Agent Settings** > **Files** and upload: * Product or service FAQ * Pricing information * Any email templates or brand voice guidelines These give the agent accurate information to draw on when composing replies. ``` Monitor my Gmail inbox for new customer emails. For each email: 1. Check whether the question can be answered using the information in my uploaded Files. 2. If yes: - Draft a reply that addresses the customer by name, answers their specific question with accurate details, and uses a professional but friendly tone - Sign off with my name - Save as a Gmail draft — do NOT send 3. If the question requires account-specific information you don't have access to: - Draft a short reply: "Thanks for your message. I'm looking into this and will follow up within 2 business days." - Apply the Gmail label "Needs Follow-up" - Save as a Gmail draft — do NOT send 4. If the email is a complaint or expresses frustration: - Draft an empathetic acknowledgment that takes the concern seriously without making commitments - Apply the Gmail label "Escalate" - Send me a Slack message: "Complaint received from [sender name]: [one-line summary]" - Save as a Gmail draft — do NOT send ``` Under **Connections**, enable: * **Gmail** — required * **Slack** — for escalation notifications #### Expected Results * Routine inquiries typically have draft replies waiting in your Drafts shortly after arrival * Complaints are flagged in Slack and queued for your personal review * Emails requiring account context are acknowledged automatically so no customer is left waiting * You send or discard each draft — nothing goes out without your approval *** ### Use Case 3: Extracting Data from Inbound Emails **Outcome**: Order confirmations, inbound form submissions, and structured notifications can be logged to a spreadsheet as they arrive, with minimal manual entry. This is ideal for teams receiving order emails, lead notification emails from web forms, or any recurring email with a consistent structure. Find the sender address for the emails you want to process. For example: * Order confirmations from your e-commerce platform: `noreply@yourplatform.com` * Lead notifications from your website form tool: `notifications@typeform.com` * Booking confirmations: `confirm@calendly.com` Adapt the fields to match the data in your emails: ``` Monitor my inbox for new emails from noreply@yourplatform.com. For each email: 1. Extract the following fields from the email body: - Order number - Customer name - Customer email address - Order total - Items ordered (list each item and quantity on a separate line) - Delivery address - Order date 2. Append a new row to the "Order Tracker" Google Sheet with these fields in the matching columns. 3. If the order total is over $500, send me a Slack message: "Large order received: Order #[number] from [customer name] for $[amount]" ``` Under **Connections**, enable: * **Gmail** — required * **Google Sheets** — for the tracker spreadsheet * **Slack** — for high-value order alerts (optional) #### Expected Results * Inbound orders and form submissions are logged to a spreadsheet automatically * High-value events trigger a Slack notification * Your tracker stays current — no batch imports, no manual entry * You have an audit trail of received emails and the data extracted from them *** ### Tips for Better Results **Be specific about which emails to act on**: Filtering to a specific sender address ("emails from [orders@yourplatform.com](mailto:orders@yourplatform.com)") prevents false positives and makes your agent more reliable than filtering by keyword alone. **Start with drafts, not sends**: For any workflow that replies to customers, configure the AOP to save drafts rather than send immediately. Once you're confident in the output quality, you can switch to automatic sending for low-risk categories. **Upload reference documents to Files**: Agents that draft replies produce better output when they have access to your product documentation, FAQ, pricing guide, and brand voice guidelines via [Files](/user-guide/assignment-features/files). **Use Human-in-the-Loop for sensitive replies**: For complaints, billing questions, or high-value customers, add an approval step so replies require your explicit sign-off before sending. See [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop). **Improve categorization over time**: If the agent misclassifies an email, use the [Learning Feature](/user-guide/assignment-features/learning-feature) to correct it. Each correction makes future categorization more accurate. *** ### Troubleshooting * Check that the Gmail trigger is active in **Agent Settings** > **Triggers** * Re-authorize the Gmail connection on the [Connections page](https://app.duvo.ai/integrations) if it shows as disconnected * Gmail triggers only monitor the inbox of the account you connected. Shared inboxes and delegated accounts are not currently supported as trigger sources * Edit your AOP to use "save as a Gmail draft" instead of "send" for the relevant categories * Or add a [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop) approval step before any send action * Add more specific criteria for each category in your AOP — for example, add the exact sender domain for internal emails * Include examples of emails that belong in each category directly in your AOP * Use the [Learning Feature](/user-guide/assignment-features/learning-feature) to mark incorrect categorizations and improve over time * Check whether the email format is consistent. If the sender uses different templates, add instructions to handle the variations * For HTML-heavy emails, extraction may miss values formatted as images or tables. Add a note in your AOP to extract from the plain-text version where possible * Check that the Google Drive connection is authorized on the Connections page * Make sure the folder name in your AOP exactly matches the folder name in Drive *** ### Related Resources Connect and authorize Gmail Start Runs automatically on new email Add approval steps before sending Upload reference documents Improve categorization over time Log extracted data to spreadsheets Draft and send professional replies # Google Sheets Workflows Source: https://docs.duvo.ai/user-guide/examples/google-sheets-workflows Build Duvo agents that log data to spreadsheets, act on lists as work queues, and enrich rows with external information. **Time to complete:** 15–25 minutes **Difficulty:** Beginner to Intermediate **Prerequisites:** Google Sheets connection **You'll build:** Agents that log data to spreadsheets, act on lists, and enrich rows with external information *** ## Why Automate With Google Sheets? **The Problem**: Spreadsheets sit at the center of most business workflows, but keeping them up to date is manual work. Teams copy data from emails, forms, and CRM systems into Sheets by hand. Lists in Sheets sit idle when they should be driving outreach or operations. Rows with incomplete data stay incomplete because enrichment requires too many lookups. **The Solution**: Duvo agents can read from and write to Google Sheets on your behalf — logging data as it arrives, executing operations against every row in a list, and filling in missing information from external sources. **What you can achieve**: * Keep a tracking spreadsheet current without manual data entry * Turn a spreadsheet list into a work queue your agent processes automatically * Enrich rows with data from external systems so your team works with complete records * Generate structured reports by pulling from multiple sources and writing results into a formatted sheet * Audit every action in a log spreadsheet for transparency and review *** ### Before You Start Make sure you have these ready: **Google Sheets connection** — Click **Enable** on the [Connections page](https://app.duvo.ai/integrations) and authorize with your Google account **Gmail or Outlook connection** (optional) — if your workflow involves incoming emails **Slack connection** (optional) — for notifications when rows are processed or anomalies are found **CRM connection** (optional) — HubSpot, Salesforce, or Pipedrive for enrichment and logging *** ### Use Case 1: Building a Live Data Tracker **Outcome**: A shared spreadsheet stays current automatically. When something happens — an email arrives, a form is submitted, a CRM record changes — a new row appears in your Sheet. No manual copying, no batch imports. This is the most common Google Sheets pattern in Duvo. Logging into Sheets from any trigger gives your team a single place to track what is happening across systems. Before building the agent, set up the spreadsheet you want to log into: 1. Create a new Google Sheet (or use an existing one) 2. Add column headers in row 1 matching the data you want to capture — for example: `Date`, `From`, `Company`, `Subject`, `Amount`, `Status` 3. Copy the spreadsheet URL — you will include it in your AOP 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** Adapt this example to your specific data source: ``` Monitor my Gmail inbox for new emails from orders@supplier.com. For each email that arrives: 1. Extract the following fields from the email body: - Date received - Sender name - Sender email address - Order number - Total amount - Delivery date requested 2. Append a new row to the "Order Log" Google Sheet at [paste your spreadsheet URL]. Write the values in this column order: Date, Sender Name, Sender Email, Order Number, Amount, Delivery Date, Status. Set the Status column to "Received". 3. If the total amount is over $10,000, send me a Slack message: "Large order received: Order #[number] from [sender] for $[amount]" ``` To log data automatically as emails arrive: 1. Open your agent settings 2. Go to **Triggers** 3. Select **Gmail** as the trigger source 4. Enter the sender address to filter (for example, `orders@supplier.com`) See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for full setup details. Under **Connections**, enable: * **Gmail** — required for the trigger * **Google Sheets** — for logging rows * **Slack** — for high-value alerts (optional) #### Expected Results * A new row appears in your spreadsheet each time a matching email arrives * High-value orders trigger an immediate Slack notification * The Status column is pre-filled, ready for your team to update as the order progresses * No manual copying required — the spreadsheet becomes a live record *** ### Use Case 2: Driving Bulk Actions from a Spreadsheet List **Outcome**: A list in your spreadsheet becomes a work queue. Your agent reads each row, takes the appropriate action (sending an email, updating a record, calling an API), and marks the row as processed. You handle exceptions; the routine work runs automatically. This pattern works for outreach lists, follow-up queues, batch record updates, and any situation where a spreadsheet drives operations. Set up a sheet with one row per item to process. Add a **Status** column so the agent can track progress: | Name | Email | Company | Message | Status | | --------- | ------------------------------------------- | ------- | --------------------- | ------- | | Alex Chen | [alex@example.com](mailto:alex@example.com) | Acme Co | Follow up on proposal | Pending | | Sara Lee | [sara@example.com](mailto:sara@example.com) | Buildco | Check invoice status | Pending | Leave the Status column as "Pending" for rows that need processing. 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** ``` Open the "Outreach Queue" Google Sheet at [paste your spreadsheet URL]. Find all rows where the Status column is "Pending". For each Pending row: 1. Read the Name, Email, Company, and Message columns. 2. Send a personalized email to the contact: - Subject: "Following up — [Company]" - Body: Address them by first name, acknowledge their company, and include the content from the Message column. Keep it brief and professional. 3. After sending, update the Status column for that row to "Sent" and write today's date in the "Date Sent" column. 4. If sending fails, set Status to "Failed" and note the reason in a "Notes" column. After processing all rows, send me a Slack summary: "Outreach complete: [X] emails sent, [Y] failed. Review the sheet at [URL] for details." ``` Under **Connections**, enable: * **Google Sheets** — for reading the queue and updating status * **Gmail or Outlook** — for sending emails * **Slack** — for the completion summary (optional) You can run this agent: * **On demand** — click **Start Work** when you want to process the queue * **On a schedule** — set it to run daily or weekly in **Agent Settings** > **Schedule** * **When the sheet changes** — use [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) if your trigger source can notify Duvo on update #### Expected Results * All "Pending" rows are processed in sequence * Each row is marked "Sent" or "Failed" immediately after the action is taken * You receive a Slack summary with the final counts * Rows that fail are clearly marked so you can investigate and retry * The sheet doubles as an audit trail — every action is timestamped *** ### Use Case 3: Enriching and Cleaning Spreadsheet Data **Outcome**: Rows with incomplete or raw data are updated in place with information pulled from external sources. What took hours of manual lookup — filling in company sizes, verifying addresses, resolving duplicate entries — runs automatically. This pattern works for lead enrichment, data validation, deduplication, and standardizing fields imported from other systems. Decide which columns are missing data or need cleanup. Common examples: * A list of email addresses that needs company name, industry, and headcount added * A list of addresses that needs to be standardized and geocoded * A product list that needs current pricing pulled from a supplier portal * A contact list with duplicate rows that need to be merged 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** Adapt this example to your enrichment task: ``` Open the "Leads" Google Sheet at [paste your spreadsheet URL]. Find all rows where the "Company Size" column is blank. For each row: 1. Read the "Company Domain" column. 2. Use the web browser to find the company's LinkedIn page or website. Look for: - Company size (number of employees) - Industry - Headquarters location 3. Write the values you find into the "Company Size", "Industry", and "HQ Location" columns for that row. 4. If you cannot find a value with confidence, write "Not found" rather than leaving the cell blank. After finishing, count how many rows were successfully enriched and how many returned "Not found". Send me a Slack message with the summary. ``` Under **Connections**, enable: * **Google Sheets** — for reading and updating rows * **Browser** — for looking up information on external sites * **Slack** — for the completion summary (optional) For enrichment from specific systems, also enable: * **HubSpot or Salesforce** — if enriching from your CRM * **Exa** — for company and contact research via AI-powered web search #### Expected Results * Blank fields are filled in automatically for each row * "Not found" is written where data genuinely does not exist, so gaps are visible rather than hidden * You receive a summary telling you how complete the enrichment was * The sheet is ready for segmentation, outreach, or import into another system *** ### Tips for Better Results **Reference the spreadsheet by URL, not by name**: When writing your AOP, paste the full Google Sheets URL rather than the spreadsheet name. This removes ambiguity if multiple sheets share a similar name and makes it easy to update the target later. **Use a Status column for any queue-based workflow**: Marking rows as "Pending", "In Progress", "Done", or "Failed" lets your agent resume safely if interrupted. It also gives your team an at-a-glance view of queue health. **Keep headers in row 1 and data starting in row 2**: Agents expect standard spreadsheet layout. If your sheet has merged headers, grouped columns, or data starting in a different row, include that detail in your AOP. **Process in batches for large sheets**: If you have thousands of rows, tell the agent to process a fixed number per Run (for example, "process the first 100 Pending rows"). This keeps each Run fast and lets you monitor quality as you go. **Convert .xlsx files before connecting**: If you uploaded an Excel file to Google Drive, convert it to a native Google Sheet first. Go to **File** > **Save as Google Sheets**. Some Google Sheets operations are not supported on imported `.xlsx` files — see the [Google Sheets connection page](/user-guide/connections/available-connections/google-sheets#troubleshooting) for details. **Add Human-in-the-Loop for sends and updates**: For any workflow that sends emails or modifies records in an external system, consider adding an approval step before the action is taken. See [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop). *** ### Troubleshooting * Confirm the Google Sheets connection is authorized on the [Connections page](https://app.duvo.ai/integrations) * Make sure the Google account you authorized has access to the spreadsheet * Paste the full spreadsheet URL directly into your AOP rather than using the file name * Add a deduplication check to your AOP: "Before appending, check whether a row with the same \[Order Number / Email / ID] already exists. If it does, skip it." * Add a unique identifier column (such as Order Number or Email) and use it as the key for deduplication * Check whether the column header in your AOP exactly matches the header in the sheet — spelling and capitalization must match * If the sheet has multiple tabs, specify the tab name in your AOP: "Update the Status column in the 'Queue' tab" * Review the column order in your AOP and compare it to the actual headers in your sheet * If columns have been added or reordered since the agent was built, update the AOP to reflect the current layout * Confirm the Status filter in your AOP exactly matches the value you set when marking rows done (for example, "Done" vs "Completed" — these are different) * If rows were marked manually and formatting differs (extra spaces, different capitalization), standardize the values in the sheet * Provide more specific instructions in your AOP about where to find information — for example, "Look for the employee count on the company's LinkedIn About page" * Upload a reference document via [Files](/user-guide/assignment-features/files) listing the sources your agent should prefer * Use the [Learning Feature](/user-guide/assignment-features/learning-feature) to correct outputs and improve accuracy over time *** ### Related Resources Connect and authorize Google Sheets Start Runs automatically on a trigger Add approval steps before sends and updates Upload reference documents Improve accuracy over time Triage inboxes and extract email data Generate structured reports automatically # Agent Tutorials Source: https://docs.duvo.ai/user-guide/examples/index Practical, real-world tutorials for building Duvo agents from start to finish. Learn how to build Duvo agents through practical, real-world examples. Each tutorial walks you through creating an agent from start to finish. ## Business Operations Automate routing of expense reports to managers for approval every Monday Auto-approve POs based on thresholds and route high-value orders for review Draft outbound messages and approve each one before it is sent — directly from Slack or Requests Research supplier products and collect them into a Shopify-compatible spreadsheet ## Customer Management Draft and send personalized customer emails with consistent tone and formatting Triage inboxes, draft replies to common inquiries, and extract data from incoming emails Log data to spreadsheets automatically, act on rows in a list, and enrich records with external information Trigger agents from any enabled Slack channel to run reports, route requests, and kick off workflows without leaving Slack ## Reporting & Analytics Query your data warehouse to deliver scheduled KPI reports, threshold alerts, and on-demand exports to Google Sheets Generate and distribute regional sales reports to leadership automatically Summarize upcoming calendar events and send a weekly report via email # Purchase Order Processing Source: https://docs.duvo.ai/user-guide/examples/purchase-order-processing Build a Duvo agent that auto-approves purchase orders by threshold and routes high-value orders for review. **Time to complete:** 20 minutes **Difficulty:** Intermediate **Prerequisites:** Procurement system access, Email or Slack connection **You'll build:** An agent that auto-approves POs based on thresholds and routes high-value orders for review ### Why Automate This? **The Problem**: Purchase order approvals create bottlenecks. Simple $500 orders wait in the same queue as $50,000 purchases. Managers waste time approving routine orders while critical purchases get delayed. Meanwhile, procurement teams manually check vendor status and budget availability for every single PO. **The Solution**: A Duvo agent that intelligently processes purchase orders based on configurable thresholds—auto-approving routine orders instantly while routing high-value purchases through appropriate approval chains. **Expected Results**: * Auto-approve 70-80% of routine POs instantly * Reduce approval cycle from 2-3 days to under 4 hours * Eliminate manual vendor validation checks * Ensure budget compliance before approval * Complete audit trail for compliance ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Monitors your procurement system for new purchase orders 2. Validates vendor status against your approved vendor list 3. Checks available budget before processing 4. Auto-approves orders under your threshold limits 5. Routes high-value orders to appropriate approvers 6. Sends confirmations and updates status automatically ### Before You Start Make sure you have these ready: **Procurement system** - You'll need logins with read/write access. [Set up logins](/user-guide/resources/my-logins) **Email or Slack connection** - For notifications and approvals. [Add a connection](/user-guide/connections/how-to-add-connection) **Budget system access** (optional) - For automatic budget validation **Approved vendor list** - Either in your procurement system or as a Files file 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder: ``` Monitor our procurement system for new purchase orders with status "Pending Approval". For each new PO: 1. Extract PO number, requestor name, vendor, total amount, line items, and department 2. Check if the vendor is on our approved vendor list 3. If vendor is not approved, flag for procurement team review and stop processing For approved vendors, apply these approval rules: - Orders under $1,000: Auto-approve immediately - Orders $1,000 - $5,000: Check if requestor has department manager approval, then process - Orders over $5,000: Route to finance director for review with budget impact analysis After approval: 1. Update PO status to "Approved" 2. Send confirmation email to requestor with expected delivery date 3. If amount exceeds $10,000, also notify the VP of Operations Error handling: - If vendor portal is unavailable, queue the order and retry in 1 hour - If budget is exceeded, notify finance team and hold the order - If no approval response in 48 hours, escalate to next level ``` Click **"Generate"** to create the agent AOP. Duvo will generate structured AOP. Review to ensure: * Threshold amounts match your organization's approval matrix * Escalation paths are correct for your org structure * All system names are correctly identified Edit the AOP directly to adjust any thresholds or routing rules. If your vendor list isn't in your procurement system, upload it to Files: 1. Go to **Agent Settings** > **Files** 2. Upload your approved vendor list (CSV, Excel, or PDF) 3. The agent will reference this when validating vendors Click **"Connections"** and connect: 1. **Procurement system** - Add logins for your PO platform 2. **Email** - For sending approvals and confirmations 3. **Slack** (optional) - For real-time notifications to approvers Run a test with sample purchase orders: 1. Click **"Run Agent"** 2. Process a few test POs at different amounts ($500, $3,000, \$8,000) 3. Verify each follows the correct approval path Agent Running **What to check**: * Did low-value orders auto-approve correctly? * Did high-value orders route to the right approver? * Did vendor validation work? * Did confirmations send to requestors? Set the agent to run continuously or on a schedule: 1. Go to **Agent Settings** > **Schedule** 2. Choose **"Continuous"** for real-time processing, or 3. Choose **"Every hour"** for batch processing 4. Save settings ### Expected Results When your agent runs successfully, you should see: **In your procurement system**: * Auto-approved POs show "Approved" status instantly * High-value POs show "Pending \[Approver Name] Approval" * Rejected vendors flagged for review **In approver inboxes**: * Clear approval requests with PO details * Budget impact information for large orders * One-click approve/reject options **In requestor inboxes**: * Instant confirmation for auto-approved orders * Status updates when approvals are pending * Expected delivery dates **In Duvo**: * Complete audit trail of all decisions * Approval chain documentation * Processing time metrics ### Troubleshooting * **Check status filter**: Verify "Pending Approval" matches your system's exact status name * **Check permissions**: Ensure logins can view all departments' POs * **Check polling interval**: If using scheduled runs, orders may be waiting for next cycle * **List format**: Ensure vendor names match exactly (watch for "Inc." vs "Inc" issues) * **List location**: Verify Files file is attached to this agent * **Update frequency**: Make sure your vendor list is current * **Threshold values**: Double-check dollar amounts in AOP * **Org structure**: Verify approver names/emails are correct * **Department mapping**: Ensure requestors are mapped to correct departments * **System connection**: Verify budget system logins * **Account codes**: Ensure PO account codes match budget categories * **Timing**: Budget data may be delayed—add buffer for recent transactions * **Email connection**: Re-authorize if needed * **Recipient addresses**: Verify approver emails are valid * **Spam filters**: Check if notifications are being blocked ### Take It Further Once your basic agent is working, consider these enhancements: ``` Before processing any PO, check the department's remaining budget. If the PO would exceed available budget by more than 10%, hold for finance review. Include budget utilization percentage in the approval request. ``` ``` If the PO is marked as "Rush" or "Urgent": - Skip the 48-hour escalation wait time - Send immediate Slack notification to approver - If no response in 4 hours, auto-escalate to next level ``` ``` Before auto-approving, check the vendor's performance score in our system. If score is below 3.5/5, flag for procurement review regardless of amount. Include vendor rating in all approval requests. ``` ``` At end of each week, generate a summary of: - Total POs processed - Auto-approved vs manually approved ratio - Average approval time - Top vendors by spend Send report to procurement manager. ``` Different users can set their own approval thresholds. [Learn about Agent Memory](/user-guide/assignment-features/assignment-memory) * Department Manager: *"Auto-approve all purchase orders under $5,000 from approved vendors. Flag anything over $5,000 for my review."* * Director: *"Auto-approve all purchase orders under $10,000. For orders between $10,000-$25,000, check if they're budgeted before requesting approval. Anything over $25,000 requires VP sign-off."* ### Related Resources Configure approval workflows for high-value orders Set personal approval thresholds per user Upload approved vendor lists and policies Securely store procurement system access # Reviewing Drafts Before Sending Source: https://docs.duvo.ai/user-guide/examples/reviewing-drafts-before-sending Build a Duvo agent that drafts outbound messages and waits for your approval before sending them. **Time to complete:** 15 minutes **Difficulty:** Beginner **Prerequisites:** Email or Slack connection **You'll build:** An agent that drafts outbound messages and waits for your approval before sending them ### Why Automate This? **The Problem**: Sending the wrong message to a customer or stakeholder is costly — once it's out, you cannot take it back. Teams either review every draft manually (slow) or skip the review entirely and accept the risk (dangerous). **The Solution**: A Duvo agent that drafts each message and pauses for your approval before sending. You see exactly what will go out, approve or revise it, and the agent handles delivery — all without switching between tools. **Expected Results**: * Every outbound message reviewed before it is sent * Approval decisions reachable from Slack or Requests — no need to open the message editor * Full audit trail of what was approved, denied, and revised ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Reads a list of customer cases or emails that need a response 2. Drafts a personalized reply for each one 3. Pauses and shows you the draft — recipient, subject, and full body 4. Sends the message only after you approve it 5. If you deny a draft, asks you what to change and regenerates before re-requesting approval ### Before You Start Make sure you have these ready: **Email connection** — Connect Gmail or Outlook. [Add a connection](/user-guide/connections/how-to-add-connection) **A source for your messages** — This could be a Gmail inbox, a support queue, a spreadsheet of contacts, or a Slack channel. Connect whichever system holds the inputs. 1. Click **"+ Create Agent"** from your dashboard. 2. Select **"Use Agent Builder"**. Create Agent Button Paste this prompt into the Agent Builder and adjust it to match your source system: ``` Check my Gmail inbox for emails labeled "needs-reply" that have not yet been answered. For each email: 1. Read the full message and any prior thread context. 2. Draft a professional reply that addresses the customer's question directly. Keep the tone friendly and concise. 3. Before sending, request approval with: - Title: "Send reply to [sender name] — [email subject]" - Description: include the full draft body so I can review it 4. If I approve, send the reply and remove the "needs-reply" label. 5. If I deny, ask me what to change. Revise the draft and request approval again. ``` Click **"Generate"** to create the agent AOP. Duvo will generate a structured AOP. Check that: * The source system is correctly identified (Gmail, in this case) * The approval title format includes enough detail to decide without opening a separate window * The revision loop is present — the agent should ask what to change when a draft is denied, not just stop Edit the AOP directly if anything needs adjusting. Click **"Connections"** and confirm: 1. **Gmail** (or your email provider) — Connect the account you want to send from. 2. **Human-in-the-Loop** — Already available automatically. No setup needed. Run the agent on a single test email before using it in production: 1. Click **"Start Work"**. 2. Watch the session log as the agent drafts the reply. 3. When the agent reaches the approval gate, a request will appear in your [Requests](/user-guide/assignment-features/requests). Agent Running **Try each path:** * **Approve the draft** — Verify the email is sent and the label is removed. * **Deny the draft** — Verify the agent asks you what to change, revises the draft, and requests approval again. If you have Slack notifications enabled, you can approve or deny drafts without opening Duvo: 1. Go to **Settings > Notifications** and connect your Slack account. 2. Run the agent again. 3. When the approval request is created, the Duvo bot sends you a direct message in Slack with the full draft. 4. Tap **Approve** or **Deny** directly in the Slack message. 5. The agent receives your response and continues — sending the email if approved, or asking for revision if denied. The Slack message updates to show the outcome after you respond, giving you a record of each decision. Once testing is successful, set the agent to run automatically: 1. Go to **Agent Settings > Schedule**. 2. Choose how often to check for new emails — every hour, or on a custom schedule. 3. Save the schedule. New drafts will appear in Requests (or via Slack) as they are generated, ready for your review. ### Expected Results When your agent runs successfully, you should see: **In your Requests:** * One pending approval for each draft, with the full message body visible in the detail panel * Requests resolve automatically once you approve or deny **In your email sent folder:** * Only messages you explicitly approved * Nothing sent that you did not review **In Duvo:** * A complete session log showing each draft, your decision, and the final action taken ### Troubleshooting * **Check the AOP instruction** — Make sure the description field in the approval request explicitly includes the draft body. Edit the AOP and add: "Include the complete email body in the approval description." * **Check character limits** — Very long drafts may be trimmed. Break long messages into shorter ones or include a summary in the description. * **Check the fallback instruction** — The AOP must tell the agent what to do when denied. Add: "If approval is denied, ask the user what to change, revise the draft, and request approval again." * **Check notification settings** — Go to **Settings > Notifications** and verify Slack is connected and notifications are enabled. * **Check the Duvo bot** — Make sure the Duvo app is authorized in your Slack workspace. * **Check the AOP** — The phrase "only send after I approve" (or equivalent) must appear before the send step. Without it, the agent may send immediately after drafting. ### Take It Further Once your basic approval workflow is running, consider these enhancements: ``` If the email is marked as urgent or the subject contains "URGENT", set the approval title to "[URGENT] Send reply to [sender] — [subject]" so I can prioritize it in my inbox. ``` ``` If the email is a standard acknowledgment with no specific questions (e.g., "Got it, thanks"), send the reply without requesting approval. Only request approval for substantive messages. ``` ``` In the approval description, briefly note why you drafted the reply this way and flag any part you are uncertain about. ``` The same pattern works for Slack messages, social media comments, or any other outbound communication. Replace the Gmail instructions with the appropriate connection and source. ### Related Resources Full guide to approval gates and how to write them into your AOP Where all pending approvals appear A tutorial for drafting and sending personalized responses at scale A tutorial showing threshold-based approval gates in a finance workflow # Shopify Product Feed Source: https://docs.duvo.ai/user-guide/examples/shopify-product-feed Build a Duvo agent that scrapes supplier product data and formats it into a Shopify-compatible import feed. **Time to complete:** 10 minutes **Difficulty:** Beginner **Prerequisites:** Google Sheets or Excel connection **You'll build:** An agent that scrapes product data and formats it for Shopify import *** ### Why Automate This? **The Problem**: E-commerce teams manually browse supplier websites, copy product details into spreadsheets, and reformat data for Shopify import. This process takes hours, is prone to errors, and needs to be repeated whenever suppliers update their catalog. Missing a new product or price change means lost sales. **The Solution**: A Duvo agent that automatically browses supplier websites, extracts product information, and formats it into a Shopify-compatible feed—ready to import or sync with your store. **Expected Results**: * Reduce catalog updates from hours to minutes * Eliminate manual copy-paste errors * Catch new products and price changes automatically * Maintain consistent data formatting for Shopify * Schedule regular updates to keep catalog current *** ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Navigates to a supplier website 2. Extracts product details (name, price, SKU, description, images) 3. Formats data into Shopify's required CSV structure 4. Outputs to Google Sheets or Excel for import *** ### Before You Start Make sure you have these ready: **Google Sheets or Excel connection** - For storing the formatted feed. [Add a connection](/user-guide/connections/how-to-add-connection) **Supplier website URL** - The website you want to scrape **Shopify import format** (optional) - Upload to Files for reference *** 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder (modify the URL for your supplier): ``` Research all available iPhone options on apple.com and collect them into a spreadsheet in a format I can import into Shopify. For each product found: 1. Extract the product name 2. Extract all available variants (storage size, color) 3. Extract the price for each variant 4. Extract the product description 5. Extract product image URLs 6. Generate a unique SKU based on product name and variant Format the data with these Shopify columns: - Handle (URL-friendly product name) - Title - Body (HTML description) - Vendor - Type - Tags - Published - Option1 Name, Option1 Value - Option2 Name, Option2 Value - Variant SKU - Variant Price - Image Src Save to a new Google Sheet called "Apple Products - Shopify Feed" with today's date. ``` Click **"Generate"** to create the agent AOP. Review to ensure: * The correct website URL is specified * All product fields you need are captured * Shopify column mapping is correct for your store Click **"Connections"** and connect: 1. **Google Sheets or Excel** - For outputting the formatted feed 1. Click **"Run Agent"** 2. Watch as the agent browses the supplier website 3. View the extracted products in real-time **What to watch for**: * Is the agent finding all products? * Are prices being extracted correctly? * Are images being captured? Once complete, check your Google Sheet: 1. Verify all products were captured 2. Check that formatting matches Shopify requirements 3. Validate prices and variants are correct Shopify Feed Example *** ### Expected Results When your agent runs successfully, you should see: **In Google Sheets/Excel**: * Complete product catalog with all variants * Properly formatted for Shopify import * Consistent SKU generation * All image URLs captured **Ready for Shopify**: * Download as CSV * Import directly into Shopify Admin * Or connect via API for automatic sync **In Duvo**: * Complete log of pages visited * Count of products extracted * Any errors or missing data flagged *** ### Troubleshooting * **Page structure**: Website may have changed—update your AOP * **Dynamic loading**: Some sites require scrolling to load products * **Login required**: Some supplier sites need authentication * **Currency symbols**: Ensure agent is extracting numeric values only * **Sale prices**: Specify whether to capture regular or sale price * **Regional pricing**: Check if site is showing correct region's prices * **Lazy loading**: Images may need page scroll to load * **Multiple images**: Specify if you want primary image only or all images * **Image size**: Request specific image sizes if available * **Special characters**: Product names may have characters that need escaping * **HTML in descriptions**: Ensure proper HTML formatting for Shopify * **Variant structure**: Verify Option1/Option2 mapping matches your store *** ### Take It Further Once your basic agent is working, consider these enhancements: ``` After collecting Apple products, also collect from: - Samsung (samsung.com/phones) - Google (store.google.com/phones) Combine all products into a single feed with Vendor field populated. ``` ``` Run every Sunday at midnight. Compare new prices to previous feed. Flag any products with price changes greater than 10%. Email me a summary of changes before publishing. ``` ``` Check if each product shows "In Stock" or "Out of Stock". Set Shopify inventory to 100 if in stock, 0 if out of stock. Mark out-of-stock products as unpublished. ``` ``` For each product, generate: - SEO-optimized title (include key features) - Meta description (150 characters) - URL-friendly handle - Relevant tags for filtering ``` ``` Also check competitor sites for the same products. Add a "Competitor Price" column. Flag any products where our price is higher. ``` *** ### Related Resources How Duvo navigates websites Upload Shopify format templates Connect spreadsheet apps Improve extraction accuracy over time # Slack Mention Workflows Source: https://docs.duvo.ai/user-guide/examples/slack-mention-workflows Trigger Duvo agents from any enabled Slack channel by mentioning the Duvo app, with live progress and results posted back in the thread. **Time to complete:** 20–30 minutes **Difficulty:** Beginner to Intermediate **Prerequisites:** Slack Workspace connection (team admin installs once) **You'll build:** Agents your team can trigger from any enabled Slack channel by mentioning the Duvo app ## Why Trigger Agents from Slack? **The Problem**: Most automation tools require team members to log into a separate interface, find the right agent, fill in a form, and wait for results elsewhere. When work starts in Slack — an inbound request, an incident in the #ops channel, a question in #finance — switching contexts adds friction and slows teams down. **The Solution**: Mention the Duvo app in any enabled Slack channel with a request and supporting context. Duvo starts a Run immediately, posts live progress in the thread, and delivers results without anyone leaving Slack. **What your team can achieve**: * Pull on-demand reports and data summaries from shared channels without logging into a separate tool * Route incoming Slack requests (IT help, HR questions, ops tasks) automatically so nothing falls through the cracks * Kick off full multi-step workflows by mentioning Duvo in the thread where the request already lives * Review drafts, get feedback, or approve actions — all from the same Slack thread * Let anyone on the team trigger automations they would otherwise need a specialist to run *** ## Before You Start Make sure these are in place before using Slack-triggered agents: **Slack Workspace connection installed** — A team admin must install the Duvo app once for your workspace from the [Connections page](https://app.duvo.ai/integrations). See [Slack Workspace](/user-guide/connections/available-connections/slack-workspace). **Slack account linked** — Each user goes to **Settings > Notifications** and links their personal Slack account so Duvo can reach them for Human-in-the-Loop requests. **Slack trigger enabled** — On each agent you want to trigger from Slack, open **Setup** and enable the Slack trigger. **Duvo invited to your channels** — Invite the Duvo app to any channel where you plan to use it (`/invite @Duvo`). In direct messages, the bot is available automatically. *** ## How It Works Once set up, triggering an agent is as simple as mentioning the Duvo app in a channel: ``` @Duvo pull this week's open support tickets from Zendesk and summarize them by priority ``` Duvo reads the full thread context — including any files, images, or messages from other Slack apps in the thread — and starts the Run. A live progress status appears in the thread and updates as the agent works — it is a single indicator that changes as steps complete, not a stream of new messages, so it does not clutter the thread. If the agent needs your input at any point — to approve an action, answer a question, or handle an exception — it pauses and sends an interactive request as a Slack DM to the relevant user. You can approve or respond directly in Slack without opening any other tool. When the Run is done, results are posted back to the same thread. **If you have more than one agent with Slack triggers enabled**, Duvo shows a selection menu when you mention `@Duvo` so you can pick which agent to run. If only one agent matches, it starts automatically. Channel message triggers work differently — they fire all matching agents simultaneously from the same message rather than showing a menu. See [Skip the mention with a channel message trigger](#tips-for-better-results) in Tips below. **Files and images attached to Slack messages are passed to the agent automatically**, so you can include a PDF, spreadsheet, or screenshot in your Slack message and the agent receives it as context. *** ## Use Case 1: On-Demand Reports from Shared Channels **Outcome**: Any team member can ask for a report or data lookup in a shared channel and get results posted back — without logging into another tool, waiting for a scheduled run, or asking an analyst. This is useful for reports that come up irregularly: "what's the status on these five accounts?", "how many orders are stuck in pending?", "can you pull the supplier lead times from our ERP?". 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. Write the AOP to expect a request as input and pull the right data based on what is asked: ``` You will receive a report request from a Slack message. Read the request carefully and identify what data is being asked for. Pull the relevant data from [your data source — e.g., Salesforce, Google Sheets, your ERP]. Return a clear, formatted summary in Slack. Use bullet points or a table for multi-row data. Include the date range or filter criteria you used so the reader can verify the results. If the request is ambiguous, ask a clarifying question before pulling data. ``` Adapt the data source to the system your team uses (Google Sheets, Salesforce, Snowflake, etc.). 1. Open your agent and go to **Setup**. 2. Enable the **Slack** trigger. 3. Save. Under **Connections**, enable the connection to your data source — for example: * **Google Sheets** — for spreadsheet-based data * **Salesforce** — for CRM records * **Snowflake** — for warehouse queries ### Expected Results * A team member mentions Duvo with a report request in any enabled channel * A live progress status appears in the thread and updates as the Run progresses, showing what the agent is currently doing * Results appear in the thread within a few minutes, formatted and ready to share *** ## Use Case 2: Request Intake and Routing in Shared Channels **Outcome**: Requests that arrive in shared Slack channels — IT help, HR questions, ops tasks, finance approvals — are read, categorized, and routed to the right person or queue automatically. Nothing falls through the cracks and the channel stays organized. This removes the need for a dedicated person to watch a shared channel and manually triage each message. 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. Adapt the categories and routing destinations to your team's workflow: ``` You will receive a request from a Slack message. The message may describe an IT issue, an HR question, an operations request, a finance approval, or something else. Classify the request into one of these categories: - IT: hardware, software, access, passwords, or system issues - HR: leave, onboarding, benefits, or policy questions - Finance: invoices, expenses, approvals, or payment queries - Ops: facilities, supplies, logistics, or vendor questions - Other: anything that does not fit the above Then take the following actions: For IT requests: - Post a reply in the thread: "Got it — I've logged this with the IT team. Ticket created." - Create a ticket in [your ticketing system] with the request title, description, and the Slack user's name. For HR requests: - Post a reply: "Logged this with HR. Someone will follow up within 1 business day." - Send a direct message to [HR contact's Slack handle] with the request details. For Finance requests: - Post a reply: "Sent this to Finance for review." - Send the request details to the #finance-requests channel. For Ops and Other: - Post a reply: "Logged this for the ops team." - Post the original message and sender in #ops-queue. ``` Enable the Slack trigger on this agent in **Setup**. Under **Connections**, enable: * **Slack** — required because this AOP sends direct messages and posts in channels other than the trigger thread (e.g., `#finance-requests`, `#ops-queue`). In-thread replies in the trigger thread are handled by the Slack Workspace connection automatically. * Any ticketing or operations system your AOP writes to (e.g., Jira, Linear, ServiceNow) ### Expected Results * Team members post requests in the shared channel and mention Duvo * Each request is acknowledged in the thread within seconds * Tickets are created and the right people are notified automatically * The requester sees confirmation in the thread without following up separately *** ## Use Case 3: Kicking Off Workflows from Existing Slack Conversations **Outcome**: When a conversation in Slack reaches a decision point — a refund to process, a record to update, a document to generate — one mention starts the full workflow without leaving the thread. The whole conversation history becomes context for the agent. This is ideal for operations, support, and account management teams who already coordinate in Slack and want to act on what they discuss without switching tools. 1. Click **+ Create Agent** from your dashboard. 2. Select **Use Agent Builder**. ``` You will receive context from a Slack thread. Read the full conversation to understand what has been discussed and what action has been agreed. Identify the action that needs to be taken. This may be stated explicitly ("please process the refund for order #12345") or implied by the conversation ("approved" after a refund request was posted). Carry out the action: - For refunds: locate the order in [your order system], apply the refund, and post a confirmation in the thread with the refund ID and amount. - For record updates: find the record in [your CRM/ERP], apply the change described in the thread, and confirm the update. - For document generation: generate the document based on the details in the thread, upload it to [Google Drive / SharePoint], and post the link in the thread. If the action is unclear or requires information not present in the thread, ask a clarifying question before proceeding. Before taking any irreversible action (deleting records, sending emails, processing payments), request approval via Human-in-the-Loop (sent as a DM to the relevant user). Include what you are about to do and ask for confirmation. ``` 1. Open your agent and go to **Setup**. 2. Enable the **Slack** trigger. 3. Save. Enable the connections to the systems your workflow touches — your order management system, CRM, Google Drive, etc. Posting confirmations to the trigger thread is handled automatically by the Slack Workspace connection. Human-in-the-Loop requests are delivered as Slack DMs to the relevant user. The personal Slack connection is only needed if your AOP also sends DMs or posts to other channels as agent steps. ### Expected Results * Team members discuss a request or decision in a Slack thread, then mention Duvo * Duvo reads the full thread and understands what action was agreed * The agent carries out the workflow and posts results in the thread * Approvals for sensitive actions appear as interactive buttons — respond directly in Slack *** ## Use Case 4: Sharing Files for Processing **Outcome**: Team members can drop a document, spreadsheet, or image into a Slack channel, mention Duvo, and have it processed immediately — extracted, validated, summarized, or loaded into a system. Any files attached to messages in the thread are automatically available to the agent. ### Example AOP for Document Processing ``` You will receive one or more files via a Slack message. Process each file as follows: For invoices (PDFs): - Extract the vendor name, invoice number, total amount, line items, and due date. - Log the extracted data as a new row in the "Invoices Pending" Google Sheet. - Post a summary in the Slack thread: "Invoice logged: [vendor], [amount], due [date]." - If any field is missing or unreadable, flag it in the thread. For spreadsheets: - Summarize the data: total rows, key columns, any obvious anomalies (blanks, outliers). - Post the summary in the thread. For images: - Describe what you see and, if it contains text, extract the text. - Post your description in the thread. ``` ### Expected Results * Drop a PDF invoice in the channel, mention Duvo, and it is logged to your spreadsheet within minutes * Attach a screenshot to ask Duvo to extract or describe the content * No manual downloading or re-uploading required — files from the Slack thread are passed to the agent directly *** ## Tips for Better Results **Write the AOP to handle "I'll know it when I see it" requests**: Slack requests are often phrased informally. Write your AOP to interpret the intent, not just exact phrasing. For example: "understand what the user is asking for and check the relevant data source" works better than "if the message contains the word 'report'…". **Keep one agent per topic**: A single all-purpose agent that tries to handle IT tickets, finance approvals, and report requests will produce inconsistent results. Create separate agents for distinct workflows and let the selection menu route the request to the right one. **Use Human-in-the-Loop for actions with consequences**: Add an approval step before the agent takes any irreversible action. Approvals appear as interactive buttons in a Slack DM to the relevant user — they can approve or deny without leaving Slack. See [Human-in-the-Loop](/user-guide/assignment-features/human-in-the-loop). **Start results with a one-line summary**: Instruct your AOP to lead the Slack response with a single sentence summary before the detail. Long output in a Slack thread is hard to scan. **Include thread context when you mention Duvo**: The more context the thread contains, the better the agent can respond. If you are kicking off a workflow, paste the relevant details into the thread before mentioning Duvo — or simply let the conversation build up naturally before triggering. **Skip the mention with a channel message trigger**: If you want an agent to start automatically on every message in a channel — or every message containing a specific keyword — you can set up a channel message trigger instead. The agent fires without anyone needing to tag the Duvo app, which is useful for monitoring channels like #alerts or #support-inbox where every message should be processed. In **Setup**, enable the **Channel Message** trigger, select the channel, and optionally specify keywords or patterns to filter which messages start the agent. Unlike mention triggers, if multiple agents have matching Channel Message triggers, they will all start simultaneously from the same message — no selection menu appears, so use specific keywords to avoid unintended overlaps. *** ## Troubleshooting * Confirm the Duvo app has been invited to the channel (`/invite @Duvo`) * Check that the agent has the Slack trigger enabled in **Setup** * Verify the Slack Workspace connection is active on the [Connections page](https://app.duvo.ai/integrations) * Verify all connections required by the agent are linked and authorized under **Connections** — a missing connection can stop the Run from starting * Ensure the agent has a published build — a draft-only agent cannot be triggered If Duvo acknowledges the mention but the Run fails or returns no results, see the **Run starts but fails or returns no results** entry below. This means more than one of your agents has Slack triggers enabled. Select the agent you want from the menu. To avoid the menu in the future, disable the Slack trigger on agents you do not intend to trigger from this channel. * Confirm the files are attached to messages in the same Slack thread where you mentioned Duvo * Files must be attached at the time of the mention, or in messages in the thread before the mention * Very large files may take longer to process * Slack has message length limits. Instruct your AOP to summarize results rather than dump raw data. For large outputs, write results to a Google Sheet or document and post the link in the thread instead. * Check that all connections the agent needs are enabled and authorized under **Connections** — for example, if the AOP reads from Salesforce or writes to Google Sheets, those connections must be linked * Re-authorize any connection that shows as disconnected on the [Connections page](https://app.duvo.ai/integrations) * Open the Run in Duvo to see the full error detail in the session log * Confirm your Slack account is linked in **Settings > Notifications** * Check that Slack notifications are enabled in your notification settings * Make sure the Duvo app is not muted in Slack *** ## Related Resources Install the Duvo app for your workspace Link a personal Slack account for DMs and cross-channel posts Add approval steps for sensitive actions Start agents from external events Trigger and run agents from email Keep a human in the loop on agent output # Snowflake Workflows Source: https://docs.duvo.ai/user-guide/examples/snowflake-workflows Build Duvo agents that query your Snowflake warehouse and turn the results into scheduled reports, threshold alerts, and spreadsheet exports. **Time to complete:** 20–35 minutes **Difficulty:** Intermediate **Prerequisites:** Snowflake connection (key-pair authentication), Optional: Slack, Gmail, Outlook, or Google Sheets **You'll build:** Agents that query your data warehouse and turn the results into reports, alerts, and actions ## Why Use Snowflake with Duvo? **The Problem**: Valuable business data sits in your data warehouse — inventory levels, revenue figures, pipeline metrics, exception counts. Getting it into the hands of decision-makers requires a data engineer, a BI dashboard, or a manual export. Ad-hoc questions take hours. Monitoring dashboards go unread. Alerts are configured once and forgotten. **The Solution**: Duvo agents can query Snowflake directly, interpret the results, and take action — sending a Slack message when a threshold is breached, writing a formatted report to Google Sheets, or summarizing warehouse trends in a Monday-morning email. No dashboards to maintain. No scheduled SQL scripts to babysit. **What you can achieve**: * Deliver scheduled KPI summaries before your team's Monday standup * Get a Slack alert the moment inventory falls below a reorder threshold * Pull a fresh data extract into Google Sheets for a stakeholder who needs it in minutes * Monitor for anomalies across large datasets and escalate exceptions automatically *** ### Before You Start Make sure you have these ready: **Snowflake connection** — follow the [Snowflake connection guide](/user-guide/connections/available-connections/snowflake) to configure key-pair authentication and add the connection on the [Connections page](https://app.duvo.ai/integrations) **Slack connection** (optional) — for threshold alerts and summaries. Click **Enable** on the Connections page and authorize with your Slack workspace **Gmail or Outlook connection** (optional) — for email distribution of reports **Google Sheets connection** (optional) — for writing query results to a spreadsheet *** ### Use Case 1: Scheduled KPI Report from Warehouse Data **Outcome**: Every Monday morning, a summary of last week's key metrics — revenue, volume, exceptions — lands in your team's Slack channel. No one has to log into Snowflake or build a query. This workflow queries Snowflake on a schedule, formats the results into a readable summary, and distributes it to the right people. 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** Adapt the table names, columns, and metric names to match your warehouse schema: ``` Every Monday at 7:00 AM, generate a weekly business metrics summary. Step 1: Query Snowflake for last week's metrics (Monday–Sunday). Run these queries and collect the results: - Total revenue: SELECT SUM(order_total) FROM orders WHERE order_date BETWEEN [last Monday] AND [last Sunday] AND status = 'completed' - Order count: SELECT COUNT(*) FROM orders WHERE order_date BETWEEN [last Monday] AND [last Sunday] - Average order value: calculate from the above - Exception count (failed or refunded orders): SELECT COUNT(*) FROM orders WHERE order_date BETWEEN [last Monday] AND [last Sunday] AND status IN ('failed', 'refunded') Step 2: Compare to the prior week by running the same queries for the previous Monday–Sunday period. Step 3: Calculate week-over-week change as a percentage for each metric. Step 4: Format a short summary message: "Weekly Metrics — [date range] - Revenue: $[value] ([+/-X%] vs prior week) - Orders: [count] ([+/-X%]) - Avg order value: $[value] ([+/-X%]) - Exceptions: [count] ([+/-X%]) [If exceptions increased more than 20%, add: 'WARNING: Exception rate up — check the Orders table for details.']" Step 5: Post the message to the #data-ops Slack channel. ``` Under **Connections**, enable: * **Snowflake** — required * **Slack** — for posting the summary (or substitute Gmail/Outlook for email delivery) 1. Go to **Agent Settings** > **Triggers** 2. Select **Schedule** 3. Set to **Weekly** on **Monday** at **7:00 AM** in your timezone #### Expected Results * A Slack summary appears in your channel before your Monday standup * Week-over-week comparisons show at a glance whether things are trending better or worse * Anomaly flags are surfaced automatically so the team knows when to dig deeper * No one needs to open Snowflake or write a query to get the numbers *** ### Use Case 2: Threshold Alert When a Metric Breaches a Limit **Outcome**: When inventory for a top SKU drops below the reorder point — or when a fraud rate, error count, or cost metric crosses a threshold — your team gets a Slack message immediately rather than discovering the problem hours later. This workflow polls Snowflake on a short schedule, checks against defined limits, and alerts only when action is needed. Before writing the AOP, decide: * **Which table and column** holds the metric you want to watch (e.g., `inventory.quantity_on_hand`) * **What value triggers an alert** (e.g., less than 100 units, more than 5% error rate) * **What context to include** in the alert (e.g., which SKU, which region, current value, historical average) ``` Every hour, check for inventory levels that require attention. Step 1: Run this query in Snowflake: SELECT sku, product_name, quantity_on_hand, reorder_point, warehouse_location FROM inventory.stock_levels WHERE quantity_on_hand < reorder_point ORDER BY quantity_on_hand ASC Step 2: If the query returns no rows, stop — no action needed. Step 3: If any rows are returned: - For each row, format a line: "• [product_name] (SKU [sku]) — [quantity_on_hand] units remaining at [warehouse_location] (reorder point: [reorder_point])" - Assemble a Slack message: "Inventory Alert — [count] SKUs below reorder point: [lines from above] Action: Check your replenishment queue or place restock orders." Step 4: Post the message to the #supply-chain Slack channel. Step 5: Do not send a duplicate alert if the same SKUs were already alerted in the last 4 hours. ``` Under **Connections**, enable: * **Snowflake** — required * **Slack** — for posting the alert 1. Go to **Agent Settings** > **Triggers** 2. Select **Schedule** 3. Set to **Every hour** (or every 15 minutes for time-critical metrics) #### Expected Results * Alerts fire only when a threshold is actually breached — no noise when things are fine * Each alert names the specific SKUs or records requiring attention * Your team can act immediately instead of learning about the problem in a weekly report * The deduplication instruction prevents the same alert from firing repeatedly before anyone has had a chance to act *** ### Use Case 3: Export Query Results to Google Sheets **Outcome**: A stakeholder needs a fresh data pull from the warehouse — customer list, transaction export, regional breakdown — and it needs to be in a spreadsheet they can filter and share. The agent runs the query and writes the results into a Google Sheet quickly. This is useful for ad-hoc exports, recurring data pulls that feed downstream tools, or replacing manual "download CSV, clean it up, paste into Sheets" workflows. 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** Adapt the query and sheet name to your use case: ``` When started, export a fresh customer account list from Snowflake to Google Sheets. Step 1: Run this query in Snowflake: SELECT account_id, account_name, industry, annual_revenue, country, account_owner, created_date, last_activity_date FROM crm.accounts WHERE status = 'active' ORDER BY annual_revenue DESC Step 2: Write the results to the "Customer Accounts" Google Sheet: - Use the first sheet ("Sheet1") - Clear the existing content from row 2 downward (preserve the header row) - Write the query results starting from row 2, with one row per account - Use these column headers (already in row 1): Account ID, Account Name, Industry, Annual Revenue, Country, Account Owner, Created, Last Activity Step 3: Add a note at the top of the sheet (cell A1 comment or a dedicated "last updated" cell): "Last refreshed: [current date and time] — [row count] accounts" ``` Under **Connections**, enable: * **Snowflake** — required * **Google Sheets** — for writing results * **On demand**: click **Start Work** whenever you need a fresh pull * **Scheduled**: set a daily or weekly trigger under **Agent Settings** > **Triggers** if the sheet needs to stay current automatically #### Expected Results * The Google Sheet is populated with fresh data each time the agent runs * Stakeholders can filter, sort, and share the sheet without touching Snowflake * The "last refreshed" cell makes it clear how current the data is * Large result sets are handled automatically — when results are too large to return inline, they may be provided as a CSV that the agent can upload directly to the sheet *** ### Tips for Better Results **Name your queries in the AOP**: Label each query with what it measures (e.g., "Query 1: weekly revenue"). This makes it easier to refine specific queries without rewriting the entire AOP. **Use date ranges explicitly**: Rather than `WHERE date = CURRENT_DATE - 7`, write out the range in plain language in your AOP (e.g., "from last Monday to last Sunday") and let the agent calculate the exact dates at runtime. This avoids off-by-one errors from timezone differences. **Keep queries read-only**: Duvo's Snowflake connection only allows SELECT statements. Design your workflow so any write operations happen via a different connection (Google Sheets, Slack, email) rather than back into Snowflake. **Add a sanity check**: For reports that feed business decisions, add a line to your AOP like "If the total revenue figure is less than $1,000 or more than $10,000,000, stop and send me a Slack message saying the numbers look unexpected — do not distribute the report." This catches data pipeline issues before they mislead stakeholders. **Upload schema context to Files**: If your warehouse has many tables or non-obvious column names, upload a data dictionary or schema summary to **Agent Settings** > **Files**. The agent can use it to write more accurate queries. *** ### Troubleshooting * Re-open the Snowflake connection on the [Connections page](https://app.duvo.ai/integrations) and verify the account identifier, username, warehouse, database, schema, and role * Check that the RSA public key is still registered in Snowflake under `ALTER USER ... SET RSA_PUBLIC_KEY = '...'` * Confirm the Snowflake user's role has USAGE on the warehouse and SELECT on the target tables * Run the same query manually in Snowflake's worksheet UI to confirm the result * Check that the warehouse is not suspended — if it cannot auto-resume (or resume is slow), queries may fail or time out rather than return results * Verify that the date range in the AOP is computing correctly; add a line asking the agent to log the computed date range before querying * Check for timezone differences: Snowflake stores timestamps in UTC by default. If your AOP says "last week" without specifying a timezone, add one (e.g., "last Monday to last Sunday, US Eastern time") * Look for duplicate rows: if your table has one row per event and the query isn't aggregating correctly, add `SELECT DISTINCT` or a `GROUP BY` * Confirm the Snowflake role can see all the rows you expect — row-level security policies can silently filter results * When results are too large to return inline, they may be provided as a CSV file. The agent can upload the CSV directly to Google Sheets — update your AOP to say: "If the query result is a CSV file, upload it to the Google Sheet" * Confirm the trigger is set to **Active** under **Agent Settings** > **Triggers** * Check the agent's Run history to see whether previous scheduled Runs succeeded or failed * If Runs are failing, open the failed Run and read the run log to identify the error *** ### Related Resources Configure key-pair authentication and add the connection Run agents on a recurring schedule Start agents from external events Write query results to a spreadsheet Post summaries and alerts to channels Add approval steps for sensitive actions Upload schema context for more accurate queries # Weekly Sales Report Source: https://docs.duvo.ai/user-guide/examples/weekly-sales-report Build a Duvo agent that pulls CRM data, calculates KPIs, and distributes regional sales reports every Monday morning. **Time to complete:** 20 minutes **Difficulty:** Intermediate **Prerequisites:** CRM/Sales platform access, Email or Slack connection, Spreadsheet connection **You'll build:** An agent that generates and distributes customized sales reports every week ### Why Automate This? **The Problem**: Sales managers spend Monday mornings pulling data from multiple systems, building spreadsheets, calculating metrics, and formatting reports. By the time reports are distributed, the data is already hours old. Different regions get different formats. And creating personalized views for each stakeholder is simply not feasible manually. **The Solution**: A Duvo agent that automatically pulls sales data, calculates KPIs, generates formatted reports with regional filtering, and distributes them to the right stakeholders—all before anyone arrives Monday morning. **Expected Results**: * Eliminate 3-4 hours of manual report building per week * Deliver reports by 7 AM Monday (before anyone asks) * Provide personalized regional views for each manager * Ensure consistent metrics and formatting * Include week-over-week comparisons automatically *** ### What You'll Build By the end of this tutorial, you'll have an agent that: 1. Pulls sales data from your CRM for the past week 2. Calculates key performance metrics and comparisons 3. Generates formatted reports with charts and highlights 4. Filters data by region for each recipient 5. Distributes via email and posts to Slack 6. Archives reports in your shared drive *** ### Before You Start Make sure you have these ready: **CRM/Sales platform** - Salesforce, HubSpot, or similar. [Set up logins](/user-guide/resources/my-logins) **Email connection** - For distributing reports. [Add a connection](/user-guide/connections/how-to-add-connection) **Google Sheets or Excel** - For generating formatted reports **Slack connection** (optional) - For posting summaries **Google Drive or SharePoint** (optional) - For archiving reports *** 1. Click **"+ Create Agent"** from your dashboard 2. Select **"Use Agent Builder"** (recommended for this tutorial) Create Agent Button Paste this prompt into the Agent Builder: ``` Every Monday at 6:00 AM, generate and distribute weekly sales reports. Step 1: Gather sales data from our CRM for the past 7 days - New deals created - Deals closed (won and lost) - Pipeline value changes - Revenue recognized - Meetings held - Calls made Step 2: Calculate key metrics - Total revenue for the week - Week-over-week growth percentage - Average deal size - Win rate (closed won / total closed) - Pipeline coverage ratio - Forecast accuracy vs actual Step 3: Generate the report Create a formatted report including: - Executive summary with top 3 highlights - Revenue breakdown by product line - Top 5 deals closed this week - Pipeline status and 30/60/90 day forecast - Team performance leaderboard - At-risk deals requiring attention - Comparison to same week last year Step 4: Create regional versions Generate separate reports for: - West Region (CA, OR, WA, NV, AZ) - East Region (NY, NJ, PA, MA, CT) - Central Region (TX, IL, OH, MI, GA) - Include only deals from each region's territories Step 5: Distribute reports - Send regional reports to respective Regional Sales Managers - Send company-wide summary to VP of Sales and CEO - Post highlights summary to #sales-team Slack channel - Save all reports to the Sales Reports folder in Google Drive with date stamp Step 6: Log completion Record report generation timestamp and any data quality issues encountered. If CRM data appears incomplete (less than 50% of typical weekly volume), send alert to sales operations before distributing reports. ``` Click **"Generate"** to create the agent AOP. Review to ensure: * All metrics are correctly defined * Regional territories match your organization * Distribution list is accurate * Report format meets your needs Create a consistent look by uploading a template: 1. Go to **Agent Settings** > **Files** 2. Upload your report template (Excel or Google Sheets format) 3. Include your company branding, chart styles, and section layouts Click **"Connections"** and connect: 1. **CRM** - Salesforce, HubSpot, or your sales platform 2. **Google Sheets or Excel** - For report generation 3. **Email** - For distribution 4. **Slack** (optional) - For team notifications 5. **Google Drive or SharePoint** (optional) - For archiving Run a manual test before scheduling: 1. Click **"Run Agent"** 2. Review the generated report for accuracy 3. Verify regional filtering is correct 4. Check that all recipients received their reports Agent Running **What to check**: * Are the numbers accurate vs your CRM? * Is the regional breakdown correct? * Did the formatting look right? * Were all stakeholders included? Set up the Monday morning schedule: 1. Go to **Agent Settings** > **Schedule** 2. Select **Weekly** on **Monday** at **6:00 AM** 3. Choose your timezone 4. Save settings Your agent will now generate and distribute reports automatically every Monday. *** ### Expected Results When your agent runs successfully, you should see: **In stakeholder inboxes** (by 7 AM Monday): * Formatted PDF reports with charts * Executive summary highlighting key wins and concerns * Week-over-week comparisons * Regional breakdown specific to their territory **In Slack #sales-team**: * Quick highlights summary * Link to full report * Celebration of top performers **In Google Drive/SharePoint**: * Archived reports with date stamps * Historical data for trend analysis * Accessible to entire sales organization **In Duvo**: * Execution log with timing * Data quality alerts if applicable * Distribution confirmation *** ### Troubleshooting * **Date range**: Verify timezone settings match your CRM * **Filters**: Check that all deal stages are included * **Currency**: Ensure consistent currency conversion if international * **Duplicates**: Confirm deals aren't being counted multiple times * **Territory mapping**: Verify state/country agents in AOP * **Account agent**: Check that accounts have correct region tags in CRM * **New territories**: Update AOP when territories change * **Template**: Ensure template is properly formatted and compatible * **Data types**: Verify numbers are formatted as numbers, dates as dates * **Chart data ranges**: Check that charts reference correct cells * **File size**: Large reports may be blocked—consider Drive links instead * **Recipients**: Verify email addresses are current * **Spam filters**: Check corporate spam filters for attachments * **Channel permissions**: Ensure agent has permission to post * **Message length**: Slack has character limits—keep summaries concise * **Bot configuration**: Verify Slack app is properly installed *** ### Take It Further Once your basic agent is working, consider these enhancements: ``` Compare this week's closed revenue to what was forecasted 4 weeks ago. Calculate forecast accuracy percentage for each rep. Highlight reps with >90% accuracy as "Reliable Forecasters". Include 4-week forecast accuracy trend in the report. ``` ``` If any of these conditions are met, send immediate Slack alert to VP of Sales: - Week-over-week revenue down more than 20% - Win rate below 15% - Pipeline coverage below 2x - Any deal over $100K marked "at risk" ``` ``` Include a section on deals lost to competitors this week. Group by competitor and identify patterns. Calculate loss rate by competitor over past 90 days. ``` ``` Create individual performance scorecards for each rep: - Revenue vs quota percentage - Activity metrics (calls, emails, meetings) - Pipeline health - Forecast accuracy Send each rep their personal scorecard along with team report. ``` Regional managers can customize their reports. [Learn about Agent Memory](/user-guide/assignment-features/assignment-memory) * West Region Manager: *"Only include data for California, Oregon, and Washington territories. Highlight accounts over \$50K in annual value. Send the report to my regional team at 6 AM Pacific."* * East Region Manager: *"Only include data for New York, New Jersey, and Pennsylvania territories. Highlight accounts over \$100K in annual value. Send the report to my regional team and VP of Sales."* *** ### Related Resources Customize reports for each stakeholder Upload report templates and formatting guides Connect your CRM and communication tools Review reports before distribution # Agent Overview Source: https://docs.duvo.ai/user-guide/getting-started/assignment-overview Learn what Duvo agents are, what they can automate, and how they work across your business systems and tools. ## Introduction A Duvo agent is your automated teammate—a smart assistant that handles repetitive business tasks across your systems and tools without human intervention. Unlike traditional automation that follows rigid, pre-programmed rules, Duvo agents understand your goals and adapt to different situations. Agents overview page in Duvo ## What Can Duvo Agents Do? Duvo agents excel at cross-system workflows that move data and actions between multiple tools like CRMs, email, spreadsheets, and ERP systems. They handle repetitive processes you do the same way every time, such as processing orders, generating reports, or onboarding customers. Agents are perfect for data gathering and routing—collecting information from various sources and sending it to the right people or systems. They manage scheduled maintenance tasks that need to happen daily, weekly, or monthly, and handle form filling and data entry by navigating systems and inputting information accurately. They also provide monitoring and alerting by watching for specific conditions and notifying the right people when action is needed. ## Key Components of a Duvo Agent Every Duvo agent operates as if it were you performing the task, using your logins and access to work seamlessly across your systems. | Component | Description | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **AOP (Agent Operating Procedure)** | Defines what the agent does, when it acts, and how it handles different situations. These are the detailed rules that guide your agent's behavior and decision-making. | | **Connections** | Allow the agent to access your systems on your behalf. For example, if the agent needs to send an email, it uses your email logins to compose and send it as if you wrote it yourself. All logins are stored securely and encrypted. | | **My Logins** | When you make your logins available to Duvo via our secure vault, the agent can log into your systems (email, ERP, CRM, spreadsheets, or any other tool) just as you would. | | **Files** | Provide the agent with reference information it needs to complete tasks. You can upload documents, conversion tables, pricing guides, company policies, standard operating procedures, or any other reference materials the agent should consult. For example, if your agent needs to apply different shipping rates based on zones, you can add a rate table to the files for the agent to reference. | | **Browser automation** | Enables the agent to work with any web-based system, even those without traditional API connections. This is particularly valuable for internal business systems, legacy applications, or specialized tools that are critical to your operations but still require manual interaction. The agent can navigate these systems through the browser just like you would—clicking, typing, and filling out forms. | | **Human-in-the-loop controls** | Provide approval points where you review and authorize actions before the agent executes them. You decide which actions require your oversight and which can run automatically. | | **Audit trail** | Provides complete logs of everything your agent does, ensuring transparency and compliance. You can always see exactly what actions were taken, when, and using which logins. | ## Viewing Your Agents The main Agents page shows all your agents and folders. Use the toggle in the top-right of the page to switch between **grid view** and **list view** — your preference is saved automatically. * **Grid view**: Displays each agent as a card showing its name, connections, and schedule status at a glance. * **List view**: Shows agents in a compact table format, making it easier to scan and compare a large number of agents. # Monitor the First Week Source: https://docs.duvo.ai/user-guide/getting-started/monitor-first-week A daily review cadence, the signals to watch in Duvo, and a playbook for the most common anomalies during the highest-risk first week after an agent goes live. The first five to seven days after an agent goes live are the highest-risk period. Volume is real, edge cases you did not test for will surface, and small problems compound quickly if you are not watching. This guide gives you a daily review cadence, the specific signals to track in Duvo, and a clear playbook for the most common anomalies — so you can tell the difference between normal early noise and something that genuinely needs your attention. ## Why the First Week Is Different During testing you controlled the inputs. In production, inputs are unpredictable — real emails, real files, real volumes. Agents that worked perfectly in tests often surface new failure modes in the first week simply because the variety of real-world data is much wider than your test cases covered. The goal of first-week monitoring is not to watch every Run in real time. It is to catch pattern changes early enough to act before they become problems, and to graduate off intensive monitoring once you have evidence that the agent is stable. ## Daily Checks: Day 1 to Day 7 Run through this list each day while the agent is in its first week of production use. It takes about five to ten minutes. ### Requests Open [Requests](/user-guide/assignment-features/requests) and check for pending approval requests. * Are there more pending requests than expected? A spike in Needs Input usually means the AOP is hitting an ambiguous case it is not confident about — see [Spike in Needs Input](#spike-in-needs-input) below. * Are requests sitting unanswered for more than a few hours? Unanswered requests pause the Runs that created them. If your team is not seeing the notifications, adjust the escalation path in the AOP or your Slack/email notification setup. ### Queue health (if applicable) If the agent uses [Queue](/user-guide/assignment-features/case-queue), open the Cases view and check the status breakdown for the time period covering the last 24 hours. | Metric | Healthy range | Watch for | | -------------------- | --------------------------------- | --------------------------------------------------- | | **Failed rate** | Under 5% of cases processed | Any sudden spike above your baseline | | **Needs Input rate** | Stable or declining over the week | Rising rate signals an AOP gap | | **Postponed rate** | Stable | Rising rate may indicate an upstream system is slow | ### Runs List Open the Runs List (Past Runs) and apply the **Needs attention** filter to see any Failed or Needs Input Runs from the past 24 hours. * For each failed Run, open it and note which step failed. Look for clustering: if five Runs all fail at the same step, that is an AOP or Connection issue, not random noise. * If a Run failed due to a Connection error, go to Connections, check whether the Connection is still authorized, and re-authorize if needed. ### Cost per Run trend In [Team Insights](/user-guide/analytics/team-insights-overview), check the average cost per run for this agent over the past 24 hours against your baseline from testing. * A cost spike often means the agent is making more tool calls than expected — common when the AOP does not give the agent a clear stopping point and it keeps searching or retrying. * A cost spike can also indicate a tool-call loop: the agent calls a tool, gets an unexpected result, and tries again repeatedly. Open the high-cost Run from the [Runs List](/user-guide/running-assignments/jobs-list) and scroll through the steps to find where calls are repeating. ### Output spot-check Pick three to five completed Runs at random and open them. Read the output the agent produced. * Does the output look correct? Would a human reviewer accept it? * Are there patterns in what looks off? Edge cases cluster — if you find one, look for others like it. ## Team Insights Signals to Watch Open [Team Insights](/user-guide/analytics/team-insights-overview) and set the time period to **Last 7 days**. Use these signals to identify trends early. Compare the number of Runs triggered against what you expected when you set up the schedule or trigger. * Significantly fewer Runs than expected may mean the trigger is not firing (check the trigger configuration) or Runs are failing before they complete (check the Failed count). * Significantly more Runs than expected may mean the trigger is firing on events you did not intend. Check the trigger source configuration and consider adding a filter in the AOP. The source breakdown shows where runs originate — manual, scheduled, or from a specific trigger. * If the source mix changes unexpectedly (for example, a scheduled agent suddenly shows a spike in manual runs), investigate whether team members are retriggering Runs manually because they do not trust the automatic output. If the failure rate is above your baseline, look for clustering before making AOP changes. * **Single Connection failing repeatedly**: the external service may be experiencing issues, or the Connection credentials expired. Check the third-party service status page and re-authorize the Connection if needed. * **Failures spread across multiple Connections**: this usually points to an AOP logic issue — the agent is attempting something in the wrong order or with the wrong data. * **Failures only on certain input types**: your AOP needs to handle that input shape. Add a HITL gate to catch it while you refine the AOP. If the agent has multiple approval gates, check whether one is generating significantly more requests than others. A single gate driving most of the Needs Input volume is usually the first AOP gap to fix. ## Anomaly Response Patterns **What it means**: The agent is frequently reaching a decision point it is not confident about. It is asking for help rather than deciding autonomously. **How to respond**: Open several recent Needs Input requests in Requests and read them carefully. Identify what they have in common — the same type of question, the same step in the workflow, the same data condition. Update the AOP to handle that condition explicitly. Either give the agent a rule to follow, or widen the HITL gate with a clearer decision framework so reviewers can respond consistently. If the condition genuinely should always require human approval, tighten the HITL gate description so reviewers understand what they are approving. **What it means**: Runs are ending without completing successfully. This requires immediate investigation. **How to respond**: Open two or three failed Runs from the [Runs List](/user-guide/running-assignments/jobs-list) (Past Runs in the sidebar) and read through the steps of each one to find where it failed. If they all fail at the same step, that step has a problem — a Connection issue, a data format mismatch, or a logic error in the AOP. If they fail at different steps, look for a common thread: the same Connection, the same input type, or the same time of day (which may indicate an external service outage). If the failure rate is high and you cannot immediately fix the root cause, consider pausing the agent (disable the schedule or trigger) and communicating to your team while you investigate. **What it means**: Individual Runs are consuming significantly more than your baseline cost estimate. **How to respond**: Open one of the high-cost Runs from the [Runs List](/user-guide/running-assignments/jobs-list) and scroll through the steps. Count how many tool calls the agent made. A healthy Run typically makes a predictable number of calls. A high-cost Run often shows many repeated calls to the same tool — a sign of a loop. If you see a tool-call loop, update the AOP to give the agent a clear exit condition. For example: "If you do not find the record after searching twice, stop and request HITL." If the cost is high but the tool calls look reasonable, the inputs may be much larger than expected. Check whether you can batch the input or pre-filter it before the agent processes it. **What it means**: Runs are taking significantly longer to complete than during testing. **How to respond**: Check whether the latency drift is consistent across all Runs or isolated to specific runs. If isolated, the upstream system may have been slow at that time (check external service status pages or your own infrastructure logs). If consistent, compare the volume of data the agent is processing in production versus testing. Real-world volumes are often larger. Update the AOP to process in smaller batches, or add a volume cap while you investigate. If Run duration is approaching your business process SLA, consider whether you need to adjust the schedule (run more frequently in smaller batches) or add a volume limit to the AOP. ## Emergency Stop If something is clearly going wrong and you need to stop the agent immediately, use one of these methods. Open the agent. Click the **Schedule** button in the agent header. Toggle the schedule off, or navigate to the **Triggers** tab and disable the trigger. Runs already running will complete. No new Runs will start. Fastest stop for write-heavy agents. If the agent is actively writing data and you need to stop it mid-run: Go to **Connections** in the left sidebar. Find the Connection the agent is using to write data. Disconnect it. The agent fails immediately when it tries to use that Connection. This is the fastest way to stop a write-heavy agent when you are not sure whether damage is still occurring. If the problem was introduced by a recent AOP change: Open the agent. Use the revision selector in the builder toolbar to select the last known-good revision. Switch back to that version and re-enable the schedule or trigger. Monitor the next two or three Runs manually before reducing your check frequency. See [Agent Versions](/user-guide/advanced/assignment-versions) for details on browsing and restoring revisions. ## Post-Incident Template When something goes wrong and you need to communicate or document it, use this template. To identify the root cause before filling it in: open one of the failed Runs from the Runs List and read the step where it failed. A Connection error points to a credential issue. Repeated failures on the same step with similar inputs point to an AOP logic gap. A failure on the very first step often means the input data was missing or malformed. ``` Date: [date] Agent: [name] Owner: [name] What happened: [One paragraph: what the agent did, what it should have done, and what the impact was.] How we detected it: [Daily check / alert / team member reported / ...] Root cause: [What specifically caused the failure — e.g.: - AOP gap: the agent hit a case the AOP did not handle - Connection issue: a Connection was disconnected or its credentials expired - Input data issue: the data passed to the agent was missing or malformed - External service outage: the third-party service was unavailable] What we changed: [AOP update / Connection fix / volume cap added / ...] What we will watch: [The specific metric or signal we will monitor over the next [N] days to confirm the fix worked.] ``` ## Graduating Off First-Week Mode You can move from daily checks to a routine operational rhythm when all of the following are true for three consecutive days: * Failed rate is under 5% and stable or declining. * Needs Input rate is stable or declining. * No cost or latency spikes. * Output spot-checks look correct. * No unresolved anomalies in Requests. ### Handoff to ongoing operational rhythm When you graduate off first-week monitoring: Move to weekly rather than daily checks, using Team Insights to review the past seven days. Set up persistent alerts if your agent uses a notification step in the AOP — for example, a Slack message after each run summarizing the outcome. Schedule a 30-day review with the agent owner to reassess whether the AOP needs refinement based on accumulated production experience. Update the agent runbook with anything you learned in the first week — owner contact, typical cost per Run, known edge cases, and the escalation path. ## Related The checklist and setup steps before going live. Where to find failed and in-progress Runs across all agents. Run volume, failure rates, and cost trends. Where HITL requests land and how to respond. Case statuses and failure rates for queue-based agents. Reviewing and reverting to a previous revision. # Promote to Production Source: https://docs.duvo.ai/user-guide/getting-started/promote-to-production The pre-promotion checklist, how to switch on a schedule or trigger, soft-launch options, team access, and the runbook to hand an agent over to your team. Before you turn on a schedule or trigger and hand an agent over to your team, run through this guide. It covers the decisions and steps that builders most often skip — and regret later. The path from a tested build to a stable production agent follows a predictable flow. ```mermaid theme={"dark"} flowchart TD A[Pre-promotion checklist] --> B[Switch on the schedule or trigger] B --> C[Soft-launch: volume cap, time window, or restricted source] C --> D[Share access and onboard operators] D --> E[Notifications and runbook in place] E --> F[Agent live in production] F -->|Something goes wrong| G[Toggle off the schedule, trigger, or connection] G --> H[Revert to the last known-good revision] H --> B ``` ## Pre-Promotion Checklist Work through this list before enabling any schedule or trigger. Each item represents a category of surprise that commonly appears in the first week of production use. ### Testing signed off * At least three end-to-end test Runs have run without unexpected failures. * HITL approval gates have been exercised — you have seen real approval requests, denied one, and confirmed the agent handles denial gracefully. * Edge cases identified during testing have been handled in the AOP or accepted as known gaps. * The run debugger shows no unexplained errors in recent Runs. See [Guardrails for High-Risk Automations](/user-guide/security/high-risk-guardrails) for risk scoring and shadow-mode testing guidance before going live with high-stakes agents. ### Connections scoped to production Logins * All connections in the agent point to production accounts, not personal or sandbox accounts. * Logins and Secrets used by the agent belong to a service account or shared Login where appropriate — not a personal user account that could be disabled. * Connection permissions are scoped to the minimum required. An agent that only reads data from Salesforce does not need write permissions. ### Human-in-the-Loop coverage validated * Every action that is irreversible, expensive, or externally visible has an approval gate. * Approval descriptions give reviewers enough context to decide without opening another system. * Escalation paths are defined: what happens if a request is ignored for 24 hours, or denied twice. ### Cost and latency within target * Estimated cost per Run is acceptable for the expected Run frequency. * Typical Run duration fits within the business process SLA (for example, a nightly report that takes four hours is a problem if stakeholders expect it before 08:00). * If cost or duration is higher than expected, investigate before going live rather than hoping it improves. ### Owner and escalation contact named * One named person is responsible for this agent in production. * That person knows they are the owner and understands what the agent does. * A backup contact is identified for when the primary owner is unavailable. ### Rollback path documented * The previous working revision is identified and accessible via [Agent Versions](/user-guide/advanced/assignment-versions). * The team knows how to pause the schedule or trigger — and who is allowed to do it. ## Switching On the Trigger or Schedule Enable the schedule or trigger only after the checklist above is complete. Open the agent. Click the **Schedule** button (or calendar icon) in the agent header. Set the frequency. See [Scheduling Agents](/user-guide/assignment-features/scheduling-assignments) for all options. Click **Add schedule** to save. The agent now runs automatically. Scheduled Runs appear in the Runs list with a clock icon so you can distinguish them from manual runs. Open the agent. Click the **Schedule** button and select the **Triggers** tab (lightning bolt icon). Configure the trigger source — email, Slack message, file drop, status change, or webhook. Save the trigger. See [Event-Driven Triggers](/user-guide/assignment-features/event-driven-triggers) for setup details by trigger type. ### Soft-launch options Running at full volume immediately is rarely the right move. Consider these options for the first days of production: **Volume cap** — Add an explicit cap to the AOP to limit how many records or actions the agent processes per Run. Once you are confident it is behaving correctly, remove the cap. ``` Process at most 10 records per Run for the first two weeks. Log a message if the cap is reached: "Volume cap active — [count] records processed." ``` **Time-window restriction** — Limit write operations to business hours so a human can respond quickly if something goes wrong. ``` Only perform write actions between 08:00 and 18:00 Monday–Friday. Outside these hours, queue the action and process it at 08:00 on the next business day. ``` **Restricted source** — If the agent handles inbound events (emails, Slack messages, file drops), configure the trigger to accept events from one team or channel before expanding to all. ### Toggling off in seconds If something goes wrong, you can stop the agent immediately: * **Disable a schedule**: Open the agent, go to Schedule, and toggle the schedule off. Runs already running continue to completion; no new Runs start. * **Disable a trigger**: Open the agent, go to Triggers, and disable the trigger. No new Runs are created from that trigger. * **Revoke a connection**: Go to the Connections page, find the connection, and disconnect it. The agent fails immediately if it tries to use that connection — the fastest way to stop a write-heavy agent when you are not sure whether damage is still occurring. ## Sharing Access with Your Team ### Roles required | What the person does | Minimum role needed | | -------------------------------------------- | ----------------------------------- | | Builds and edits the agent | Builder (for own agents) or Manager | | Reviews and approves HITL requests | Member | | Monitors own Run results | Member | | Views all team Run results and Team Insights | Administrator | | Changes the agent AOP or schedule | Manager or higher | | Manages team members and permissions | Administrator or higher | See [Roles and Permissions](/user-guide/teams/roles-and-permissions) for the full permissions matrix. ### Memory scope decisions If the agent uses [Agent Memory](/user-guide/assignment-features/assignment-memory), decide before going live whether memory should be per-user or shared across the team: * **Per-user memory**: Each person who runs the agent starts from their own memory context. Best for personal productivity agents where each user's context is independent. * **Shared memory**: All runs read from and write to the same memory context. Best for team workflows where state needs to persist across different users triggering the agent. Changing memory scope after an agent has been running in production can cause unexpected behavior. Make this decision before the first production run. ### Logins and Secrets access * Logins and Secrets used by the agent must be accessible when the agent runs — not locked to a personal account. * If operators will trigger the agent manually, confirm they can see the agent in their workspace. * If the agent uses a login stored in your personal vault, consider moving it to a shared or service Login before going live. ### Onboarding operators The people who will trigger and monitor the agent — but did not build it — need a short handoff. Cover: What the agent does and what triggers it. Where to find Runs and how to read the status indicators. How to respond to HITL requests in [Requests](/user-guide/assignment-features/requests). Who to contact if something looks wrong. How to pause the agent in an emergency (see above). ## Notifications and Runbook ### Where alerts go Configure at least one notification path before going live. Options include: * **Slack**: Have the agent post a summary to a team channel after each run. * **Email**: Use a Gmail or Outlook connection to send a status email to the owner. * **HITL escalation**: Set a fallback in the AOP to create a HITL request if the Run fails, so the owner sees it in Requests. Add the notification step directly to the AOP so it runs automatically. ### Runbook template Copy and fill in this template before the agent goes live. Keep it somewhere the whole team can find it. ``` Agent: [Name] Owner: [Name, contact] Backup contact: [Name, contact] What it does: [One sentence] Runs: [Frequency or trigger] Typical duration: [e.g., 5–10 minutes] Typical cost per run: [e.g., $0.08] Failure response: 1. Check the run debugger for the failed Run to identify which step failed. 2. If a Connection is down, check the third-party service status page. 3. If the AOP logic failed, revert to the previous revision via Agent Versions. 4. Notify [stakeholder] if more than [N] Runs fail in a 24-hour window. Pause procedure: 1. Open the assignment. 2. Disable the schedule or trigger. 3. Notify [Slack channel / email list] with a brief explanation. Rollback procedure: 1. Open the assignment. 2. Go to the revision selector in the builder toolbar. 3. Select the last known-good revision. 4. Re-enable the schedule or trigger. 5. Monitor the next two Runs manually. ``` ## Assigning Owners Every production agent needs a named owner. Ownership is not the same as the team role — it is an informal accountability designation that complements the permissions model. ### Owner types | Role | Responsibility | | ----------------- | --------------------------------------------------------------------------------------------------------------------------- | | **Build owner** | Responsible for the AOP, connections, and making changes. Usually the Builder or Manager who created the agent. | | **Ops owner** | Responsible for day-to-day monitoring, HITL responses, and escalation. This may be a different person from the build owner. | | **HITL operator** | Handles approval requests in Requests. There can be multiple operators covering different time zones. | ### Escalation when the owner is unavailable Define the escalation path before the agent goes live: 1. **Primary owner** — first contact for any issue. 2. **Backup owner** — covers when the primary is OOO. Must have at least Manager role. 3. **Escalation Manager** — for issues the backup cannot resolve. Has permission to pause, revert, or disable the agent. The "owner of last resort" pattern: designate one Administrator who can take emergency action on any agent regardless of who built it. This person does not need to be involved day to day — they exist so there is always someone who can act. ### When ownership changes When the build owner changes roles or leaves the team: Transfer the relevant Logins and Secrets to the new owner's access or to a shared Login. Update the runbook with the new owner's contact details. Schedule a handoff session so the new owner understands the agent's AOP and known edge cases. Have the new owner run at least one manual Run before the next scheduled run. ## What's Next? Your agent is live. The first week is the highest-risk period — monitor it closely before settling into a routine cadence. The testing checklist and environment separation patterns that feed into this guide. Apply the right controls before enabling autonomous write operations. How to review and revert to a previous revision. Risk tiers, approval shapes, and escalation chains. Where HITL requests land and how to respond. Run volume, failure rates, and cost trends across your team. # Quick Start Source: https://docs.duvo.ai/user-guide/getting-started/quick-start Create and run your first Duvo agent in minutes. Step-by-step guide covering setup, connections, testing, and scheduling. Get up and running with Duvo in minutes. This page walks you through creating and running your first agent.